예제 #1
0
파일: Response.php 프로젝트: kaiwa/http
 /**
  * Class init.
  *
  * @param string $body
  * @param int    $status
  * @param array  $headers
  */
 public function __construct($body = 'php://memory', $status = 200, array $headers = array())
 {
     if (!$body instanceof StreamInterface) {
         $body = new Stream($body, Stream::MODE_READ_WRITE_RESET);
     }
     foreach ($headers as $name => $value) {
         $value = HeaderHelper::allToArray($value);
         if (!HeaderHelper::arrayOnlyContainsString($value)) {
             throw new \InvalidArgumentException('Header values should ony have string.');
         }
         if (!HeaderHelper::isValidName($name)) {
             throw new \InvalidArgumentException('Invalid header name');
         }
         $normalized = strtolower($name);
         $this->headerNames[$normalized] = $name;
         $this->headers[$name] = $value;
     }
     $this->stream = $body;
     $this->statusCode = $status;
 }
예제 #2
0
 /**
  * Class init.
  *
  * @param string|UriInterface    $uri
  * @param string                 $method
  * @param string|StreamInterface $body
  * @param array                  $headers
  */
 public function __construct($uri = null, $method = null, $body = 'php://memory', $headers = array())
 {
     if (!$body instanceof StreamInterface) {
         $body = new Stream($body, Stream::MODE_READ_WRITE_RESET);
     }
     if (!$uri instanceof UriInterface) {
         $uri = new PsrUri((string) $uri);
     }
     foreach ($headers as $name => $value) {
         $value = HeaderHelper::allToArray($value);
         if (!HeaderHelper::arrayOnlyContainsString($value)) {
             throw new \InvalidArgumentException('Header values should ony have string.');
         }
         if (!HeaderHelper::isValidName($name)) {
             throw new \InvalidArgumentException('Invalid header name');
         }
         $normalized = strtolower($name);
         $this->headerNames[$normalized] = $name;
         $this->headers[$name] = $value;
     }
     $this->stream = $body;
     $this->method = $this->validateMethod($method);
     $this->uri = $uri;
 }
예제 #3
0
 /**
  * Send a request to the server and return a Response object with the response.
  *
  * @param   RequestInterface  $request  The request object to store request params.
  *
  * @return  ResponseInterface
  *
  * @since    2.1
  */
 protected function doRequest(RequestInterface $request)
 {
     // Setup the cURL handle.
     $ch = curl_init();
     // Set the request method.
     $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod();
     // Don't wait for body when $method is HEAD
     $options[CURLOPT_NOBODY] = $request->getMethod() === 'HEAD';
     // Initialize the certificate store
     $options[CURLOPT_CAINFO] = $this->getOption('certpath', __DIR__ . '/cacert.pem');
     // Set HTTP Version
     switch ($request->getProtocolVersion()) {
         case '1.0':
             $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
             break;
         case '1.1':
             $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
             break;
         case '2.0':
             if (defined('CURL_HTTP_VERSION_2_0')) {
                 $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
             }
     }
     // If data exists let's encode it and make sure our Content-type header is set.
     $data = (string) $request->getBody();
     if (isset($data)) {
         // If the data is a scalar value simply add it to the cURL post fields.
         if (is_scalar($data) || strpos($request->getHeaderLine('Content-Type'), 'multipart/form-data') === 0) {
             $options[CURLOPT_POSTFIELDS] = $data;
         } else {
             $options[CURLOPT_POSTFIELDS] = http_build_query($data);
         }
         if (!$request->getHeaderLine('Content-Type')) {
             $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
         }
         // Add the relevant headers.
         if (is_scalar($options[CURLOPT_POSTFIELDS])) {
             $request = $request->withHeader('Content-Length', strlen($options[CURLOPT_POSTFIELDS]));
         }
     }
     // Build the headers string for the request.
     if ($headers = $request->getHeaders()) {
         // Add the headers string into the stream context options array.
         $options[CURLOPT_HTTPHEADER] = HeaderHelper::toHeaderLine($headers);
     }
     // If an explicit timeout is given user it.
     if ($timeout = $this->getOption('timeout')) {
         $options[CURLOPT_TIMEOUT] = (int) $timeout;
         $options[CURLOPT_CONNECTTIMEOUT] = (int) $timeout;
     }
     // If an explicit user agent is given use it.
     if ($userAgent = $this->getOption('userAgent')) {
         $options[CURLOPT_USERAGENT] = $userAgent;
     }
     // Set the request URL.
     $options[CURLOPT_URL] = (string) $request->getRequestTarget();
     // We want our headers. :-)
     $options[CURLOPT_HEADER] = true;
     // Return it... echoing it would be tacky.
     $options[CURLOPT_RETURNTRANSFER] = true;
     // Override the Expect header to prevent cURL from confusing itself in its own stupidity.
     // Link: http://the-stickman.com/web-development/php-and-curl-disabling-100-continue-header/
     $options[CURLOPT_HTTPHEADER][] = 'Expect:';
     /*
      * Follow redirects if server config allows
      * @deprecated  safe_mode is removed in PHP 5.4, check will be dropped when PHP 5.3 support is dropped
      */
     if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
         $options[CURLOPT_FOLLOWLOCATION] = (bool) isset($this->options['follow_location']) ? $this->options['follow_location'] : true;
     }
     // Set any custom transport options
     if ($this->getOption('options')) {
         foreach ((array) $this->getOption('options') as $key => $value) {
             $options[$key] = $value;
         }
     }
     // Set the cURL options.
     curl_setopt_array($ch, $options);
     // Execute the request and close the connection.
     $content = curl_exec($ch);
     if (!$this->getOption('allow_empty_result', false) && !trim($content)) {
         $message = curl_error($ch);
         // Error but nothing from cURL? Create our own
         $message = $message ?: 'No HTTP response received';
         throw new \RuntimeException($message);
     }
     // Get the request information.
     $info = curl_getinfo($ch);
     // Close the connection.
     curl_close($ch);
     return $this->getResponse($content, $info);
 }
예제 #4
0
 /**
  * Send a request to the server and return a Response object with the response.
  *
  * @param   RequestInterface  $request  The request object to store request params.
  *
  * @return  ResponseInterface
  *
  * @since   2.1
  */
 protected function doRequest(RequestInterface $request)
 {
     // Create the stream context options array with the required method offset.
     $options = array('method' => $request->getMethod());
     // Set HTTP Version
     $options['protocol_version'] = $request->getProtocolVersion();
     // If data exists let's encode it and make sure our Content-Type header is set.
     $data = (string) $request->getBody();
     if (isset($data)) {
         // If the data is a scalar value simply add it to the stream context options.
         if (is_scalar($data)) {
             $options['content'] = $data;
         } else {
             $options['content'] = http_build_query($data);
         }
         if (!$request->getHeader('Content-Type')) {
             $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
         }
         // Add the relevant headers.
         $request = $request->withHeader('Content-Length', strlen($options['content']));
     }
     // Speed up stream get URL
     // @see http://stackoverflow.com/questions/3629504/php-file-get-contents-very-slow-when-using-full-url
     // @see http://stackoverflow.com/questions/13679976/how-to-speed-up-file-get-contents
     $request = $request->withHeader('Connection', 'Close');
     // Build the headers string for the request.
     if ($headers = $request->getHeaders()) {
         // Add the headers string into the stream context options array.
         $options['header'] = HeaderHelper::toHeaderLine($headers, true);
     }
     // If an explicit timeout is given user it.
     if ($this->getOption('timeout')) {
         $options['timeout'] = (int) $this->getOption('timeout');
     }
     // If an explicit user agent is given use it.
     if ($this->getOption('userAgent')) {
         $options['user_agent'] = $this->getOption('userAgent');
     }
     // Ignore HTTP errors so that we can capture them.
     $options['ignore_errors'] = 1;
     // Follow redirects.
     $options['follow_location'] = (int) $this->getOption('follow_location', 1);
     foreach ((array) $this->getOption('options') as $key => $value) {
         $options[$key] = $value;
     }
     // Create the stream context for the request.
     $context = stream_context_create(array('http' => $options));
     // Capture PHP errors
     $php_errormsg = '';
     $track_errors = ini_get('track_errors');
     ini_set('track_errors', true);
     $connection = @fopen($request->getRequestTarget(), Stream::MODE_READ_ONLY_FROM_BEGIN, false, $context);
     if (!$connection) {
         if (!$php_errormsg) {
             // Error but nothing from php? Create our own
             $php_errormsg = sprintf('Could not connect to resource: %s', $request->getRequestTarget());
         }
         // Restore error tracking to give control to the exception handler
         ini_set('track_errors', $track_errors);
         throw new \RuntimeException($php_errormsg);
     }
     $stream = new Stream($connection);
     if ($dest = $this->getOption('target_file')) {
         $content = '';
         StreamHelper::copyTo($stream, $dest);
     } else {
         $content = $stream->getContents();
     }
     $metadata = $stream->getMetadata();
     $stream->close();
     if (isset($metadata['wrapper_data']['headers'])) {
         $headers = $metadata['wrapper_data']['headers'];
     } elseif (isset($metadata['wrapper_data'])) {
         $headers = $metadata['wrapper_data'];
     } else {
         $headers = array();
     }
     return $this->getResponse($headers, $content);
 }
예제 #5
0
 /**
  * Return an instance with the specified header appended with the given value.
  *
  * Existing values for the specified header will be maintained. The new
  * value(s) will be appended to the existing list. If the header did not
  * exist previously, it will be added.
  *
  * This method MUST be implemented in such a way as to retain the
  * immutability of the message, and MUST return an instance that has the
  * new header and/or value.
  *
  * @param string  $name  Case-insensitive header field name to add.
  * @param mixed   $value Header value(s).
  *
  * @return static
  * @throws \InvalidArgumentException for invalid header names or values.
  */
 public function withAddedHeader($name, $value)
 {
     $value = HeaderHelper::allToArray($value);
     if (!HeaderHelper::arrayOnlyContainsString($value)) {
         throw new \InvalidArgumentException('Header values should ony have string.');
     }
     if (!HeaderHelper::isValidName($name)) {
         throw new \InvalidArgumentException('Invalid header name');
     }
     $new = clone $this;
     if (!$this->hasHeader($name)) {
         $new = $new->createHeader($name);
     }
     $name = $new->getHeaderName($name);
     $new->headers[$name] = array_merge($new->headers[$name], $value);
     return $new;
 }