Exemplo n.º 1
0
 /**
  * Perform the HTTP request.
  *
  * @param      \phpcouch\http\HttpRequest HTTP Request object
  *
  * @return     \phpcouch\http\HttpResponse  The response from the server
  *
  * @author     Simon Thulbourn <*****@*****.**>
  * @since      1.0.0
  */
 public function sendRequest(\phpcouch\http\HttpRequest $request)
 {
     $internalRequest = new \HttpRequest($request->getDestination(), self::$httpMethods[$request->getMethod()]);
     // additional headers
     foreach ($request->getHeaders() as $key => $values) {
         foreach ($values as $value) {
             $this->headers[$key] = $value;
         }
     }
     if (!isset($this->headers['Content-Type'])) {
         $this->headers['Content-Type'] = 'application/json';
     }
     if (null !== ($payload = $request->getContent())) {
         if (is_resource($payload)) {
             // This adapter has no real stream support as of now
             $payload = stream_get_contents($payload, -1, 0);
         }
         if ('PUT' == $request->getMethod()) {
             $internalRequest->setPutData($payload);
         } elseif ('POST' == $request->getMethod()) {
             $internalRequest->setBody($payload);
             $this->headers['Content-Length'] = strlen($payload);
         }
     }
     $internalRequest->addHeaders($this->headers);
     $message = new \HttpMessage($internalRequest->send());
     $response = new HttpResponse();
     $response->setStatusCode($message->getResponseCode());
     if (!isset($response)) {
         throw new TransportException('Could not read HTTP response status line');
     }
     foreach ($message->getHeaders() as $key => $value) {
         $response->setHeader($key, $value);
     }
     $response->setContent($message->getBody());
     if ($message->getResponseCode() >= 400) {
         if ($message->getResponseCode() % 500 < 100) {
             // a 5xx response
             throw new HttpServerErrorException($message->getResponseStatus(), $message->getResponseCode(), $response);
         } else {
             // a 4xx response
             throw new HttpClientErrorException($message->getResponseStatus(), $message->getResponseCode(), $response);
         }
     }
     return $response;
 }
Exemplo n.º 2
0
 /**
  * Perform the HTTP request.
  *
  * @param      \phpcouch\http\HttpRequest  The request to send
  *
  * @return     \phpcouch\http\HttpResponse  The response from the server
  *
  * @author     David Zülke <*****@*****.**>
  * @author     Simon Thulbourn <*****@*****.**>
  * @since      1.0.0
  */
 public function sendRequest(\phpcouch\http\HttpRequest $request)
 {
     $options = $this->options;
     $options['http']['method'] = $request->getMethod();
     if (null !== ($payload = $request->getContent())) {
         if (is_resource($payload)) {
             // This adapter has no real stream support as of now
             $payload = stream_get_contents($payload, -1, 0);
         }
         $options['http']['content'] = $payload;
         $options['http']['header'][] = 'Content-Length: ' . strlen($payload);
     }
     // additional headers
     foreach ($request->getHeaders() as $key => $values) {
         foreach ($values as $value) {
             $options['http']['header'][] = "{$key}: {$value}";
         }
     }
     // must do this as there is a bug in all current PHP versions causing an additional \r\n being appended to the last header (so there are two \r\n sequences before the request body starts) when it's an array
     // a string it is then, that fixes the problem
     $options['http']['header'] = implode("\r\n", $options['http']['header']);
     $ctx = stream_context_create($options);
     $fp = @fopen($request->getDestination(), 'r', false, $ctx);
     if ($fp === false) {
         $error = error_get_last();
         throw new TransportException($error['message']);
     }
     $meta = stream_get_meta_data($fp);
     // $meta['wrapper_data'] is an indexed array of the individual response header lines
     // when a redirect happens, we get all the response headers merged together
     // so we need to run in a loop and create a chain of responses until we reach the final, authoritative one
     // [0]=>
     // string(30) "HTTP/1.0 301 Moved Permanently"
     // [1]=>
     // string(39) "Server: CouchDB/0.9.0 (Erlang OTP/R13B)"
     // [2]=>
     // string(73) "Location: http://localhost:5984/test_suite_db%2Fwith_slashes/_design/test"
     // [3]=>
     // string(35) "Date: Sat, 11 Jul 2009 21:33:46 GMT"
     // [4]=>
     // string(17) "Content-Length: 0"
     // [5]=>
     // string(15) "HTTP/1.0 200 OK"
     // [6]=>
     // string(39) "Server: CouchDB/0.9.0 (Erlang OTP/R13B)"
     // [7]=>
     // string(19) "Etag: "1-573696572""
     // [8]=>
     // string(35) "Date: Sat, 11 Jul 2009 21:33:46 GMT"
     // [9]=>
     // string(30) "Content-Type: application/json"
     // [10]=>
     // string(18) "Content-Length: 96"
     // [11]=>
     // string(30) "Cache-Control: must-revalidate"
     foreach ($meta['wrapper_data'] as $headerLine) {
         if (preg_match('#^HTTP/1\\.[01]\\s+(\\d{3})\\s+(.+)$#', $headerLine, $matches)) {
             $statusCode = (int) $matches[1];
             $statusMessage = $matches[2];
             if (isset($response)) {
                 $response = new HttpResponse($response);
             } else {
                 $response = new HttpResponse();
             }
             $response->setStatusCode($statusCode);
             continue;
         }
         if (!isset($response)) {
             throw new TransportException('Could not read HTTP response status line');
         }
         $headerParts = explode(':', $headerLine, 2);
         if (count($headerParts) == 2) {
             $response->setHeader(trim($headerParts[0]), trim($headerParts[1]));
         }
     }
     $body = stream_get_contents($fp);
     $response->setContent($body);
     if ($statusCode >= 400) {
         if ($statusCode % 500 < 100) {
             // a 5xx response
             throw new HttpServerErrorException($statusMessage, $statusCode, $response);
         } else {
             // a 4xx response
             throw new HttpClientErrorException($statusMessage, $statusCode, $response);
         }
     } else {
         return $response;
     }
 }
Exemplo n.º 3
0
 /**
  * @param string       $message
  * @param int          $code
  * @param HttpResponse $response
  * @param \Exception   $previous
  */
 public function __construct($message, $code, \phpcouch\http\HttpResponse $response = null, \Exception $previous = null)
 {
     $message = $message . "\n" . $response->getContent();
     parent::__construct($message, $code, $previous);
     $this->response = $response;
 }
Exemplo n.º 4
0
 /**
  * Perform the HTTP request
  *
  * @param      \phpcouch\http\HttpRequest  HTTP request object
  *
  * @return     \phpcouch\http\HttpResponse The response from the server
  *
  * @throws     TransportException
  *
  * @author     Peter Limbach <*****@*****.**>
  */
 public function sendRequest(HttpRequest $request)
 {
     $options = $this->options;
     $content = $request->getContent();
     if ($content !== null) {
         if (is_resource($content)) {
             $stat = fstat($content);
             $length = $stat['size'];
         } else {
             $length = strlen($content);
         }
         $options['header'][] = 'Content-Length: ' . $length;
     }
     // additional headers
     foreach ($request->getHeaders() as $key => $values) {
         foreach ($values as $value) {
             $options['header'][] = "{$key}: {$value}";
         }
     }
     $curl = curl_init($request->getDestination());
     if (is_resource($content) && $request->getMethod() == HttpRequest::METHOD_PUT) {
         // cURL needs this in combination with CURLOPT_INFILE
         curl_setopt($curl, CURLOPT_PUT, true);
     } else {
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getMethod());
     }
     curl_setopt($curl, CURLOPT_HTTPHEADER, $options['header']);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
     if (is_resource($content)) {
         rewind($content);
         curl_setopt($curl, CURLOPT_INFILE, $content);
         curl_setopt($curl, CURLOPT_INFILESIZE, $length);
     } else {
         curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
     }
     curl_setopt($curl, CURLOPT_USERAGENT, $options['user_agent']);
     foreach ($options['curl'] as $cUrlOption => $value) {
         curl_setopt($curl, $cUrlOption, $value);
     }
     $body = curl_exec($curl);
     if ($body === false) {
         throw new TransportException(curl_error($curl));
     }
     $response = new HttpResponse();
     $response->setContent($body);
     $info = curl_getinfo($curl);
     $response->setContentType($info['content_type']);
     $response->setStatusCode($info['http_code']);
     curl_close($curl);
     if ($info['http_code'] >= 400) {
         if ($info['http_code'] % 500 < 100) {
             // a 5xx response
             throw new HttpServerErrorException($response->getStatusMessage(), $info['http_code'], $response);
         } else {
             // a 4xx response
             throw new HttpClientErrorException($response->getStatusMessage(), $info['http_code'], $response);
         }
     } else {
         return $response;
     }
 }