ByteStream
6 days ago
Middleware
6 days ago
Transport
6 days ago
examples
6 days ago
LICENSE.md
6 days ago
README.md
6 days ago
class-client.php
6 days ago
class-clientstate.php
6 days ago
class-connection.php
6 days ago
class-crawler.php
6 days ago
class-httpclientexception.php
6 days ago
class-httperror.php
6 days ago
class-request.php
6 days ago
class-response.php
6 days ago
composer.json
6 days ago
class-request.php
147 lines
| 1 | <?php |
| 2 | |
| 3 | namespace WordPress\HttpClient; |
| 4 | |
| 5 | class Request { |
| 6 | |
| 7 | const STATE_CREATED = 'STATE_CREATED'; |
| 8 | const STATE_ENQUEUED = 'STATE_ENQUEUED'; |
| 9 | const STATE_WILL_ENABLE_CRYPTO = 'STATE_WILL_ENABLE_CRYPTO'; |
| 10 | const STATE_WILL_SEND_HEADERS = 'STATE_WILL_SEND_HEADERS'; |
| 11 | const STATE_WILL_SEND_BODY = 'STATE_WILL_SEND_BODY'; |
| 12 | const STATE_SENT = 'STATE_SENT'; |
| 13 | const STATE_RECEIVING_HEADERS = 'STATE_RECEIVING_HEADERS'; |
| 14 | const STATE_RECEIVING_BODY = 'STATE_RECEIVING_BODY'; |
| 15 | const STATE_RECEIVED = 'STATE_RECEIVED'; |
| 16 | const STATE_FAILED = 'STATE_FAILED'; |
| 17 | const STATE_FINISHED = 'STATE_FINISHED'; |
| 18 | |
| 19 | private static $last_id; |
| 20 | |
| 21 | public $id; |
| 22 | |
| 23 | public $state = self::STATE_CREATED; |
| 24 | |
| 25 | public $url; |
| 26 | public $is_ssl; |
| 27 | public $method; |
| 28 | public $headers; |
| 29 | public $http_version; |
| 30 | /** |
| 31 | * @var WP_Byte_Reader |
| 32 | */ |
| 33 | public $upload_body_stream; |
| 34 | public $redirected_from; |
| 35 | public $redirected_to; |
| 36 | |
| 37 | public $cache_key; |
| 38 | |
| 39 | /** |
| 40 | * @var HttpError |
| 41 | */ |
| 42 | public $error; |
| 43 | /** |
| 44 | * @var Response |
| 45 | */ |
| 46 | public $response; |
| 47 | |
| 48 | /** |
| 49 | * @param string $url |
| 50 | */ |
| 51 | public function __construct( string $url, $request_info = array() ) { |
| 52 | $request_info = array_merge( |
| 53 | array( |
| 54 | 'http_version' => '1.1', |
| 55 | 'method' => 'GET', |
| 56 | 'headers' => array(), |
| 57 | 'body_stream' => null, |
| 58 | 'redirected_from' => null, |
| 59 | ), |
| 60 | $request_info |
| 61 | ); |
| 62 | |
| 63 | $this->id = ++ self::$last_id; |
| 64 | $this->is_ssl = 0 === strpos( $url, 'https://' ); |
| 65 | |
| 66 | // Extract username/password from URL if present. |
| 67 | // @TODO: Use the WHATWG URL parser. |
| 68 | $url_parts = parse_url( $url ); |
| 69 | if ( ! empty( $url_parts['user'] ) ) { |
| 70 | $auth = $url_parts['user']; |
| 71 | if ( ! empty( $url_parts['pass'] ) ) { |
| 72 | $auth .= ':' . $url_parts['pass']; |
| 73 | } |
| 74 | // Add basic auth header. |
| 75 | $request_info['headers']['authorization'] = 'Basic ' . base64_encode( $auth ); |
| 76 | |
| 77 | // Remove credentials from URL. |
| 78 | $url = |
| 79 | $url_parts['scheme'] . '://' . |
| 80 | $url_parts['host'] . |
| 81 | ( ! empty( $url_parts['port'] ) ? ':' . $url_parts['port'] : '' ) . |
| 82 | ( ! empty( $url_parts['path'] ) ? $url_parts['path'] : '' ) . |
| 83 | ( ! empty( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ) . |
| 84 | ( ! empty( $url_parts['fragment'] ) ? '#' . $url_parts['fragment'] : '' ); |
| 85 | } |
| 86 | |
| 87 | $this->url = $url; |
| 88 | $this->method = $request_info['method']; |
| 89 | |
| 90 | $headers = array( |
| 91 | 'host' => isset( $url_parts['host'] ) ? $url_parts['host'] : '', |
| 92 | 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36', |
| 93 | 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', |
| 94 | 'accept-language' => 'en-US,en;q=0.9', |
| 95 | 'connection' => 'close', |
| 96 | ); |
| 97 | if ( $request_info['body_stream'] ) { |
| 98 | $length = $request_info['body_stream']->length(); |
| 99 | if ( null !== $length ) { |
| 100 | $headers['content-length'] = $length; |
| 101 | } else { |
| 102 | $headers['transfer-encoding'] = 'chunked'; |
| 103 | } |
| 104 | } |
| 105 | foreach ( $request_info['headers'] as $k => $v ) { |
| 106 | $headers[ $k ] = $v; |
| 107 | } |
| 108 | $this->headers = array_change_key_case( $headers, CASE_LOWER ); |
| 109 | $this->upload_body_stream = $request_info['body_stream']; |
| 110 | $this->http_version = $request_info['http_version']; |
| 111 | $this->redirected_from = $request_info['redirected_from']; |
| 112 | if ( $this->redirected_from ) { |
| 113 | $this->redirected_from->redirected_to = $this; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | public function __clone() { |
| 118 | $this->id = ++ self::$last_id; |
| 119 | } |
| 120 | |
| 121 | public function get_header( $name ) { |
| 122 | return $this->headers[ $name ] ?? null; |
| 123 | } |
| 124 | |
| 125 | public function latest_redirect() { |
| 126 | $request = $this; |
| 127 | while ( $request->redirected_to ) { |
| 128 | $request = $request->redirected_to; |
| 129 | } |
| 130 | |
| 131 | return $request; |
| 132 | } |
| 133 | |
| 134 | public function original_request() { |
| 135 | $request = $this; |
| 136 | while ( $request->redirected_from ) { |
| 137 | $request = $request->redirected_from; |
| 138 | } |
| 139 | |
| 140 | return $request; |
| 141 | } |
| 142 | |
| 143 | public function is_redirected() { |
| 144 | return null !== $this->redirected_to; |
| 145 | } |
| 146 | } |
| 147 |