123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <?php
- /**
- * Stream driver performs external requests using php
- * sockets.
- *
- * This is the default driver for all external requests.
- *
- * @package KO7\Request
- *
- * @copyright (c) 2007-2016 Kohana Team
- * @copyright (c) since 2016 Koseven Team
- * @license https://koseven.dev/LICENSE
- *
- */
- class KO7_Request_Client_Stream extends Request_Client_External {
- /**
- * Sends the HTTP message [Request] to a remote server and processes
- * the response.
- *
- * @param Request $request request to send
- * @param Response $response response to send
- *
- * @throws Request_Exception
- *
- * @return Response
- */
- public function _send_message(Request $request, Response $response): Response
- {
- // Calculate stream mode
- $mode = ($request->method() === HTTP_Request::GET) ? 'r' : 'r+';
- // Process cookies
- if ($cookies = $request->cookie())
- {
- $request->headers('cookie', http_build_query($cookies, NULL, '; '));
- }
- // Get the message body
- $body = $request->body();
- // Set the content length and form-urlencoded
- if ($body)
- {
- $request->headers('content-length', (string)strlen($body));
- $request->headers('content-type', 'application/x-www-form-urlencoded');
- }
- [$protocol] = explode('/', $request->protocol());
- // Create the context
- $options = [
- strtolower($protocol) => [
- 'method' => $request->method(),
- 'header' => (string)$request->headers(),
- 'content' => $body
- ]
- ];
- // Create the context stream
- $context = stream_context_create($options);
- // Set options
- if (!empty($this->_options))
- {
- stream_context_set_option($context, $this->_options);
- }
- $uri = $request->uri();
- if ($query = $request->query())
- {
- $uri .= '?' . http_build_query($query, NULL, '&');
- }
- // Throws an Exception if you try to write smth. but requested stream is not write-able or unavailable
- try
- {
- //Suppress warning: failed to open stream: HTTP wrapper does not support writeable connections
- if (is_resource($context) && get_resource_type($context) === 'stream-context' && $mode === 'r+') {
- throw new Request_Exception('Failed to open stream: HTTP wrapper does not support writeable connections: '.$uri);
- }
- $stream = fopen($uri, $mode, FALSE, $context);
- }
- catch(Exception $e)
- {
- throw new Request_Exception($e->getMessage());
- }
- if (is_resource($stream)) {
- $meta_data = stream_get_meta_data($stream);
- // Get the HTTP response code
- $http_response = array_shift($meta_data['wrapper_data']);
- // Fetch respone protocol and status
- preg_match_all('/(\w+\/\d\.\d) (\d{3})/', $http_response, $matches);
- $protocol = $matches[1][0];
- $status = (int)$matches[2][0];
- // Get any existing response headers
- $response_header = $response->headers();
- // Process headers
- array_map([$response_header, 'parse_header_string'], [], $meta_data['wrapper_data']);
- // Build the response
- $response->status($status)->protocol($protocol)->body(stream_get_contents($stream));
- // Close the stream after use
- fclose($stream);
- return $response;
- } else {
- throw new Request_Exception('Request stream could not be opened: '.$request->method() .' '.$request->uri());
- }
- }
- }
|