PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.6.4
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.6.4
4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / vendor / guzzlehttp / psr7 / src / Message.php
surecart / vendor / guzzlehttp / psr7 / src Last commit date
Exception 1 year ago AppendStream.php 1 year ago BufferStream.php 1 year ago CachingStream.php 1 year ago DroppingStream.php 1 year ago FnStream.php 1 year ago Header.php 1 year ago HttpFactory.php 1 year ago InflateStream.php 1 year ago LazyOpenStream.php 1 year ago LimitStream.php 1 year ago Message.php 1 year ago MessageTrait.php 1 year ago MimeType.php 1 year ago MultipartStream.php 1 year ago NoSeekStream.php 1 year ago PumpStream.php 1 year ago Query.php 1 year ago Request.php 1 year ago Response.php 1 year ago Rfc7230.php 1 year ago ServerRequest.php 1 year ago Stream.php 1 year ago StreamDecoratorTrait.php 1 year ago StreamWrapper.php 1 year ago UploadedFile.php 1 year ago Uri.php 1 year ago UriComparator.php 1 year ago UriNormalizer.php 1 year ago UriResolver.php 1 year ago Utils.php 1 year ago
Message.php
247 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace SureCartVendors\GuzzleHttp\Psr7;
6
7 use SureCartVendors\Psr\Http\Message\MessageInterface;
8 use SureCartVendors\Psr\Http\Message\RequestInterface;
9 use SureCartVendors\Psr\Http\Message\ResponseInterface;
10
11 final class Message
12 {
13 /**
14 * Returns the string representation of an HTTP message.
15 *
16 * @param MessageInterface $message Message to convert to a string.
17 */
18 public static function toString(MessageInterface $message): string
19 {
20 if ($message instanceof RequestInterface) {
21 $msg = trim($message->getMethod().' '
22 .$message->getRequestTarget())
23 .' HTTP/'.$message->getProtocolVersion();
24 if (!$message->hasHeader('host')) {
25 $msg .= "\r\nHost: ".$message->getUri()->getHost();
26 }
27 } elseif ($message instanceof ResponseInterface) {
28 $msg = 'HTTP/'.$message->getProtocolVersion().' '
29 .$message->getStatusCode().' '
30 .$message->getReasonPhrase();
31 } else {
32 throw new \InvalidArgumentException('Unknown message type');
33 }
34
35 foreach ($message->getHeaders() as $name => $values) {
36 if (is_string($name) && strtolower($name) === 'set-cookie') {
37 foreach ($values as $value) {
38 $msg .= "\r\n{$name}: ".$value;
39 }
40 } else {
41 $msg .= "\r\n{$name}: ".implode(', ', $values);
42 }
43 }
44
45 return "{$msg}\r\n\r\n".$message->getBody();
46 }
47
48 /**
49 * Get a short summary of the message body.
50 *
51 * Will return `null` if the response is not printable.
52 *
53 * @param MessageInterface $message The message to get the body summary
54 * @param int $truncateAt The maximum allowed size of the summary
55 */
56 public static function bodySummary(MessageInterface $message, int $truncateAt = 120): ?string
57 {
58 $body = $message->getBody();
59
60 if (!$body->isSeekable() || !$body->isReadable()) {
61 return null;
62 }
63
64 $size = $body->getSize();
65
66 if ($size === 0) {
67 return null;
68 }
69
70 $body->rewind();
71 $summary = $body->read($truncateAt);
72 $body->rewind();
73
74 if ($size > $truncateAt) {
75 $summary .= ' (truncated...)';
76 }
77
78 // Matches any printable character, including unicode characters:
79 // letters, marks, numbers, punctuation, spacing, and separators.
80 if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary) !== 0) {
81 return null;
82 }
83
84 return $summary;
85 }
86
87 /**
88 * Attempts to rewind a message body and throws an exception on failure.
89 *
90 * The body of the message will only be rewound if a call to `tell()`
91 * returns a value other than `0`.
92 *
93 * @param MessageInterface $message Message to rewind
94 *
95 * @throws \RuntimeException
96 */
97 public static function rewindBody(MessageInterface $message): void
98 {
99 $body = $message->getBody();
100
101 if ($body->tell()) {
102 $body->rewind();
103 }
104 }
105
106 /**
107 * Parses an HTTP message into an associative array.
108 *
109 * The array contains the "start-line" key containing the start line of
110 * the message, "headers" key containing an associative array of header
111 * array values, and a "body" key containing the body of the message.
112 *
113 * @param string $message HTTP request or response to parse.
114 */
115 public static function parseMessage(string $message): array
116 {
117 if (!$message) {
118 throw new \InvalidArgumentException('Invalid message');
119 }
120
121 $message = ltrim($message, "\r\n");
122
123 $messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
124
125 if ($messageParts === false || count($messageParts) !== 2) {
126 throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
127 }
128
129 [$rawHeaders, $body] = $messageParts;
130 $rawHeaders .= "\r\n"; // Put back the delimiter we split previously
131 $headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
132
133 if ($headerParts === false || count($headerParts) !== 2) {
134 throw new \InvalidArgumentException('Invalid message: Missing status line');
135 }
136
137 [$startLine, $rawHeaders] = $headerParts;
138
139 if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
140 // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
141 $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
142 }
143
144 /** @var array[] $headerLines */
145 $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
146
147 // If these aren't the same, then one line didn't match and there's an invalid header.
148 if ($count !== substr_count($rawHeaders, "\n")) {
149 // Folding is deprecated, see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
150 if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
151 throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
152 }
153
154 throw new \InvalidArgumentException('Invalid header syntax');
155 }
156
157 $headers = [];
158
159 foreach ($headerLines as $headerLine) {
160 $headers[$headerLine[1]][] = $headerLine[2];
161 }
162
163 return [
164 'start-line' => $startLine,
165 'headers' => $headers,
166 'body' => $body,
167 ];
168 }
169
170 /**
171 * Constructs a URI for an HTTP request message.
172 *
173 * @param string $path Path from the start-line
174 * @param array $headers Array of headers (each value an array).
175 */
176 public static function parseRequestUri(string $path, array $headers): string
177 {
178 $hostKey = array_filter(array_keys($headers), function ($k) {
179 // Numeric array keys are converted to int by PHP.
180 $k = (string) $k;
181
182 return strtolower($k) === 'host';
183 });
184
185 // If no host is found, then a full URI cannot be constructed.
186 if (!$hostKey) {
187 return $path;
188 }
189
190 $host = $headers[reset($hostKey)][0];
191 $scheme = substr($host, -4) === ':443' ? 'https' : 'http';
192
193 return $scheme.'://'.$host.'/'.ltrim($path, '/');
194 }
195
196 /**
197 * Parses a request message string into a request object.
198 *
199 * @param string $message Request message string.
200 */
201 public static function parseRequest(string $message): RequestInterface
202 {
203 $data = self::parseMessage($message);
204 $matches = [];
205 if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
206 throw new \InvalidArgumentException('Invalid request string');
207 }
208 $parts = explode(' ', $data['start-line'], 3);
209 $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
210
211 $request = new Request(
212 $parts[0],
213 $matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1],
214 $data['headers'],
215 $data['body'],
216 $version
217 );
218
219 return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
220 }
221
222 /**
223 * Parses a response message string into a response object.
224 *
225 * @param string $message Response message string.
226 */
227 public static function parseResponse(string $message): ResponseInterface
228 {
229 $data = self::parseMessage($message);
230 // According to https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2
231 // the space between status-code and reason-phrase is required. But
232 // browsers accept responses without space and reason as well.
233 if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
234 throw new \InvalidArgumentException('Invalid response string: '.$data['start-line']);
235 }
236 $parts = explode(' ', $data['start-line'], 3);
237
238 return new Response(
239 (int) $parts[1],
240 $data['headers'],
241 $data['body'],
242 explode('/', $parts[0])[1],
243 $parts[2] ?? null
244 );
245 }
246 }
247