[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/google/Google/IO/ -> Stream.php (source)

   1  <?php
   2  /*
   3   * Copyright 2013 Google Inc.
   4   *
   5   * Licensed under the Apache License, Version 2.0 (the "License");
   6   * you may not use this file except in compliance with the License.
   7   * You may obtain a copy of the License at
   8   *
   9   *     http://www.apache.org/licenses/LICENSE-2.0
  10   *
  11   * Unless required by applicable law or agreed to in writing, software
  12   * distributed under the License is distributed on an "AS IS" BASIS,
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14   * See the License for the specific language governing permissions and
  15   * limitations under the License.
  16   */
  17  
  18  /**
  19   * Http Streams based implementation of Google_IO.
  20   *
  21   * @author Stuart Langley <[email protected]>
  22   */
  23  
  24  require_once 'Google/IO/Abstract.php';
  25  
  26  class Google_IO_Stream extends Google_IO_Abstract
  27  {
  28    const TIMEOUT = "timeout";
  29    const ZLIB = "compress.zlib://";
  30    private $options = array();
  31    private $trappedErrorNumber;
  32    private $trappedErrorString;
  33  
  34    private static $DEFAULT_HTTP_CONTEXT = array(
  35      "follow_location" => 0,
  36      "ignore_errors" => 1,
  37    );
  38  
  39    private static $DEFAULT_SSL_CONTEXT = array(
  40      "verify_peer" => true,
  41    );
  42  
  43    /**
  44     * Execute an HTTP Request
  45     *
  46     * @param Google_HttpRequest $request the http request to be executed
  47     * @return Google_HttpRequest http request with the response http code,
  48     * response headers and response body filled in
  49     * @throws Google_IO_Exception on curl or IO error
  50     */
  51    public function executeRequest(Google_Http_Request $request)
  52    {
  53      $default_options = stream_context_get_options(stream_context_get_default());
  54  
  55      $requestHttpContext = array_key_exists('http', $default_options) ?
  56          $default_options['http'] : array();
  57  
  58      if ($request->getPostBody()) {
  59        $requestHttpContext["content"] = $request->getPostBody();
  60      }
  61  
  62      $requestHeaders = $request->getRequestHeaders();
  63      if ($requestHeaders && is_array($requestHeaders)) {
  64        $headers = "";
  65        foreach ($requestHeaders as $k => $v) {
  66          $headers .= "$k: $v\r\n";
  67        }
  68        $requestHttpContext["header"] = $headers;
  69      }
  70  
  71      $requestHttpContext["method"] = $request->getRequestMethod();
  72      $requestHttpContext["user_agent"] = $request->getUserAgent();
  73  
  74      $requestSslContext = array_key_exists('ssl', $default_options) ?
  75          $default_options['ssl'] : array();
  76  
  77      if (!array_key_exists("cafile", $requestSslContext)) {
  78        $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem';
  79      }
  80  
  81      $options = array(
  82          "http" => array_merge(
  83              self::$DEFAULT_HTTP_CONTEXT,
  84              $requestHttpContext
  85          ),
  86          "ssl" => array_merge(
  87              self::$DEFAULT_SSL_CONTEXT,
  88              $requestSslContext
  89          )
  90      );
  91  
  92      $context = stream_context_create($options);
  93  
  94      $url = $request->getUrl();
  95  
  96      if ($request->canGzip()) {
  97        $url = self::ZLIB . $url;
  98      }
  99  
 100      // We are trapping any thrown errors in this method only and
 101      // throwing an exception.
 102      $this->trappedErrorNumber = null;
 103      $this->trappedErrorString = null;
 104  
 105      // START - error trap.
 106      set_error_handler(array($this, 'trapError'));
 107      $fh = fopen($url, 'r', false, $context);
 108      restore_error_handler();
 109      // END - error trap.
 110  
 111      if ($this->trappedErrorNumber) {
 112        throw new Google_IO_Exception(
 113            sprintf(
 114                "HTTP Error: Unable to connect: '%s'",
 115                $this->trappedErrorString
 116            ),
 117            $this->trappedErrorNumber
 118        );
 119      }
 120  
 121      $response_data = false;
 122      $respHttpCode = self::UNKNOWN_CODE;
 123      if ($fh) {
 124        if (isset($this->options[self::TIMEOUT])) {
 125          stream_set_timeout($fh, $this->options[self::TIMEOUT]);
 126        }
 127  
 128        $response_data = stream_get_contents($fh);
 129        fclose($fh);
 130  
 131        $respHttpCode = $this->getHttpResponseCode($http_response_header);
 132      }
 133  
 134      if (false === $response_data) {
 135        throw new Google_IO_Exception(
 136            sprintf(
 137                "HTTP Error: Unable to connect: '%s'",
 138                $respHttpCode
 139            ),
 140            $respHttpCode
 141        );
 142      }
 143  
 144      $responseHeaders = $this->getHttpResponseHeaders($http_response_header);
 145  
 146      return array($response_data, $responseHeaders, $respHttpCode);
 147    }
 148  
 149    /**
 150     * Set options that update the transport implementation's behavior.
 151     * @param $options
 152     */
 153    public function setOptions($options)
 154    {
 155      $this->options = $options + $this->options;
 156    }
 157  
 158    /**
 159     * Method to handle errors, used for error handling around
 160     * stream connection methods.
 161     */
 162    public function trapError($errno, $errstr)
 163    {
 164      $this->trappedErrorNumber = $errno;
 165      $this->trappedErrorString = $errstr;
 166    }
 167  
 168    /**
 169     * Set the maximum request time in seconds.
 170     * @param $timeout in seconds
 171     */
 172    public function setTimeout($timeout)
 173    {
 174      $this->options[self::TIMEOUT] = $timeout;
 175    }
 176  
 177    /**
 178     * Get the maximum request time in seconds.
 179     * @return timeout in seconds
 180     */
 181    public function getTimeout()
 182    {
 183      return $this->options[self::TIMEOUT];
 184    }
 185  
 186    /**
 187     * Test for the presence of a cURL header processing bug
 188     *
 189     * {@inheritDoc}
 190     *
 191     * @return boolean
 192     */
 193    protected function needsQuirk()
 194    {
 195      return false;
 196    }
 197  
 198    protected function getHttpResponseCode($response_headers)
 199    {
 200      $header_count = count($response_headers);
 201  
 202      for ($i = 0; $i < $header_count; $i++) {
 203        $header = $response_headers[$i];
 204        if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) {
 205          $response = explode(' ', $header);
 206          return $response[1];
 207        }
 208      }
 209      return self::UNKNOWN_CODE;
 210    }
 211  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1