Google_IO_Stream

The Google Adsense Dashboard Google IO Stream class.

Defined (1)

The class is defined in the following location(s).

/src/Google/IO/Stream.php  
  1. class Google_IO_Stream extends Google_IO_Abstract 
  2. const TIMEOUT = "timeout"; 
  3. const ZLIB = "compress.zlib://"; 
  4. private $options = array(); 
  5. private $trappedErrorNumber; 
  6. private $trappedErrorString; 
  7.  
  8. private static $DEFAULT_HTTP_CONTEXT = array( 
  9. "follow_location" => 0,  
  10. "ignore_errors" => 1,  
  11. ); 
  12.  
  13. private static $DEFAULT_SSL_CONTEXT = array( 
  14. "verify_peer" => true,  
  15. ); 
  16.  
  17. /** 
  18. * Execute an HTTP Request 
  19. * @param Google_HttpRequest $request the http request to be executed 
  20. * @return Google_HttpRequest http request with the response http code,  
  21. * response headers and response body filled in 
  22. * @throws Google_IO_Exception on curl or IO error 
  23. */ 
  24. public function executeRequest(Google_Http_Request $request) 
  25. $default_options = stream_context_get_options(stream_context_get_default()); 
  26.  
  27. $requestHttpContext = array_key_exists('http', $default_options) ? 
  28. $default_options['http'] : array(); 
  29.  
  30. if ($request->getPostBody()) { 
  31. $requestHttpContext["content"] = $request->getPostBody(); 
  32.  
  33. $requestHeaders = $request->getRequestHeaders(); 
  34. if ($requestHeaders && is_array($requestHeaders)) { 
  35. $headers = ""; 
  36. foreach ($requestHeaders as $k => $v) { 
  37. $headers .= "$k: $v\r\n"; 
  38. $requestHttpContext["header"] = $headers; 
  39.  
  40. $requestHttpContext["method"] = $request->getRequestMethod(); 
  41. $requestHttpContext["user_agent"] = $request->getUserAgent(); 
  42.  
  43. $requestSslContext = array_key_exists('ssl', $default_options) ? 
  44. $default_options['ssl'] : array(); 
  45.  
  46. if (!array_key_exists("cafile", $requestSslContext)) { 
  47. $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem'; 
  48.  
  49. $options = array( 
  50. "http" => array_merge( 
  51. self::$DEFAULT_HTTP_CONTEXT,  
  52. $requestHttpContext 
  53. ),  
  54. "ssl" => array_merge( 
  55. self::$DEFAULT_SSL_CONTEXT,  
  56. $requestSslContext 
  57. ); 
  58.  
  59. $context = stream_context_create($options); 
  60.  
  61. $url = $request->getUrl(); 
  62.  
  63. if ($request->canGzip()) { 
  64. $url = self::ZLIB . $url; 
  65.  
  66. $this->client->getLogger()->debug( 
  67. 'Stream request',  
  68. array( 
  69. 'url' => $url,  
  70. 'method' => $request->getRequestMethod(),  
  71. 'headers' => $requestHeaders,  
  72. 'body' => $request->getPostBody() 
  73. ); 
  74.  
  75. // We are trapping any thrown errors in this method only and 
  76. // throwing an exception. 
  77. $this->trappedErrorNumber = null; 
  78. $this->trappedErrorString = null; 
  79.  
  80. // START - error trap. 
  81. set_error_handler(array($this, 'trapError')); 
  82. $fh = fopen($url, 'r', false, $context); 
  83. restore_error_handler(); 
  84. // END - error trap. 
  85.  
  86. if ($this->trappedErrorNumber) { 
  87. $error = sprintf( 
  88. "HTTP Error: Unable to connect: '%s'",  
  89. $this->trappedErrorString 
  90. ); 
  91.  
  92. $this->client->getLogger()->error('Stream ' . $error); 
  93. throw new Google_IO_Exception($error, $this->trappedErrorNumber); 
  94.  
  95. $response_data = false; 
  96. $respHttpCode = self::UNKNOWN_CODE; 
  97. if ($fh) { 
  98. if (isset($this->options[self::TIMEOUT])) { 
  99. stream_set_timeout($fh, $this->options[self::TIMEOUT]); 
  100.  
  101. $response_data = stream_get_contents($fh); 
  102. fclose($fh); 
  103.  
  104. $respHttpCode = $this->getHttpResponseCode($http_response_header); 
  105.  
  106. if (false === $response_data) { 
  107. $error = sprintf( 
  108. "HTTP Error: Unable to connect: '%s'",  
  109. $respHttpCode 
  110. ); 
  111.  
  112. $this->client->getLogger()->error('Stream ' . $error); 
  113. throw new Google_IO_Exception($error, $respHttpCode); 
  114.  
  115. $responseHeaders = $this->getHttpResponseHeaders($http_response_header); 
  116.  
  117. $this->client->getLogger()->debug( 
  118. 'Stream response',  
  119. array( 
  120. 'code' => $respHttpCode,  
  121. 'headers' => $responseHeaders,  
  122. 'body' => $response_data,  
  123. ); 
  124.  
  125. return array($response_data, $responseHeaders, $respHttpCode); 
  126.  
  127. /** 
  128. * Set options that update the transport implementation's behavior. 
  129. * @param $options 
  130. */ 
  131. public function setOptions($options) 
  132. $this->options = $options + $this->options; 
  133.  
  134. /** 
  135. * Method to handle errors, used for error handling around 
  136. * stream connection methods. 
  137. */ 
  138. public function trapError($errno, $errstr) 
  139. $this->trappedErrorNumber = $errno; 
  140. $this->trappedErrorString = $errstr; 
  141.  
  142. /** 
  143. * Set the maximum request time in seconds. 
  144. * @param $timeout in seconds 
  145. */ 
  146. public function setTimeout($timeout) 
  147. $this->options[self::TIMEOUT] = $timeout; 
  148.  
  149. /** 
  150. * Get the maximum request time in seconds. 
  151. * @return timeout in seconds 
  152. */ 
  153. public function getTimeout() 
  154. return $this->options[self::TIMEOUT]; 
  155.  
  156. /** 
  157. * Test for the presence of a cURL header processing bug 
  158. * {@inheritDoc} 
  159. * @return boolean 
  160. */ 
  161. protected function needsQuirk() 
  162. return false; 
  163.  
  164. protected function getHttpResponseCode($response_headers) 
  165. $header_count = count($response_headers); 
  166.  
  167. for ($i = 0; $i < $header_count; $i++) { 
  168. $header = $response_headers[$i]; 
  169. if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) { 
  170. $response = explode(' ', $header); 
  171. return $response[1]; 
  172. return self::UNKNOWN_CODE;