public static function makeRequest(HttpRequest $request)
 {
     $requestUri = $request->getRequestUri()->getUri();
     // if the request is towards a file URL, return the response constructed
     // from file
     if (0 === strpos($requestUri, "file:///")) {
         return HttpResponse::fromFile($requestUri);
     }
     $httpResponse = new HttpResponse();
     $curlChannel = curl_init();
     curl_setopt($curlChannel, CURLOPT_URL, $requestUri);
     curl_setopt($curlChannel, CURLOPT_FOLLOWLOCATION, 1);
     curl_setopt($curlChannel, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($curlChannel, CURLOPT_TIMEOUT, 10);
     if ($request->getRequestMethod() === "POST") {
         curl_setopt($curlChannel, CURLOPT_POST, 1);
         curl_setopt($curlChannel, CURLOPT_POSTFIELDS, $request->getContent());
     }
     $basicAuthUser = $request->getBasicAuthUser();
     $basicAuthPass = $request->getBasicAuthPass();
     if (NULL !== $basicAuthUser) {
         $request->setHeader("Authorization", "Basic " . base64_encode($basicAuthUser . ":" . $basicAuthPass));
     }
     // Including HTTP headers in request
     $headers = $request->getHeaders(TRUE);
     if (!empty($headers)) {
         curl_setopt($curlChannel, CURLOPT_HTTPHEADER, $headers);
     }
     // Connect to SSL/TLS server, validate certificate and host
     if ($request->getRequestUri()->getScheme() === "https") {
         curl_setopt($curlChannel, CURLOPT_SSL_VERIFYPEER, 1);
         curl_setopt($curlChannel, CURLOPT_SSL_VERIFYHOST, 2);
     }
     // Callback to extract all the HTTP headers from the response...
     // In order to really correctly parse HTTP headers one would have to look at RFC 2616...
     curl_setopt($curlChannel, CURLOPT_HEADERFUNCTION, function ($curlChannel, $header) use($httpResponse) {
         // Ignore Status-Line (RFC 2616, section 6.1)
         if (0 === preg_match('|^HTTP/\\d+.\\d+ [1-5]\\d\\d|', $header)) {
             // Only deal with header lines that contain a colon
             if (strpos($header, ":") !== FALSE) {
                 // Only deal with header lines that contain a colon
                 list($key, $value) = explode(":", trim($header));
                 $httpResponse->setHeader(trim($key), trim($value));
             }
         }
         return strlen($header);
     });
     $output = curl_exec($curlChannel);
     if ($errorNumber = curl_errno($curlChannel)) {
         throw new OutgoingHttpRequestException(curl_error($curlChannel));
     }
     $httpResponse->setStatusCode(curl_getinfo($curlChannel, CURLINFO_HTTP_CODE));
     $httpResponse->setContent($output);
     curl_close($curlChannel);
     return $httpResponse;
 }
Example #2
0
 /**
  * Executes an HTTP transaction and returns the response.
  *
  * @param HttpRequest $request
  * @return HttpResponse
  */
 public function getResponse(HttpRequest $request)
 {
     $uri = $request->getUrl();
     $headers = $request->getHeaders();
     $flatHeaders = [];
     foreach ($headers as $key => $value) {
         $flatHeaders[] = $key . ": " . $value;
     }
     $flatHeaders[] = 'Connection: Keep-Alive';
     $flatHeaders[] = 'Expect:';
     $flatHeaders[] = 'Accept-Language: en-GB';
     $flatHeaders[] = 'Cache-Control: no-cache';
     $flatHeaders[] = 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)';
     $curl = curl_init($uri);
     curl_setopt($curl, CURLOPT_HEADER, false);
     $payload = $request->getPayload();
     switch ($request->getMethod()) {
         case "head":
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "HEAD");
             break;
         case "delete":
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
             break;
         case "post":
             curl_setopt($curl, CURLOPT_POST, true);
             curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
             break;
         case "put":
             curl_setopt($curl, CURLOPT_POST, true);
             curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
             break;
     }
     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($curl, CURLOPT_HTTPHEADER, $flatHeaders);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
     $response = curl_exec($curl);
     $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
     curl_close($curl);
     $httpResponse = new HttpResponse();
     $httpResponse->setResponseBody($response);
     $httpResponse->setResponseCode($responseCode);
     return $httpResponse;
 }
Example #3
0
 /**
  * Signs request with signature v3
  *
  * @param   \HttpRequest   $request    Http request
  * @param   string         $subdomain  optional A subdomain
  */
 protected function signRequestV3($request, $subdomain = null)
 {
     $time = time();
     //Gets the http method name
     $httpMethod = self::$httpMethods[$request->getMethod()];
     $components = parse_url($request->getUrl());
     //Retrieves headers from request
     $options = $request->getHeaders();
     //Adding timestamp
     if (!isset($options['Date'])) {
         $options['Date'] = gmdate('r', $time);
         $request->addHeaders(['Date' => $options['Date']]);
     }
     //This also includes a mock objects which look like "Mock_S3QueryClient_d65a1dc1".
     if (preg_match('#(?<=[_\\\\])S3QueryClient(?=_|$)#', get_class($this))) {
         $amzHeaders = [];
         foreach ($options as $key => $val) {
             if (preg_match('/^x-amz-/i', $key)) {
                 //Saves amz headers which are used to sign the request
                 $amzHeaders[strtolower($key)] = $val;
             }
         }
         //S3 Client has a special Authorization string
         $canonicalizedAmzHeaders = '';
         if (!empty($amzHeaders)) {
             ksort($amzHeaders);
             foreach ($amzHeaders as $k => $v) {
                 $canonicalizedAmzHeaders .= $k . ':' . trim(preg_replace('/#( *[\\r\\n]+ *)+#/', ' ', $v)) . "\n";
             }
         }
         //Note that in case of multiple sub-resources, sub-resources must be lexicographically sorted
         //by sub-resource name and separated by '&'. e.g. ?acl&versionId=value.
         if (!empty($components['query'])) {
             $canonPath = $components['path'] . '?';
             parse_str($components['query'], $subresources);
             ksort($subresources);
             $allowed = $this->getAllowedSubResources();
             foreach ($subresources as $k => $v) {
                 if (in_array($k, $allowed)) {
                     $canonPath .= $k . ($v !== '' ? '=' . $v : '') . '&';
                 }
             }
             $canonPath = substr($canonPath, 0, -1);
         }
         $canonicalizedResource = (isset($subdomain) ? '/' . strtolower($subdomain) : '') . (isset($canonPath) ? $canonPath : $components['path'] . (!empty($components['query']) ? '?' . $components['query'] : '') . (!empty($components['fragment']) ? '#' . $components['fragment'] : ''));
         $stringToSign = $httpMethod . "\n" . (!empty($options['Content-Md5']) ? $options['Content-Md5'] . '' : '') . "\n" . (!empty($options['Content-Type']) ? $options['Content-Type'] . '' : '') . "\n" . (isset($amzHeaders['x-amz-date']) ? '' : $options['Date'] . "\n") . $canonicalizedAmzHeaders . $canonicalizedResource;
         $options['Authorization'] = "AWS " . $this->awsAccessKeyId . ":" . base64_encode(hash_hmac('sha1', $stringToSign, $this->secretAccessKey, 1));
     } else {
         $options['Authorization'] = "AWS " . $this->awsAccessKeyId . ":" . base64_encode(hash_hmac('sha1', $options['Date'], $this->secretAccessKey, 1));
     }
     $request->addHeaders(['Authorization' => $options['Authorization']]);
 }
Example #4
0
 /**
  * Signs request with signature version 4
  *
  * @param   \HttpRequest $request     Http Request
  * @param   string       $region      optional Overrides region as destination region for multiregional operations
  * @throws  QueryClientException
  */
 protected function signRequestV4($request, $region = null)
 {
     $time = time();
     //Gets the http method name
     $httpMethod = self::$httpMethods[$request->getMethod()];
     //Region is mandatory part for this type of authentication
     $region = $region ?: $this->getAws()->getRegion();
     //Gets host from the url
     $components = parse_url($request->getUrl());
     $crd = gmdate('Ymd', $time) . '/' . $region . '/' . $this->getServiceName() . '/aws4_request';
     $opt = ['X-Amz-Algorithm' => 'AWS4-HMAC-SHA256', 'X-Amz-Credential' => $this->awsAccessKeyId . '/' . $crd, 'X-Amz-Date' => gmdate('Ymd\\THis\\Z', $time), 'X-Amz-Expires' => '86400'];
     $headers = ['X-Amz-Date' => $opt['X-Amz-Date']];
     //Calculating canonicalized query string
     $canonicalizedQueryString = '';
     if (!empty($components['query'])) {
         parse_str($components['query'], $pars);
         ksort($pars);
         foreach ($pars as $k => $v) {
             $canonicalizedQueryString .= '&' . rawurlencode($k) . '=' . rawurlencode($v);
         }
         $canonicalizedQueryString = ltrim($canonicalizedQueryString, '&');
     }
     //Calculating payload
     $payload = '';
     if ($httpMethod == 'POST') {
         if ($request->getBody() != '') {
             $payload = $request->getBody();
         } else {
             $pars = $request->getPostFields();
             foreach ($pars as $k => $v) {
                 //We do not use rawurlencode because httpRequest does not do this, and we need to hash payload
                 $payload .= '&' . urlencode($k) . '=' . urlencode($v);
             }
             $payload = ltrim($payload, '&');
         }
     } elseif ($httpMethod == 'PUT') {
         $payload = $request->getPutData();
         if (empty($payload) && $request->getPutFile()) {
             $headers['X-Amz-Content-Sha256'] = hash_file('sha256', $request->getPutFile());
         }
     }
     if (!isset($headers['X-Amz-Content-Sha256'])) {
         $headers['X-Amz-Content-Sha256'] = hash('sha256', $payload);
     }
     //Adding x-amz headers
     $request->addHeaders($headers);
     //Calculating canonical headers
     $allHeaders = $request->getHeaders();
     $allHeaders['X-Amz-SignedHeaders'] = 'host';
     $signedHeaders = ['host' => $components['host']];
     foreach ($allHeaders as $k => $v) {
         $lk = strtolower($k);
         //This x-amz header does not have to be signed
         if ($lk == 'x-amz-signedheaders') {
             continue;
         }
         if (preg_match('/x-amz-/i', $k) || $lk == 'content-type' || $lk == 'content-md5') {
             $signedHeaders[$lk] = $v;
         }
     }
     ksort($signedHeaders);
     $allHeaders['X-Amz-SignedHeaders'] = join(';', array_keys($signedHeaders));
     $canonicalHeaders = '';
     foreach ($signedHeaders as $k => $v) {
         $canonicalHeaders .= $k . ':' . $v . "\n";
     }
     $canonicalRequest = $httpMethod . "\n" . $components['path'] . "\n" . $canonicalizedQueryString . "\n" . $canonicalHeaders . "\n" . $allHeaders['X-Amz-SignedHeaders'] . "\n" . $headers['X-Amz-Content-Sha256'];
     $stringToSign = $opt['X-Amz-Algorithm'] . "\n" . $opt['X-Amz-Date'] . "\n" . $crd . "\n" . hash('sha256', $canonicalRequest);
     $dateKey = hash_hmac('sha256', gmdate('Ymd', $time), "AWS4" . $this->secretAccessKey, true);
     $dateRegionKey = hash_hmac('sha256', $region, $dateKey, true);
     $dateRegionServiceKey = hash_hmac('sha256', $this->getServiceName(), $dateRegionKey, true);
     $signingKey = hash_hmac('sha256', 'aws4_request', $dateRegionServiceKey, true);
     //X-Amz-Signature
     $signature = hash_hmac('sha256', $stringToSign, $signingKey);
     $headers['Authorization'] = $opt['X-Amz-Algorithm'] . ' ' . 'Credential=' . $opt['X-Amz-Credential'] . ',' . 'SignedHeaders=' . $allHeaders['X-Amz-SignedHeaders'] . ',' . 'Signature=' . $signature;
     $request->addHeaders($headers);
 }
 private function _get_modified_since()
 {
     $requestHeaders = null;
     if (function_exists('apache_request_headers')) {
         $requestHeaders = apache_request_headers();
     } elseif (class_exists('HttpRequest')) {
         $requestHeaders = HttpRequest::getHeaders();
     }
     $modified_since = !empty($requestHeaders) ? $requestHeaders['If-Modified-Since'] : $_SERVER['HTTP_IF_MODIFIED_SINCE'];
     unset($requestHeaders);
     $date = $this->parse_http_date($modified_since);
     return $date !== false ? $date["timestamp"] : false;
 }