Source for file stream.php

Documentation is available at stream.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  HTTP
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. /**
  13.  * HTTP transport class for using PHP streams.
  14.  *
  15.  * @package     Joomla.Platform
  16.  * @subpackage  HTTP
  17.  * @since       11.3
  18.  */
  19. class JHttpTransportStream implements JHttpTransport
  20. {
  21.     /**
  22.      * @var    JRegistry  The client options.
  23.      * @since  11.3
  24.      */
  25.     protected $options;
  26.  
  27.     /**
  28.      * Constructor.
  29.      *
  30.      * @param   JRegistry  $options  Client options object.
  31.      *
  32.      * @since   11.3
  33.      * @throws  RuntimeException
  34.      */
  35.     public function __construct(JRegistry $options)
  36.     {
  37.         // Verify that fopen() is available.
  38.         if (!self::isSupported())
  39.         {
  40.             throw new RuntimeException('Cannot use a stream transport when fopen() is not available.');
  41.         }
  42.  
  43.         // Verify that URLs can be used with fopen();
  44.         if (!ini_get('allow_url_fopen'))
  45.         {
  46.             throw new RuntimeException('Cannot use a stream transport when "allow_url_fopen" is disabled.');
  47.         }
  48.  
  49.         $this->options = $options;
  50.     }
  51.  
  52.     /**
  53.      * Send a request to the server and return a JHttpResponse object with the response.
  54.      *
  55.      * @param   string   $method     The HTTP method for sending the request.
  56.      * @param   JUri     $uri        The URI to the resource to request.
  57.      * @param   mixed    $data       Either an associative array or a string to be sent with the request.
  58.      * @param   array    $headers    An array of request headers to send with the request.
  59.      * @param   integer  $timeout    Read timeout in seconds.
  60.      * @param   string   $userAgent  The optional user agent string to send with the request.
  61.      *
  62.      * @return  JHttpResponse 
  63.      *
  64.      * @since   11.3
  65.      * @throws  RuntimeException
  66.      */
  67.     public function request($methodJUri $uri$data nullarray $headers null$timeout null$userAgent null)
  68.     {
  69.         // Create the stream context options array with the required method offset.
  70.         $options array('method' => strtoupper($method));
  71.  
  72.         // If data exists let's encode it and make sure our Content-Type header is set.
  73.         if (isset($data))
  74.         {
  75.             // If the data is a scalar value simply add it to the stream context options.
  76.             if (is_scalar($data))
  77.             {
  78.                 $options['content'$data;
  79.             }
  80.             // Otherwise we need to encode the value first.
  81.             else
  82.             {
  83.                 $options['content'http_build_query($data);
  84.             }
  85.  
  86.             if (!isset($headers['Content-Type']))
  87.             {
  88.                 $headers['Content-Type''application/x-www-form-urlencoded; charset=utf-8';
  89.             }
  90.  
  91.             // Add the relevant headers.
  92.             $headers['Content-Length'strlen($options['content']);
  93.         }
  94.  
  95.         // Build the headers string for the request.
  96.         $headerString null;
  97.  
  98.         if (isset($headers))
  99.         {
  100.             foreach ($headers as $key => $value)
  101.             {
  102.                 $headerString .= $key ': ' $value "\r\n";
  103.             }
  104.  
  105.             // Add the headers string into the stream context options array.
  106.             $options['header'trim($headerString"\r\n");
  107.         }
  108.  
  109.         // If an explicit timeout is given user it.
  110.         if (isset($timeout))
  111.         {
  112.             $options['timeout'= (int) $timeout;
  113.         }
  114.  
  115.         // If an explicit user agent is given use it.
  116.         if (isset($userAgent))
  117.         {
  118.             $options['user_agent'$userAgent;
  119.         }
  120.  
  121.         // Ignore HTTP errors so that we can capture them.
  122.         $options['ignore_errors'1;
  123.  
  124.         // Follow redirects.
  125.         $options['follow_location'= (int) $this->options->get('follow_location'1);
  126.  
  127.         // Create the stream context for the request.
  128.         $context stream_context_create(array('http' => $options));
  129.  
  130.         // Capture PHP errors
  131.         $php_errormsg '';
  132.         $track_errors ini_get('track_errors');
  133.         ini_set('track_errors'true);
  134.  
  135.         // Open the stream for reading.
  136.         $stream @fopen((string) $uri'r'false$context);
  137.  
  138.         if (!$stream)
  139.         {
  140.             if (!$php_errormsg)
  141.             {
  142.                 // Error but nothing from php? Create our own
  143.                 $php_errormsg sprintf('Could not connect to resource: %s'$uri$err$errno);
  144.             }
  145.  
  146.             // Restore error tracking to give control to the exception handler
  147.             ini_set('track_errors'$track_errors);
  148.  
  149.             throw new RuntimeException($php_errormsg);
  150.         }
  151.  
  152.         // Restore error tracking to what it was before.
  153.         ini_set('track_errors'$track_errors);
  154.  
  155.         // Get the metadata for the stream, including response headers.
  156.         $metadata stream_get_meta_data($stream);
  157.  
  158.         // Get the contents from the stream.
  159.         $content stream_get_contents($stream);
  160.  
  161.         // Close the stream.
  162.         fclose($stream);
  163.  
  164.         if (isset($metadata['wrapper_data']['headers']))
  165.         {
  166.             $headers $metadata['wrapper_data']['headers'];
  167.         }
  168.         elseif (isset($metadata['wrapper_data']))
  169.         {
  170.             $headers $metadata['wrapper_data'];
  171.         }
  172.         else
  173.         {
  174.             $headers array();
  175.         }
  176.  
  177.         return $this->getResponse($headers$content);
  178.  
  179.     }
  180.  
  181.     /**
  182.      * Method to get a response object from a server response.
  183.      *
  184.      * @param   array   $headers  The response headers as an array.
  185.      * @param   string  $body     The response body as a string.
  186.      *
  187.      * @return  JHttpResponse 
  188.      *
  189.      * @since   11.3
  190.      * @throws  UnexpectedValueException
  191.      */
  192.     protected function getResponse(array $headers$body)
  193.     {
  194.         // Create the response object.
  195.         $return new JHttpResponse;
  196.  
  197.         // Set the body for the response.
  198.         $return->body $body;
  199.  
  200.         // Get the response code from the first offset of the response headers.
  201.         preg_match('/[0-9]{3}/'array_shift($headers)$matches);
  202.         $code $matches[0];
  203.  
  204.         if (is_numeric($code))
  205.         {
  206.             $return->code = (int) $code;
  207.         }
  208.  
  209.         // No valid response code was detected.
  210.         else
  211.         {
  212.             throw new UnexpectedValueException('No HTTP response code found.');
  213.         }
  214.  
  215.         // Add the response headers to the response object.
  216.         foreach ($headers as $header)
  217.         {
  218.             $pos strpos($header':');
  219.             $return->headers[trim(substr($header0$pos))trim(substr($header($pos 1)));
  220.         }
  221.  
  222.         return $return;
  223.     }
  224.  
  225.     /**
  226.      * Method to check if http transport stream available for use
  227.      *
  228.      * @return bool true if available else false
  229.      *
  230.      * @since   12.1
  231.      */
  232.     public static function isSupported()
  233.     {
  234.         return function_exists('fopen'&& is_callable('fopen');
  235.     }
  236. }

Documentation generated on Tue, 19 Nov 2013 15:14:30 +0100 by phpDocumentor 1.4.3