1<?php 2 3namespace OAuth\Common\Http\Client; 4 5use OAuth\Common\Http\Exception\TokenResponseException; 6use OAuth\Common\Http\Uri\UriInterface; 7 8/** 9 * Client implementation for streams/file_get_contents 10 */ 11class StreamClient extends AbstractClient 12{ 13 /** 14 * Any implementing HTTP providers should send a request to the provided endpoint with the parameters. 15 * They should return, in string form, the response body and throw an exception on error. 16 * 17 * @param UriInterface $endpoint 18 * @param mixed $requestBody 19 * @param array $extraHeaders 20 * @param string $method 21 * 22 * @return string 23 * 24 * @throws TokenResponseException 25 * @throws \InvalidArgumentException 26 */ 27 public function retrieveResponse( 28 UriInterface $endpoint, 29 $requestBody, 30 array $extraHeaders = array(), 31 $method = 'POST' 32 ) { 33 // Normalize method name 34 $method = strtoupper($method); 35 36 $this->normalizeHeaders($extraHeaders); 37 38 if ($method === 'GET' && !empty($requestBody)) { 39 throw new \InvalidArgumentException('No body expected for "GET" request.'); 40 } 41 42 if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) { 43 $extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded'; 44 } 45 46 $host = 'Host: '.$endpoint->getHost(); 47 // Append port to Host if it has been specified 48 if ($endpoint->hasExplicitPortSpecified()) { 49 $host .= ':'.$endpoint->getPort(); 50 } 51 52 $extraHeaders['Host'] = $host; 53 $extraHeaders['Connection'] = 'Connection: close'; 54 55 if (is_array($requestBody)) { 56 $requestBody = http_build_query($requestBody, '', '&'); 57 } 58 $extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody); 59 60 $context = $this->generateStreamContext($requestBody, $extraHeaders, $method); 61 62 $level = error_reporting(0); 63 $response = file_get_contents($endpoint->getAbsoluteUri(), false, $context); 64 error_reporting($level); 65 if (false === $response) { 66 $lastError = error_get_last(); 67 if (is_null($lastError)) { 68 throw new TokenResponseException('Failed to request resource.'); 69 } 70 throw new TokenResponseException($lastError['message']); 71 } 72 73 return $response; 74 } 75 76 private function generateStreamContext($body, $headers, $method) 77 { 78 return stream_context_create( 79 array( 80 'http' => array( 81 'method' => $method, 82 'header' => implode("\r\n", array_values($headers)), 83 'content' => $body, 84 'protocol_version' => '1.1', 85 'user_agent' => $this->userAgent, 86 'max_redirects' => $this->maxRedirects, 87 'timeout' => $this->timeout 88 ), 89 ) 90 ); 91 } 92} 93