public function testClass() { $request = new \Spore\HttpFoundation\Request(); $this->assert->object($request)->isInstanceOf('\\Spore\\HttpFoundation\\Request'); $request->setUri('http://*****:*****@www.google.com:8080/search?q=test'); $this->assert->string($request->getUri())->isEqualTo('http://*****:*****@www.google.com:8080/search?q=test'); $request->setUri('http://*****:*****@www.google.com:80/search?q=test'); $this->assert->string($request->getUri())->isEqualTo('http://*****:*****@www.google.com/search?q=test'); $request->setMethod('GET'); $this->assert->exception(function () use($request) { $request->setMethod('FOOT'); })->isInstanceOf('\\InvalidArgumentException'); $this->assert->string($request->getPath())->isEqualTo('/search'); $this->assert->string($request->getScheme())->isEqualTo('http'); $this->assert->string($request->getHost())->isEqualTo('www.google.com'); $this->assert->integer($request->getPort())->isEqualTo(80); $request->setPort(8080); $this->assert->integer($request->getPort())->isEqualTo(8080); $this->assert->string($request->getMethod())->isEqualTo('GET'); $this->assert->boolean($request->isGet())->isTrue(); $this->assert->boolean($request->isPost())->isFalse(); $this->assert->boolean($request->isDelete())->isFalse(); $this->assert->boolean($request->isPatch())->isFalse(); $this->assert->boolean($request->isOptions())->isFalse(); $this->assert->boolean($request->isTrace())->isFalse(); $this->assert->boolean($request->isConnect())->isFalse(); $this->assert->boolean($request->isPut())->isFalse(); $this->assert->boolean($request->isHead())->isFalse(); $this->assert->string($request->getUser())->isEqualTo('username'); $this->assert->string($request->getPassword())->isEqualTo('passwd'); $request->setUser('username1'); $this->assert->string($request->getUser())->isEqualTo('username1'); $request->setPassword('passwd2'); $this->assert->string($request->getPassword())->isEqualTo('passwd2'); $this->assert->boolean($request->isAuth())->isTrue(); $request = new \Spore\HttpFoundation\Request('http://www.google.com/search?q=test'); $request->setQuery('q=toto&hl=fr'); $this->assert->object($request->getQuery())->isInstanceOf('\\Symfony\\Component\\HttpFoundation\\ParameterBag'); $this->assert->array($request->getQuery()->all())->isEqualTo(array('q' => 'toto', 'hl' => 'fr')); $request->setQuery(array('foot' => 'bar')); $this->assert->array($request->getQuery()->all())->isEqualTo(array('q' => 'toto', 'hl' => 'fr', 'foot' => 'bar')); $this->assert->exception(function () use($request) { $request->setQuery(1); })->isInstanceOf('\\InvalidArgumentException'); $request = new \Spore\HttpFoundation\Request(); $this->assert->object($request->getQuery())->isInstanceOf('\\Symfony\\Component\\HttpFoundation\\ParameterBag'); $request->setData('test'); $this->assert->string($request->getData())->isEqualTo('test'); }
/** * Send request * * @param String $method * @param String $uri * @param Array $params * @param Mixed $data * @param Array $headers * @return \Spore\HttpFoundation\Response */ public function call($method, $uri, array $params, $data = null, array $headers = array()) { $method = strtoupper($method); $parts = array(); if (strpos($uri, '/') !== false) { $parts = array_filter(explode('/', $uri)); } foreach ($params as $key => $value) { $uri = str_replace(':' . $key, $value, $uri); } if (!empty($parts)) { foreach ($parts as $value) { if ($value[0] == ':') { $key = substr($value, 1); if (isset($params[$key])) { unset($params[$key]); } } } } $request = new Request(); $request->setUri($uri); $request->setMethod($method); if (isset($this->formats[$this->format])) { $request->headers->set('Accept', $this->formats[$this->format]); } else { $request->headers->set('Accept', ''); } if (!empty($params)) { $request->setQuery($params); } if (!empty($data)) { $request->setData($data); } $env = new ArrayObject(array('format' => $this->format)); $middlewares = $this->getMiddlewares(); foreach ($middlewares as $middleware) { $middleware->processRequest($request, $env); } $response = $this->getAdapter()->execute($request); foreach ($middlewares as $middleware) { $middleware->processResponse($response, $env); } unset($middlewares); return $response; }
/** * Send request * * @param String $method * @param String $endpoint * @param Array $params * @param Mixed $data * @param Array $headers * @return \Spore\HttpFoundation\Response * @throws \InvalidArgumentException, \RuntimeException */ public function call($method, $endpoint, array $params, $data = null, array $headers = array()) { $method = strtoupper($method); if (isset($this->spec['methods'][$endpoint])) { $spec = $this->spec['methods'][$endpoint]; if ($spec['method'] != $method) { throw new InvalidArgumentException(sprintf("Method %s is not allowed.", $method)); } $params = $this->verifyParameters($params, isset($spec['required_params']) ? $spec['required_params'] : array(), isset($spec['optional_params']) ? $spec['optional_params'] : array()); $uri = rtrim($this->spec['base_url'], '/') . $spec['path']; foreach ($params as $key => $value) { $uri = str_replace(':' . $key, $value, $uri); } $request = new Request(); $request->setUri($uri); $request->setMethod($method); if (!empty($data)) { $request->setData($data); } $env = new ArrayObject(array('format' => $this->format)); foreach ($this->middlewares as $middleware) { $middleware->processRequest($request, $env); } $response = $this->getAdapter()->execute($request); if (isset($spec['expected'])) { if (!in_array($response->getStatusCode(), $spec['expected'])) { throw new RuntimeException(Response::$statusTexts[$response->getStatusCode()]); } } foreach ($this->middlewares as $middleware) { $middleware->processResponse($response, $env); } return $response; } throw new InvalidArgumentException(sprintf("Endpoint %s is not defined.", $endpoint)); }
/** * * @param \Spore\HttpFoundation\Request $request * @return \Spore\HttpFoundation\Response * @throws \RuntimeException */ public function execute(Request $request) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $request->getUri()); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FORBID_REUSE, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); curl_setopt($ch, CURLOPT_MAXREDIRS, 3); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_USERAGENT, sprintf('Spore\\Client (version %s +http://github.com/euskadi31/Spore)', \Spore\Client::VERSION)); if ($request->headers->count() > 0) { $headers = array(); foreach ($request->headers->allPreserveCase() as $key => $value) { $headers[] = $key . ': ' . $value[0]; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } if ($request->getPort() != 80) { curl_setopt($ch, CURLOPT_PORT, $request->getPort()); } /*if ($request->isAuth()) { curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, true); curl_setopt($ch, CURLOPT_USERPWD, $request->getUser() . ':' . $request->getPassword()); }*/ if ($this->isSecure) { curl_setopt($ch, CURLOPT_SSLCERT, $this->sslcert); if (!empty($this->passphrase)) { curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->passphrase); } } $curlValue = true; $method = $request->getMethod(); switch ($method) { case 'GET': $curlMethod = CURLOPT_HTTPGET; break; case 'HEAD': $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "HEAD"; break; case 'POST': $data = $request->getData(); if (!is_string($data)) { $data = http_build_query($data, '', '&'); } $curlMethod = CURLOPT_POST; break; case 'PUT': $data = $request->getData(); if (!is_string($data)) { $data = http_build_query($data, '', '&'); } $length = strlen($data); $fh = fopen('php://memory', 'rw'); fwrite($fh, $data); rewind($fh); $data = array(CURLOPT_INFILE => $fh, CURLOPT_INFILESIZE => $length); $curlMethod = CURLOPT_UPLOAD; //$curlMethod = CURLOPT_CUSTOMREQUEST; //$curlValue = "PUT"; break; case 'DELETE': $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "DELETE"; break; case 'PATCH': $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "PATCH"; break; case 'TRACE': $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "TRACE"; break; case 'OPTIONS': $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = "OPTIONS"; break; } // mark as HTTP request and set HTTP method curl_setopt($ch, $curlMethod, $curlValue); /** * Make sure POSTFIELDS is set after $curlMethod is set: * @link http://de2.php.net/manual/en/function.curl-setopt.php#81161 */ if ($method == 'POST') { curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } elseif ($curlMethod == CURLOPT_UPLOAD) { // this covers a PUT by file-handle: // Make the setting of this options explicit (rather than setting it through the loop following a bit lower) // to group common functionality together. foreach ($data as $key => $value) { curl_setopt($ch, $key, $value); } } elseif ($method == 'PUT') { curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } elseif ($method == 'PATCH') { curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } unset($data); $response = curl_exec($ch); if ($response === false) { $error = curl_error($ch); curl_close($ch); throw new RuntimeException($error); } $info = curl_getinfo($ch); curl_close($ch); // close resource if (isset($fh)) { fclose($fh); } // Eliminate multiple HTTP responses. do { $parts = preg_split('|(?:\\r?\\n){2}|m', $response, 2); $again = false; if (isset($parts[1]) && preg_match("|^HTTP/1\\.[01](.*?)\r\n|mi", $parts[1])) { $response = $parts[1]; $again = true; } } while ($again); // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string: if (stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n") !== false) { $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response); } list($header, $body) = explode("\r\n\r\n", $response); unset($response); $_headers = explode("\r\n", $header); unset($_headers[0], $header); $headers = array(); foreach ($_headers as $value) { if (strpos($value, ': ') !== false) { list($key, $val) = explode(': ', $value); $headers[strtolower($key)] = $val; } } unset($_headers); if (isset($headers['status'])) { unset($headers['status']); } return new Response($body, $info['http_code'], $headers); }