public function testRequest() { $testCase = $this; $http = new Http(new Callback(function (RequestInterface $request) use($testCase) { // api request if ($request->getUri()->getPath() == '/api') { $testCase->assertEquals('Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW', (string) $request->getHeader('Authorization')); $testCase->assertEquals('application/x-www-form-urlencoded', (string) $request->getHeader('Content-Type')); $testCase->assertEquals('grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA', (string) $request->getBody()); $response = <<<TEXT HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" } TEXT; } else { throw new \RuntimeException('Invalid path'); } return ResponseParser::convert($response, ResponseParser::MODE_LOOSE)->toString(); })); $oauth = new AuthorizationCode($http, new Url('http://127.0.0.1/api'), Environment::getService('importer')); $oauth->setClientPassword(self::CLIENT_ID, self::CLIENT_SECRET); $accessToken = $oauth->getAccessToken('SplxlOBeZQQYbYS6WxSbIA'); $this->assertEquals('2YotnFZFEjr1zCsicMWpAA', $accessToken->getAccessToken()); $this->assertEquals('example', $accessToken->getTokenType()); $this->assertEquals(3600, $accessToken->getExpiresIn()); }
protected function getAuthorizationCode($code, $state) { $testCase = $this->testCase; $http = new Http(new Callback(function (RequestInterface $request) use($testCase) { // api request if ($request->getUri()->getPath() == '/api') { $testCase->assertEquals('Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW', (string) $request->getHeader('Authorization')); $testCase->assertEquals('application/x-www-form-urlencoded', (string) $request->getHeader('Content-Type')); $response = <<<TEXT HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" } TEXT; } else { throw new \RuntimeException('Invalid path'); } return ResponseParser::convert($response, ResponseParser::MODE_LOOSE)->toString(); })); $oauth = new AuthorizationCode($http, new Url('http://127.0.0.1/api'), Environment::getService('importer')); $oauth->setClientPassword(ClientCredentialsTest::CLIENT_ID, ClientCredentialsTest::CLIENT_SECRET); return $oauth; }
public function request(RequestInterface $request, Options $options) { $url = $request->getUri(); foreach ($this->resources as $resource) { $resourceUrl = new Url($resource['url']); if ($resource['method'] == $request->getMethod() && $resourceUrl->getHost() == $url->getHost() && $resourceUrl->getPath() == $url->getPath() && $resourceUrl->getQuery() == $url->getQuery()) { $response = $resource['handler']($request); return ResponseParser::convert($response); } } throw new Exception('Resource not available ' . $request->getMethod() . ' ' . $url); }
public function testCookieStore() { $store = new CookieStore\Memory(); $http = new Http(new Handler\Callback(function ($request) { $response = <<<TEXT HTTP/1.1 200 OK Content-Encoding: gzip Content-Type: text/html; charset=utf-8 Date: Sat, 04 Jan 2014 18:19:45 GMT ETag: "815832758" Set-Cookie: webmaker.sid=s%3Aj%3A%7B%22_csrfSecret%22%3A%22uMs5W0M2tR2ewHNiJQye7lpe%22%7D.wSMQqQeiDgatt0Smv2Nbq5g92lX04%2FmOBiiRdPZIuro; Path=/; Expires=Tue, 04 Feb 2024 18:19:45 GMT; HttpOnly; Secure Strict-Transport-Security: max-age=15768000 Vary: Accept-Encoding X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block transfer-encoding: chunked Connection: keep-alive foobar TEXT; return ResponseParser::convert($response, ResponseParser::MODE_LOOSE)->toString(); })); $http->setCookieStore($store); $request = new GetRequest(new Url('http://localhost.com')); $response = $http->request($request); $cookies = $store->load('localhost.com'); $this->assertTrue(isset($cookies['webmaker.sid'])); $this->assertEquals('webmaker.sid', $cookies['webmaker.sid']->getName()); $this->assertEquals('s%3Aj%3A%7B%22_csrfSecret%22%3A%22uMs5W0M2tR2ewHNiJQye7lpe%22%7D.wSMQqQeiDgatt0Smv2Nbq5g92lX04%2FmOBiiRdPZIuro', $cookies['webmaker.sid']->getValue()); $this->assertEquals(new \DateTime('Tue, 04 Feb 2024 18:19:45 GMT'), $cookies['webmaker.sid']->getExpires()); $this->assertEquals('/', $cookies['webmaker.sid']->getPath()); $this->assertEquals(null, $cookies['webmaker.sid']->getDomain()); $this->assertEquals(true, $cookies['webmaker.sid']->getSecure()); $this->assertEquals(true, $cookies['webmaker.sid']->getHttpOnly()); // now we have stored the cookie we check whether we get it on the next // request $testCase = $this; $http = new Http(new Handler\Callback(function ($request) use($testCase) { $cookie = $request->getHeader('Cookie'); $testCase->assertEquals('webmaker.sid=s%3Aj%3A%7B%22_csrfSecret%22%3A%22uMs5W0M2tR2ewHNiJQye7lpe%22%7D.wSMQqQeiDgatt0Smv2Nbq5g92lX04%2FmOBiiRdPZIuro', (string) $cookie); $response = <<<TEXT HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Date: Sat, 04 Jan 2014 18:19:45 GMT foobar TEXT; return ResponseParser::convert($response, ResponseParser::MODE_LOOSE)->toString(); })); $http->setCookieStore($store); $request = new GetRequest(new Url('http://localhost.com')); $response = $http->request($request); }
public function request(RequestInterface $request, Options $options) { try { $response = call_user_func_array($this->callback, array($request, $options)); if ($response instanceof Response) { return $response; } else { return ResponseParser::convert((string) $response); } } catch (\PHPUnit_Framework_Exception $e) { throw $e; } catch (\ErrorException $e) { throw $e; } }
/** * Converts the response object to an http response string * * @return string */ public function toString() { $response = ResponseParser::buildStatusLine($this) . Http::$newLine; $headers = ResponseParser::buildHeaderFromMessage($this); foreach ($headers as $header) { $response .= $header . Http::$newLine; } $response .= Http::$newLine; $response .= (string) $this->getBody(); return $response; }
public function testFlow() { $testCase = $this; $http = new Http(new Callback(function (RequestInterface $request) use($testCase) { // request token if ($request->getUri()->getPath() == '/requestToken') { $auth = Authentication::decodeParameters((string) $request->getHeader('Authorization')); $testCase->assertEquals(self::CONSUMER_KEY, $auth['oauth_consumer_key']); $testCase->assertEquals('HMAC-SHA1', $auth['oauth_signature_method']); $testCase->assertTrue(isset($auth['oauth_timestamp'])); $testCase->assertTrue(isset($auth['oauth_nonce'])); $testCase->assertEquals('1.0', $auth['oauth_version']); $testCase->assertEquals('oob', $auth['oauth_callback']); $testCase->assertTrue(isset($auth['oauth_signature'])); $tmpToken = self::TMP_TOKEN; $tmpTokenSecret = self::TMP_TOKEN_SECRET; $response = <<<TEXT HTTP/1.1 200 OK Date: Thu, 26 Sep 2013 16:36:25 GMT Content-Type: application/x-www-form-urlencoded oauth_token={$tmpToken}&oauth_token_secret={$tmpTokenSecret}&oauth_callback_confirmed=1 TEXT; } elseif ($request->getUri()->getPath() == '/accessToken') { $auth = Authentication::decodeParameters((string) $request->getHeader('Authorization')); $testCase->assertEquals(self::CONSUMER_KEY, $auth['oauth_consumer_key']); $testCase->assertEquals(self::TMP_TOKEN, $auth['oauth_token']); $testCase->assertEquals('HMAC-SHA1', $auth['oauth_signature_method']); $testCase->assertTrue(isset($auth['oauth_timestamp'])); $testCase->assertTrue(isset($auth['oauth_nonce'])); $testCase->assertEquals('1.0', $auth['oauth_version']); $testCase->assertEquals(self::VERIFIER, $auth['oauth_verifier']); $testCase->assertTrue(isset($auth['oauth_signature'])); $token = self::TOKEN; $tokenSecret = self::TOKEN_SECRET; $response = <<<TEXT HTTP/1.1 200 OK Date: Thu, 26 Sep 2013 16:36:26 GMT Content-Type: application/x-www-form-urlencoded oauth_token={$token}&oauth_token_secret={$tokenSecret} TEXT; } elseif ($request->getUri()->getPath() == '/api') { $auth = Authentication::decodeParameters((string) $request->getHeader('Authorization')); $testCase->assertEquals(self::CONSUMER_KEY, $auth['oauth_consumer_key']); $testCase->assertEquals(self::TOKEN, $auth['oauth_token']); $testCase->assertEquals('HMAC-SHA1', $auth['oauth_signature_method']); $testCase->assertTrue(isset($auth['oauth_timestamp'])); $testCase->assertTrue(isset($auth['oauth_nonce'])); $testCase->assertEquals('1.0', $auth['oauth_version']); $testCase->assertTrue(isset($auth['oauth_signature'])); $response = <<<TEXT HTTP/1.1 200 OK Date: Thu, 26 Sep 2013 16:36:26 GMT Content-Type: text/html; charset=UTF-8 SUCCESS TEXT; } else { throw new \RuntimeException('Invalid path'); } return ResponseParser::convert($response, ResponseParser::MODE_LOOSE)->toString(); })); $oauth = new Oauth($http); // request token $url = new Url('http://127.0.0.1/requestToken'); $response = $oauth->requestToken($url, self::CONSUMER_KEY, self::CONSUMER_SECRET); $this->assertInstanceOf('PSX\\Oauth\\Provider\\Data\\Response', $response); $this->assertEquals(self::TMP_TOKEN, $response->getToken()); $this->assertEquals(self::TMP_TOKEN_SECRET, $response->getTokenSecret()); // if we have optained temporary credentials we can redirect the user // to grant access to the credentials // $oauth->userAuthorization($url, array('oauth_token' => $response->getToken())) // if the user gets redirected back we can exchange the temporary // credentials to an access token we also get an verifier as GET // parameter $url = new Url('http://127.0.0.1/accessToken'); $response = $oauth->accessToken($url, self::CONSUMER_KEY, self::CONSUMER_SECRET, self::TMP_TOKEN, self::TMP_TOKEN, self::VERIFIER); $this->assertInstanceOf('PSX\\Oauth\\Provider\\Data\\Response', $response); $this->assertEquals(self::TOKEN, $response->getToken()); $this->assertEquals(self::TOKEN_SECRET, $response->getTokenSecret()); // now we can make an request to the protected api $url = new Url('http://127.0.0.1/api'); $auth = $oauth->getAuthorizationHeader($url, self::CONSUMER_KEY, self::CONSUMER_SECRET, self::TOKEN, self::TOKEN_SECRET, 'HMAC-SHA1', 'GET'); $request = new GetRequest($url, array('Authorization' => $auth)); $response = $http->request($request); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('SUCCESS', (string) $response->getBody()); }
public static function assignHttpContext($context, RequestInterface $request, Options $options = null) { stream_context_set_option($context, 'http', 'method', $request->getMethod()); stream_context_set_option($context, 'http', 'protocol_version', $request->getProtocolVersion() ?: 1.1); // until chunked transfer encoding if fully implemented we remove the // header if ($request->hasHeader('Transfer-Encoding')) { $request->removeHeader('Transfer-Encoding'); } // set header $headers = implode(Http::$newLine, ResponseParser::buildHeaderFromMessage($request)); stream_context_set_option($context, 'http', 'header', $headers); // set body $body = $request->getBody(); if ($body !== null && !in_array($request->getMethod(), array('HEAD', 'GET'))) { stream_context_set_option($context, 'http', 'content', (string) $body); } if ($options !== null) { // set proxy $proxy = $options->getProxy(); if (!empty($proxy)) { stream_context_set_option($context, 'http', 'proxy', $proxy); } // set follow location stream_context_set_option($context, 'http', 'follow_location', (int) $options->getFollowLocation()); stream_context_set_option($context, 'http', 'max_redirects', $options->getMaxRedirects()); // set timeout $timeout = $options->getTimeout(); if (!empty($timeout)) { stream_context_set_option($context, 'http', 'timeout', $timeout); } } }
protected function sendHeaders(ResponseInterface $response) { $headers = ResponseParser::buildHeaderFromMessage($response); foreach ($headers as $header) { $this->sendHeader($header); } }
public function testConvert() { $httpResponse = 'HTTP/1.1 200 OK' . Http::$newLine; $httpResponse .= 'Content-type: text/html; charset=UTF-8' . Http::$newLine; $httpResponse .= Http::$newLine; $httpResponse .= 'foobar'; $response = ResponseParser::convert($httpResponse); $this->assertEquals('HTTP/1.1', $response->getProtocolVersion()); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('OK', $response->getReasonPhrase()); $this->assertEquals('text/html; charset=UTF-8', (string) $response->getHeader('Content-Type')); $this->assertEquals('foobar', $response->getBody()); }
public function request(RequestInterface $request, Options $options) { $context = stream_context_create(); // ssl $scheme = null; if ($options->getSsl() !== false && ($options->getSsl() === true || strcasecmp($request->getUri()->getScheme(), 'https') === 0)) { $transports = stream_get_transports(); if (in_array('tls', $transports)) { $scheme = 'tls'; } elseif (in_array('ssl', $transports)) { $scheme = 'ssl'; } else { throw new NotSupportedException('https is not supported'); } Stream::assignSslContext($context, $options); } else { $scheme = 'tcp'; } // port $port = $request->getUri()->getPort(); if (empty($port)) { $port = getservbyname($request->getUri()->getScheme(), 'tcp'); } // open socket set_error_handler(__CLASS__ . '::handleError'); $timeout = ini_get('default_socket_timeout'); $handle = stream_socket_client($scheme . '://' . $request->getUri()->getHost() . ':' . $port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context); restore_error_handler(); if ($handle !== false) { // timeout $timeout = $options->getTimeout(); if (!empty($timeout)) { stream_set_timeout($handle, $timeout); } // callback $callback = $options->getCallback(); if (!empty($callback)) { call_user_func_array($callback, array($handle, $request)); } // write header $headers = ResponseParser::buildHeaderFromMessage($request); fwrite($handle, Http\RequestParser::buildStatusLine($request) . Http::$newLine); foreach ($headers as $header) { fwrite($handle, $header . Http::$newLine); } fwrite($handle, Http::$newLine); fflush($handle); // write body $body = $request->getBody(); if ($body !== null && !in_array($request->getMethod(), array('HEAD', 'GET'))) { if ($request->getHeader('Transfer-Encoding') == 'chunked') { while (!$body->eof()) { $chunk = $body->read($this->chunkSize); $len = strlen($chunk); if ($len > 0) { fwrite($handle, dechex($len) . Http::$newLine . $chunk . Http::$newLine); fflush($handle); } } fwrite($handle, '0' . Http::$newLine . Http::$newLine); fflush($handle); } else { fwrite($handle, (string) $body); fflush($handle); } } // read header $headers = array(); do { $header = trim(fgets($handle)); if (!empty($header)) { $headers[] = $header; } } while (!empty($header)); // check for timeout $meta = stream_get_meta_data($handle); if ($meta['timed_out']) { throw new HandlerException('Connection timeout'); } // build response $response = ResponseParser::buildResponseFromHeader($headers); // create stream $contentLength = (int) $response->getHeader('Content-Length'); $chunkedEncoding = $response->getHeader('Transfer-Encoding') == 'chunked'; if ($request->getMethod() != 'HEAD') { $response->setBody(new SocksStream($handle, $contentLength, $chunkedEncoding)); } else { fclose($handle); $response->setBody(new StringStream()); } return $response; } else { throw new HandlerException(!empty($errstr) ? $errstr : 'Could not open socket'); } }
public function request(RequestInterface $request, Options $options) { $this->header = array(); $this->body = fopen('php://temp', 'r+'); $handle = curl_init($request->getUri()->toString()); curl_setopt($handle, CURLOPT_HEADER, false); curl_setopt($handle, CURLOPT_RETURNTRANSFER, false); curl_setopt($handle, CURLOPT_HEADERFUNCTION, array($this, 'header')); curl_setopt($handle, CURLOPT_WRITEFUNCTION, array($this, 'write')); curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $request->getMethod()); // set header $headers = ResponseParser::buildHeaderFromMessage($request); if (!empty($headers)) { if (!$request->hasHeader('Expect')) { $headers[] = 'Expect:'; } curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); } // set body $body = $request->getBody(); if ($body !== null && !in_array($request->getMethod(), array('HEAD', 'GET'))) { if ($request->getHeader('Transfer-Encoding') == 'chunked') { curl_setopt($handle, CURLOPT_UPLOAD, true); curl_setopt($handle, CURLOPT_READFUNCTION, function ($handle, $fd, $length) use($body) { return $body->read($length); }); } else { curl_setopt($handle, CURLOPT_POSTFIELDS, (string) $body); } } // set proxy $proxy = $options->getProxy(); if (!empty($proxy)) { curl_setopt($handle, CURLOPT_PROXY, $proxy); } // set follow location curl_setopt($handle, CURLOPT_FOLLOWLOCATION, $options->getFollowLocation() && $this->hasFollowLocation); curl_setopt($handle, CURLOPT_MAXREDIRS, $options->getMaxRedirects()); // set ssl if ($options->getSsl() !== false && ($options->getSsl() === true || strcasecmp($request->getUri()->getScheme(), 'https') === 0)) { $caPath = $options->getCaPath(); if (!empty($caPath)) { curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 2); if (is_file($caPath)) { curl_setopt($handle, CURLOPT_CAINFO, $caPath); } elseif (is_dir($caPath)) { curl_setopt($handle, CURLOPT_CAPATH, $caPath); } } else { curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0); } } // set timeout $timeout = $options->getTimeout(); if (!empty($timeout)) { curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); } // callback $callback = $options->getCallback(); if (!empty($callback)) { call_user_func_array($callback, array($handle, $request)); } curl_exec($handle); // if follow location is active modify the header since all headers from // each redirection are included if ($options->getFollowLocation() && $this->hasFollowLocation) { $positions = array(); foreach ($this->header as $key => $header) { if (substr($header, 0, 5) == 'HTTP/') { $positions[] = $key; } } if (count($positions) > 1) { $this->header = array_slice($this->header, end($positions) - 1); } } if (curl_errno($handle)) { throw new HandlerException('Curl error: ' . curl_error($handle)); } curl_close($handle); // build response rewind($this->body); $response = ResponseParser::buildResponseFromHeader($this->header); if ($request->getMethod() != 'HEAD') { $response->setBody(new TempStream($this->body)); } else { $response->setBody(new StringStream()); } return $response; }