public static function assignHttpContext($context, RequestInterface $request, Options $options = null) { stream_context_set_option($context, 'http', 'method', $request->getMethod()); stream_context_set_option($context, 'http', 'protocol_version', $request->getProtocolVersion() ?: 1.1); // until chunked transfer encoding if fully implemented we remove the // header if ($request->hasHeader('Transfer-Encoding')) { $request->removeHeader('Transfer-Encoding'); } // set header $headers = implode(Http::$newLine, ResponseParser::buildHeaderFromMessage($request)); stream_context_set_option($context, 'http', 'header', $headers); // set body $body = $request->getBody(); if ($body !== null && !in_array($request->getMethod(), array('HEAD', 'GET'))) { stream_context_set_option($context, 'http', 'content', (string) $body); } if ($options !== null) { // set proxy $proxy = $options->getProxy(); if (!empty($proxy)) { stream_context_set_option($context, 'http', 'proxy', $proxy); } // set follow location stream_context_set_option($context, 'http', 'follow_location', (int) $options->getFollowLocation()); stream_context_set_option($context, 'http', 'max_redirects', $options->getMaxRedirects()); // set timeout $timeout = $options->getTimeout(); if (!empty($timeout)) { stream_context_set_option($context, 'http', 'timeout', $timeout); } } }
public function request(RequestInterface $request, Options $options) { $this->header = array(); $this->body = fopen('php://temp', 'r+'); $handle = curl_init($request->getUri()->toString()); curl_setopt($handle, CURLOPT_HEADER, false); curl_setopt($handle, CURLOPT_RETURNTRANSFER, false); curl_setopt($handle, CURLOPT_HEADERFUNCTION, array($this, 'header')); curl_setopt($handle, CURLOPT_WRITEFUNCTION, array($this, 'write')); curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $request->getMethod()); // set header $headers = ResponseParser::buildHeaderFromMessage($request); if (!empty($headers)) { if (!$request->hasHeader('Expect')) { $headers[] = 'Expect:'; } curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); } // set body $body = $request->getBody(); if ($body !== null && !in_array($request->getMethod(), array('HEAD', 'GET'))) { if ($request->getHeader('Transfer-Encoding') == 'chunked') { curl_setopt($handle, CURLOPT_UPLOAD, true); curl_setopt($handle, CURLOPT_READFUNCTION, function ($handle, $fd, $length) use($body) { return $body->read($length); }); } else { curl_setopt($handle, CURLOPT_POSTFIELDS, (string) $body); } } // set proxy $proxy = $options->getProxy(); if (!empty($proxy)) { curl_setopt($handle, CURLOPT_PROXY, $proxy); } // set follow location curl_setopt($handle, CURLOPT_FOLLOWLOCATION, $options->getFollowLocation() && $this->hasFollowLocation); curl_setopt($handle, CURLOPT_MAXREDIRS, $options->getMaxRedirects()); // set ssl if ($options->getSsl() !== false && ($options->getSsl() === true || strcasecmp($request->getUri()->getScheme(), 'https') === 0)) { $caPath = $options->getCaPath(); if (!empty($caPath)) { curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 2); if (is_file($caPath)) { curl_setopt($handle, CURLOPT_CAINFO, $caPath); } elseif (is_dir($caPath)) { curl_setopt($handle, CURLOPT_CAPATH, $caPath); } } else { curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0); } } // set timeout $timeout = $options->getTimeout(); if (!empty($timeout)) { curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); } // callback $callback = $options->getCallback(); if (!empty($callback)) { call_user_func_array($callback, array($handle, $request)); } curl_exec($handle); // if follow location is active modify the header since all headers from // each redirection are included if ($options->getFollowLocation() && $this->hasFollowLocation) { $positions = array(); foreach ($this->header as $key => $header) { if (substr($header, 0, 5) == 'HTTP/') { $positions[] = $key; } } if (count($positions) > 1) { $this->header = array_slice($this->header, end($positions) - 1); } } if (curl_errno($handle)) { throw new HandlerException('Curl error: ' . curl_error($handle)); } curl_close($handle); // build response rewind($this->body); $response = ResponseParser::buildResponseFromHeader($this->header); if ($request->getMethod() != 'HEAD') { $response->setBody(new TempStream($this->body)); } else { $response->setBody(new StringStream()); } return $response; }