public function testRequestCanSetAndRetrieveUri() { $request = new Request(); $request->setUri('/foo'); $this->assertEquals('/foo', $request->getUri()); $this->assertInstanceOf('Zend\\Uri\\Uri', $request->uri()); $this->assertEquals('/foo', $request->uri()->toString()); $this->assertEquals('/foo', $request->getUri()); }
/** * Login * * @param \Zend\Http\Request $request * @param \Zend\Http\Response $response * @return null|array|\Zend\Http\Response */ public function login(array $options, HttpRequest $request, HttpResponse $response = null) { if (null === $response) { $response = new PhpResponse(); } $session = $this->getSessionContainer(); $code = $request->getQuery('code'); if (empty($options['redirect_uri'])) { $options['redirect_uri'] = $request->getUri()->getScheme() . '://' . $this->getSiteInfo()->getFulldomain() . $request->getRequestUri(); } if (empty($code)) { $session['state'] = String::generateRandom(32); $session['redirect_uri'] = $options['redirect_uri']; $response->setContent('')->setStatusCode(302)->getHeaders()->clearHeaders()->addHeaderLine('Location', static::DIALOG_URI . '?' . http_build_query(array('client_id' => $options['client_id'], 'redirect_uri' => $options['redirect_uri'], 'state' => $session['state'], 'scope' => 'email'))); if ($response instanceof PhpResponse) { $response->send(); exit; } else { return $response; } } $state = $request->getQuery('state'); if (empty($session['state']) || $state !== $session['state']) { return null; } $client = $this->getHttpClient(); $params = null; @parse_str($client->setMethod('GET')->setUri(static::ACCESS_URI)->setParameterGet(array('client_id' => $options['client_id'], 'redirect_uri' => $session['redirect_uri'], 'client_secret' => $options['client_secret'], 'code' => $code))->send()->getBody(), $params); unset($session['state']); unset($session['redirect_uri']); if (empty($params['access_token'])) { return null; } return @json_decode($client->setMethod('GET')->setUri(static::API_URI)->setParameterGet(array('access_token' => $params['access_token']))->send()->getBody(), true); }
/** * @inheritdoc */ public function request(array $params) { try { $request = new Request(); $headers = $request->getHeaders(); $request->setUri($params['url']); $headers->addHeaderLine('Accept-Encoding', 'gzip,deflate'); if ($params['config']->isAuthenticationPossible() === true && $this->option['keys']['public'] !== null && $this->option['keys']['private'] !== null) { /** * Note: DATE_RFC1123 my not be RFC 1123 compliant, depending on your platform. * @link http://www.php.net/manual/de/function.gmdate.php#25031 */ $date = gmdate('D, d M Y H:i:s \\G\\M\\T'); $path = $request->getUri()->getPath(); $headers->addHeaderLine('Date', $date); $headers->addHeaderLine('Authorization', $this->signRequest('GET', $date, $path)); } if (isset($params['lastmodified'])) { $headers->addHeaderLine('If-Modified-Since', $params['lastmodified']); } $response = $this->client->send($request); $body = $response->getBody(); $headers = null; if ($this->option['responseheader']) { $headers = $response->getHeaders()->toArray(); $this->lastResponseHeaders = $headers; } } catch (\Exception $e) { throw new ClientException('Client exception catched, use getPrevious().', 0, $e); } return $this->createResponse($params['config']->isJson(), $response->getStatusCode(), $body, $headers); }
/** * Check if the HTTP request is a CORS request by checking if the Origin header is present and that the * request URI is not the same as the one in the Origin * * @param HttpRequest $request * @return bool */ public function isCorsRequest(HttpRequest $request) { $headers = $request->getHeaders(); if (!$headers->has('Origin')) { return false; } $originUri = UriFactory::factory($headers->get('Origin')->getFieldValue()); $requestUri = $request->getUri(); // According to the spec (http://tools.ietf.org/html/rfc6454#section-4), we should check host, port and scheme return !($originUri->getHost() === $requestUri->getHost()) || !($originUri->getPort() === $requestUri->getPort()) || !($originUri->getScheme() === $requestUri->getScheme()); }
/** * Perform an API request. * * Returns a Response object if the API HTTP request return a valid * response, false otherwise. * * @param Request $request * @return Response|false */ protected function apiRequest(Request $request) { $httpClient = $this->getHttpClient(); // check session if ($this->token === null && substr($request->getUri()->getPath(), 0, 13) !== '/REST/Session') { throw new Exception\NotAuthenticatedException('An API session must be established by calling ' . 'Dyn\\TrafficManagement::createSession() before making other API calls'); } $this->lastResponse = null; $this->lastHttpResponse = $httpClient->dispatch($request); if ($this->lastHttpResponse->isSuccess()) { $json = json_decode($this->lastHttpResponse->getBody()); if (!$json) { return false; } // parse response and store $this->lastResponse = Response::fromJson($json); return $this->lastResponse; } return false; }
public function create($data) { $router = $this->serviceLocator->get('router'); $controllerLoader = $this->serviceLocator->get('controllerLoader'); foreach ($data as $key => $requestData) { $request = new Request(); $request->setMethod($requestData['method']); $request->setUri($requestData['uri']); $queryString = $request->getUri()->getQuery(); if ($queryString) { $query = []; parse_str($queryString, $query); $request->setQuery(new Parameters($query)); } if (isset($requestData['headers'])) { foreach ($requestData['headers'] as $name => $value) { $request->getHeaders()->addHeaderLine($name, $value); } } $request->getHeaders()->addHeaders([$this->request->getHeaders()->get('Accept'), $this->request->getHeaders()->get('Content-Type')]); if (isset($requestData['content'])) { $request->setContent(json_encode($requestData['content'])); } $response = new Response(); $event = new MvcEvent(); $event->setRequest($request); $event->setResponse($response); $match = $router->match($request); RouteListener::resolveController($match); $contentModel = null; if (!isset($match) || $match->getMatchedRouteName() != 'rest.' . $this->options->getManifestName()) { $contentModel = $this->createExceptionContentModel(new Exception\RuntimeException(sprintf('%s uri is not a rest route, so is not supported by batch controller.', $requestData['uri'])), $event); } else { try { $controller = $controllerLoader->get($match->getParam('controller')); } catch (\Zend\ServiceManager\Exception\ServiceNotFoundException $exception) { $contentModel = $this->createExceptionContentModel($exception, $event); $response->setStatusCode(404); } $event->setRouteMatch($match); $controller->setEvent($event); if (!isset($contentModel)) { try { $contentModel = $controller->dispatch($request, $response); } catch (\Exception $exception) { $contentModel = $this->createExceptionContentModel($exception, $event); } } } $headers = []; foreach ($response->getHeaders() as $header) { $headers[$header->getFieldName()] = $header->getFieldValue(); } $responseModel = new JsonModel(['status' => $response->getStatusCode(), 'headers' => $headers]); if ($contentModel instanceof ModelInterface) { $responseModel->addChild($contentModel, 'content'); } $this->model->addChild($responseModel, $key); } return $this->model; }
/** * Parse Digest Authorization header * * @param string $header Client's Authorization: HTTP header * @return array|bool Data elements from header, or false if any part of * the header is invalid */ protected function _parseDigestAuth($header) { $temp = null; $data = array(); // See ZF-1052. Detect invalid usernames instead of just returning a // 400 code. $ret = preg_match('/username="******"]+)"/', $header, $temp); if (!$ret || empty($temp[1]) || !ctype_print($temp[1]) || strpos($temp[1], ':') !== false) { $data['username'] = '******'; } else { $data['username'] = $temp[1]; } $temp = null; $ret = preg_match('/realm="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!ctype_print($temp[1]) || strpos($temp[1], ':') !== false) { return false; } else { $data['realm'] = $temp[1]; } $temp = null; $ret = preg_match('/nonce="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!ctype_xdigit($temp[1])) { return false; } $data['nonce'] = $temp[1]; $temp = null; $ret = preg_match('/uri="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } // Section 3.2.2.5 in RFC 2617 says the authenticating server must // verify that the URI field in the Authorization header is for the // same resource requested in the Request Line. $rUri = $this->request->getUri(); $cUri = UriFactory::factory($temp[1]); // Make sure the path portion of both URIs is the same if ($rUri->getPath() != $cUri->getPath()) { return false; } // Section 3.2.2.5 seems to suggest that the value of the URI // Authorization field should be made into an absolute URI if the // Request URI is absolute, but it's vague, and that's a bunch of // code I don't want to write right now. $data['uri'] = $temp[1]; $temp = null; $ret = preg_match('/response="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (32 != strlen($temp[1]) || !ctype_xdigit($temp[1])) { return false; } $data['response'] = $temp[1]; $temp = null; // The spec says this should default to MD5 if omitted. OK, so how does // that square with the algo we send out in the WWW-Authenticate header, // if it can easily be overridden by the client? $ret = preg_match('/algorithm="?(' . $this->algo . ')"?/', $header, $temp); if ($ret && !empty($temp[1]) && in_array($temp[1], $this->supportedAlgos)) { $data['algorithm'] = $temp[1]; } else { $data['algorithm'] = 'MD5'; // = $this->algo; ? } $temp = null; // Not optional in this implementation $ret = preg_match('/cnonce="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!ctype_print($temp[1])) { return false; } $data['cnonce'] = $temp[1]; $temp = null; // If the server sent an opaque value, the client must send it back if ($this->useOpaque) { $ret = preg_match('/opaque="([^"]+)"/', $header, $temp); if (!$ret || empty($temp[1])) { // Big surprise: IE isn't RFC 2617-compliant. $headers = $this->request->getHeaders(); if (!$headers->has('User-Agent')) { return false; } $userAgent = $headers->get('User-Agent')->getFieldValue(); if (false === strpos($userAgent, 'MSIE')) { return false; } $temp[1] = ''; $this->ieNoOpaque = true; } // This implementation only sends MD5 hex strings in the opaque value if (!$this->ieNoOpaque && (32 != strlen($temp[1]) || !ctype_xdigit($temp[1]))) { return false; } $data['opaque'] = $temp[1]; $temp = null; } // Not optional in this implementation, but must be one of the supported // qop types $ret = preg_match('/qop="?(' . implode('|', $this->supportedQops) . ')"?/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (!in_array($temp[1], $this->supportedQops)) { return false; } $data['qop'] = $temp[1]; $temp = null; // Not optional in this implementation. The spec says this value // shouldn't be a quoted string, but apparently some implementations // quote it anyway. See ZF-1544. $ret = preg_match('/nc="?([0-9A-Fa-f]{8})"?/', $header, $temp); if (!$ret || empty($temp[1])) { return false; } if (8 != strlen($temp[1]) || !ctype_xdigit($temp[1])) { return false; } $data['nc'] = $temp[1]; $temp = null; return $data; }
protected function execute($url, $method, array $query = null, array $rawdata = null, Headers $headers = null) { $request = new Request(); // Headers $request->getHeaders()->addHeaders(array('Content-Type' => $this->getContentType())); if ($headers) { $request->getHeaders()->addHeaders($headers); } // Query if ($query) { $request->setQuery(new Parameters($query)); } $request->setUri($url)->setMethod($method); switch ($method) { case self::HTTP_VERB_POST: case self::HTTP_VERB_PUT: case self::HTTP_VERB_PATCH: if ($rawdata) { $request->setPost(new Parameters($rawdata)); } break; } $client = new HttpClient('', $this->_httpClientOptions); $adapter = $client->getAdapter(); /* @var $adapter Curl */ $secure = $request->getUri()->getScheme() == 'https'; $adapter->connect($request->getUri()->getHost(), $request->getUri()->getPort(), $secure); $ch = $adapter->getHandle(); // Set URL curl_setopt($ch, CURLOPT_URL, $request->getUriString() . '?' . $request->getQuery()->toString()); // ensure correct curl call $curlValue = true; switch ($method) { case 'GET': $curlMethod = CURLOPT_HTTPGET; break; case 'POST': $curlMethod = CURLOPT_POST; break; case 'PUT': case 'PATCH': case 'DELETE': case 'OPTIONS': case 'TRACE': case 'HEAD': $curlMethod = CURLOPT_CUSTOMREQUEST; $curlValue = $method; break; default: // For now, through an exception for unsupported request methods throw new Exception("Method '{$method}' currently not supported"); } // mark as HTTP request and set HTTP method curl_setopt($ch, CURL_HTTP_VERSION_1_1, true); curl_setopt($ch, $curlMethod, $curlValue); // ensure actual response is returned curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // set callback function if ($this->getCallbackWriteFunction() instanceof \Closure) { curl_setopt($ch, CURLOPT_WRITEFUNCTION, $this->getCallbackWriteFunction()); } // ensure headers are also returned curl_setopt($ch, CURLOPT_HEADER, false); // set callback function if ($this->getCallbackHeaderFunction() instanceof \Closure) { curl_setopt($ch, CURLOPT_HEADERFUNCTION, $this->getCallbackHeaderFunction()); } // Treating basic auth headers in a special way if ($request->getHeaders() instanceof Headers) { $headersArray = $request->getHeaders()->toArray(); if (array_key_exists('Authorization', $headersArray) && 'Basic' == substr($headersArray['Authorization'], 0, 5)) { curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, base64_decode(substr($headersArray['Authorization'], 6))); unset($headersArray['Authorization']); } // set additional headers if (!isset($headersArray['Accept'])) { $headersArray['Accept'] = ''; } $curlHeaders = array(); foreach ($headersArray as $key => $value) { $curlHeaders[] = $key . ': ' . $value; } curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders); } // POST body switch ($method) { case 'POST': case 'PUT': case 'PATCH': curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPost()->toArray()); break; } $this->_handlers[uniqid()] = $ch; end($this->_handlers); return key($this->_handlers); }
/** * Normailze Uri * * @return mixed */ public function normalize() { return $this->request->getUri()->normalize(); }
protected function getSubRequest($batchRequest, array $requestData) { $request = new Request(); $request->setMethod($requestData['method']); $request->setUri($requestData['uri']); $queryString = $request->getUri()->getQuery(); if ($queryString) { $query = []; parse_str($queryString, $query); $request->setQuery(new Parameters($query)); } $requestHeaders = [$batchRequest->getHeaders()->get('Accept'), $batchRequest->getHeaders()->get('Content-Type')]; if (isset($requestData['headers'])) { foreach ($requestData['headers'] as $name => $value) { $requestHeaders[] = GenericHeader::fromString($name . ': ' . $value); } } $request->getHeaders()->addHeaders($requestHeaders); if (isset($requestData['content'])) { $request->setContent(json_encode($requestData['content'])); } return $request; }
/** * @param Request $request * @param User $apiClient * @param string $timestamp * @return string */ private function createHmac(Request $request, User $apiClient, $timestamp) { $method = $request->getMethod(); $uri = $request->getUri()->getPath(); $query = $request->getQuery(); $query->offsetUnset('q'); $query->toString(); // Remove internal routing parameter if (isset($query['q'])) { unset($query['q']); } //$key = $apiClient->getUsername(); $key = 'testuser'; // Debug $input = trim(join(' ', [$timestamp, $method, $uri, $query->toString()])); return hash_hmac('sha256', $input, $key, false); }
/** * Converts the request into a url. * * This encodes the query parameters associated with the request. * * @param Request $request * @return string */ public static function toUriString(Request $request) { $uri = clone $request->getUri(); $uri->setQuery(array_merge($uri->getQueryAsArray(), $request->getQuery()->toArray())); return $uri->toString(); }