[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10 namespace Joomla\CMS\Http\Transport; 11 12 use Composer\CaBundle\CaBundle; 13 use Joomla\CMS\Factory; 14 use Joomla\CMS\Http\Response; 15 use Joomla\CMS\Http\TransportInterface; 16 use Joomla\Http\AbstractTransport; 17 use Joomla\Http\Exception\InvalidResponseCodeException; 18 use Joomla\Uri\Uri; 19 use Joomla\Uri\UriInterface; 20 use Laminas\Diactoros\Stream as StreamResponse; 21 22 // phpcs:disable PSR1.Files.SideEffects 23 \defined('JPATH_PLATFORM') or die; 24 // phpcs:enable PSR1.Files.SideEffects 25 26 /** 27 * HTTP transport class for using PHP streams. 28 * 29 * @since 1.7.3 30 */ 31 class StreamTransport extends AbstractTransport implements TransportInterface 32 { 33 /** 34 * Send a request to the server and return a Response object with the response. 35 * 36 * @param string $method The HTTP method for sending the request. 37 * @param UriInterface $uri The URI to the resource to request. 38 * @param mixed $data Either an associative array or a string to be sent with the request. 39 * @param array $headers An array of request headers to send with the request. 40 * @param integer $timeout Read timeout in seconds. 41 * @param string $userAgent The optional user agent string to send with the request. 42 * 43 * @return Response 44 * 45 * @since 1.7.3 46 * @throws \RuntimeException 47 */ 48 public function request($method, UriInterface $uri, $data = null, array $headers = [], $timeout = null, $userAgent = null) 49 { 50 // Create the stream context options array with the required method offset. 51 $options = array('method' => strtoupper($method)); 52 53 // If data exists let's encode it and make sure our Content-Type header is set. 54 if (isset($data)) { 55 // If the data is a scalar value simply add it to the stream context options. 56 if (is_scalar($data)) { 57 $options['content'] = $data; 58 } else { 59 // Otherwise we need to encode the value first. 60 $options['content'] = http_build_query($data); 61 } 62 63 if (!isset($headers['Content-Type'])) { 64 $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; 65 } 66 67 // Add the relevant headers. 68 $headers['Content-Length'] = \strlen($options['content']); 69 } 70 71 // If an explicit timeout is given user it. 72 if (isset($timeout)) { 73 $options['timeout'] = (int) $timeout; 74 } 75 76 // If an explicit user agent is given use it. 77 if (isset($userAgent)) { 78 $options['user_agent'] = $userAgent; 79 } 80 81 // Ignore HTTP errors so that we can capture them. 82 $options['ignore_errors'] = 1; 83 84 // Follow redirects. 85 $options['follow_location'] = (int) $this->getOption('follow_location', 1); 86 87 // Set any custom transport options 88 foreach ($this->getOption('transport.stream', array()) as $key => $value) { 89 $options[$key] = $value; 90 } 91 92 // Add the proxy configuration, if any. 93 $app = Factory::getApplication(); 94 95 if ($app->get('proxy_enable')) { 96 $options['proxy'] = $app->get('proxy_host') . ':' . $app->get('proxy_port'); 97 $options['request_fulluri'] = true; 98 99 // Put any required authorization into the headers array to be handled later 100 // @todo: do we need to support any auth type other than Basic? 101 if ($user = $app->get('proxy_user')) { 102 $auth = base64_encode($app->get('proxy_user') . ':' . $app->get('proxy_pass')); 103 104 $headers['Proxy-Authorization'] = 'Basic ' . $auth; 105 } 106 } 107 108 // Build the headers string for the request. 109 $headerEntries = array(); 110 111 if (isset($headers)) { 112 foreach ($headers as $key => $value) { 113 $headerEntries[] = $key . ': ' . $value; 114 } 115 116 // Add the headers string into the stream context options array. 117 $options['header'] = implode("\r\n", $headerEntries); 118 } 119 120 // Get the current context options. 121 $contextOptions = stream_context_get_options(stream_context_get_default()); 122 123 // Add our options to the current ones, if any. 124 $contextOptions['http'] = isset($contextOptions['http']) ? array_merge($contextOptions['http'], $options) : $options; 125 126 // Create the stream context for the request. 127 $context = stream_context_create( 128 array( 129 'http' => $options, 130 'ssl' => array( 131 'verify_peer' => true, 132 'cafile' => $this->getOption('stream.certpath', CaBundle::getBundledCaBundlePath()), 133 'verify_depth' => 5, 134 'verify_peer_name' => true, 135 ), 136 ) 137 ); 138 139 // Authentication, if needed 140 if ($uri instanceof Uri && $this->getOption('userauth') && $this->getOption('passwordauth')) { 141 $uri->setUser($this->getOption('userauth')); 142 $uri->setPass($this->getOption('passwordauth')); 143 } 144 145 // Capture PHP errors 146 $php_errormsg = ''; 147 $track_errors = ini_get('track_errors'); 148 ini_set('track_errors', true); 149 150 // Open the stream for reading. 151 $stream = @fopen((string) $uri, 'r', false, $context); 152 153 if (!$stream) { 154 if (!$php_errormsg) { 155 // Error but nothing from php? Create our own 156 $php_errormsg = sprintf('Could not connect to resource: %s', $uri); 157 } 158 159 // Restore error tracking to give control to the exception handler 160 ini_set('track_errors', $track_errors); 161 162 throw new \RuntimeException($php_errormsg); 163 } 164 165 // Restore error tracking to what it was before. 166 ini_set('track_errors', $track_errors); 167 168 // Get the metadata for the stream, including response headers. 169 $metadata = stream_get_meta_data($stream); 170 171 // Get the contents from the stream. 172 $content = stream_get_contents($stream); 173 174 // Close the stream. 175 fclose($stream); 176 177 if (isset($metadata['wrapper_data']['headers'])) { 178 $headers = $metadata['wrapper_data']['headers']; 179 } elseif (isset($metadata['wrapper_data'])) { 180 $headers = $metadata['wrapper_data']; 181 } else { 182 $headers = array(); 183 } 184 185 return $this->getResponse($headers, $content); 186 } 187 188 /** 189 * Method to get a response object from a server response. 190 * 191 * @param array $headers The response headers as an array. 192 * @param string $body The response body as a string. 193 * 194 * @return Response 195 * 196 * @since 1.7.3 197 * @throws InvalidResponseCodeException 198 */ 199 protected function getResponse(array $headers, $body) 200 { 201 // Get the response code from the first offset of the response headers. 202 preg_match('/[0-9]{3}/', array_shift($headers), $matches); 203 $code = $matches[0]; 204 205 if (!is_numeric($code)) { 206 // No valid response code was detected. 207 throw new InvalidResponseCodeException('No HTTP response code found.'); 208 } 209 210 $statusCode = (int) $code; 211 $verifiedHeaders = $this->processHeaders($headers); 212 213 $streamInterface = new StreamResponse('php://memory', 'rw'); 214 $streamInterface->write($body); 215 216 return new Response($streamInterface, $statusCode, $verifiedHeaders); 217 } 218 219 /** 220 * Method to check if http transport stream available for use 221 * 222 * @return boolean true if available else false 223 * 224 * @since 3.0.0 225 */ 226 public static function isSupported() 227 { 228 return \function_exists('fopen') && \is_callable('fopen') && ini_get('allow_url_fopen'); 229 } 230 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |