1<?php 2namespace GuzzleHttp\Handler; 3 4use GuzzleHttp\Psr7\Response; 5use Psr\Http\Message\RequestInterface; 6use Psr\Http\Message\ResponseInterface; 7use Psr\Http\Message\StreamInterface; 8 9/** 10 * Represents a cURL easy handle and the data it populates. 11 * 12 * @internal 13 */ 14final class EasyHandle 15{ 16 /** @var resource cURL resource */ 17 public $handle; 18 19 /** @var StreamInterface Where data is being written */ 20 public $sink; 21 22 /** @var array Received HTTP headers so far */ 23 public $headers = []; 24 25 /** @var ResponseInterface Received response (if any) */ 26 public $response; 27 28 /** @var RequestInterface Request being sent */ 29 public $request; 30 31 /** @var array Request options */ 32 public $options = []; 33 34 /** @var int cURL error number (if any) */ 35 public $errno = 0; 36 37 /** @var \Exception Exception during on_headers (if any) */ 38 public $onHeadersException; 39 40 /** 41 * Attach a response to the easy handle based on the received headers. 42 * 43 * @throws \RuntimeException if no headers have been received. 44 */ 45 public function createResponse() 46 { 47 if (empty($this->headers)) { 48 throw new \RuntimeException('No headers have been received'); 49 } 50 51 // HTTP-version SP status-code SP reason-phrase 52 $startLine = explode(' ', array_shift($this->headers), 3); 53 $headers = \GuzzleHttp\headers_from_lines($this->headers); 54 $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); 55 56 if (!empty($this->options['decode_content']) 57 && isset($normalizedKeys['content-encoding']) 58 ) { 59 $headers['x-encoded-content-encoding'] 60 = $headers[$normalizedKeys['content-encoding']]; 61 unset($headers[$normalizedKeys['content-encoding']]); 62 if (isset($normalizedKeys['content-length'])) { 63 $headers['x-encoded-content-length'] 64 = $headers[$normalizedKeys['content-length']]; 65 66 $bodyLength = (int) $this->sink->getSize(); 67 if ($bodyLength) { 68 $headers[$normalizedKeys['content-length']] = $bodyLength; 69 } else { 70 unset($headers[$normalizedKeys['content-length']]); 71 } 72 } 73 } 74 75 // Attach a response to the easy handle with the parsed headers. 76 $this->response = new Response( 77 $startLine[1], 78 $headers, 79 $this->sink, 80 substr($startLine[0], 5), 81 isset($startLine[2]) ? (string) $startLine[2] : null 82 ); 83 } 84 85 public function __get($name) 86 { 87 $msg = $name === 'handle' 88 ? 'The EasyHandle has been released' 89 : 'Invalid property: ' . $name; 90 throw new \BadMethodCallException($msg); 91 } 92} 93