Пример #1
0
 /**
  * 
  * @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);
 }