diff vendor/guzzlehttp/psr7/src/functions.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents 4c8ae668cc8c
children
line wrap: on
line diff
--- a/vendor/guzzlehttp/psr7/src/functions.php	Tue Jul 10 15:07:59 2018 +0100
+++ b/vendor/guzzlehttp/psr7/src/functions.php	Thu Feb 28 13:21:36 2019 +0000
@@ -69,10 +69,10 @@
  * - metadata: Array of custom metadata.
  * - size: Size of the stream.
  *
- * @param resource|string|null|int|float|bool|StreamInterface|callable $resource Entity body data
- * @param array                                                        $options  Additional options
+ * @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data
+ * @param array                                                                  $options  Additional options
  *
- * @return Stream
+ * @return StreamInterface
  * @throws \InvalidArgumentException if the $resource arg is not valid.
  */
 function stream_for($resource = '', array $options = [])
@@ -238,7 +238,7 @@
     }
 
     if ($request instanceof ServerRequestInterface) {
-        return new ServerRequest(
+        return (new ServerRequest(
             isset($changes['method']) ? $changes['method'] : $request->getMethod(),
             $uri,
             $headers,
@@ -247,7 +247,11 @@
                 ? $changes['version']
                 : $request->getProtocolVersion(),
             $request->getServerParams()
-        );
+        ))
+        ->withParsedBody($request->getParsedBody())
+        ->withQueryParams($request->getQueryParams())
+        ->withCookieParams($request->getCookieParams())
+        ->withUploadedFiles($request->getUploadedFiles());
     }
 
     return new Request(
@@ -431,7 +435,7 @@
  * @param StreamInterface $stream    Stream to read from
  * @param int             $maxLength Maximum buffer length
  *
- * @return string|bool
+ * @return string
  */
 function readline(StreamInterface $stream, $maxLength = null)
 {
@@ -495,7 +499,7 @@
     // between status-code and reason-phrase is required. But browsers accept
     // responses without space and reason as well.
     if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
-        throw new \InvalidArgumentException('Invalid response string');
+        throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
     }
     $parts = explode(' ', $data['start-line'], 3);
 
@@ -516,8 +520,8 @@
  * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
  * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
  *
- * @param string      $str         Query string to parse
- * @param bool|string $urlEncoding How the query string is encoded
+ * @param string   $str         Query string to parse
+ * @param int|bool $urlEncoding How the query string is encoded
  *
  * @return array
  */
@@ -533,9 +537,9 @@
         $decoder = function ($value) {
             return rawurldecode(str_replace('+', ' ', $value));
         };
-    } elseif ($urlEncoding == PHP_QUERY_RFC3986) {
+    } elseif ($urlEncoding === PHP_QUERY_RFC3986) {
         $decoder = 'rawurldecode';
-    } elseif ($urlEncoding == PHP_QUERY_RFC1738) {
+    } elseif ($urlEncoding === PHP_QUERY_RFC1738) {
         $decoder = 'urldecode';
     } else {
         $decoder = function ($str) { return $str; };
@@ -633,6 +637,7 @@
 function mimetype_from_extension($extension)
 {
     static $mimetypes = [
+        '3gp' => 'video/3gpp',
         '7z' => 'application/x-7z-compressed',
         'aac' => 'audio/x-aac',
         'ai' => 'application/postscript',
@@ -680,6 +685,7 @@
         'mid' => 'audio/midi',
         'midi' => 'audio/midi',
         'mov' => 'video/quicktime',
+        'mkv' => 'video/x-matroska',
         'mp3' => 'audio/mpeg',
         'mp4' => 'video/mp4',
         'mp4a' => 'audio/mp4',
@@ -758,29 +764,53 @@
         throw new \InvalidArgumentException('Invalid message');
     }
 
-    // Iterate over each line in the message, accounting for line endings
-    $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE);
-    $result = ['start-line' => array_shift($lines), 'headers' => [], 'body' => ''];
-    array_shift($lines);
+    $message = ltrim($message, "\r\n");
 
-    for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) {
-        $line = $lines[$i];
-        // If two line breaks were encountered, then this is the end of body
-        if (empty($line)) {
-            if ($i < $totalLines - 1) {
-                $result['body'] = implode('', array_slice($lines, $i + 2));
-            }
-            break;
-        }
-        if (strpos($line, ':')) {
-            $parts = explode(':', $line, 2);
-            $key = trim($parts[0]);
-            $value = isset($parts[1]) ? trim($parts[1]) : '';
-            $result['headers'][$key][] = $value;
-        }
+    $messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
+
+    if ($messageParts === false || count($messageParts) !== 2) {
+        throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
     }
 
-    return $result;
+    list($rawHeaders, $body) = $messageParts;
+    $rawHeaders .= "\r\n"; // Put back the delimiter we split previously
+    $headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
+
+    if ($headerParts === false || count($headerParts) !== 2) {
+        throw new \InvalidArgumentException('Invalid message: Missing status line');
+    }
+
+    list($startLine, $rawHeaders) = $headerParts;
+
+    if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
+        // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
+        $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
+    }
+
+    /** @var array[] $headerLines */
+    $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
+
+    // If these aren't the same, then one line didn't match and there's an invalid header.
+    if ($count !== substr_count($rawHeaders, "\n")) {
+        // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
+        if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
+            throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
+        }
+
+        throw new \InvalidArgumentException('Invalid header syntax');
+    }
+
+    $headers = [];
+
+    foreach ($headerLines as $headerLine) {
+        $headers[$headerLine[1]][] = $headerLine[2];
+    }
+
+    return [
+        'start-line' => $startLine,
+        'headers' => $headers,
+        'body' => $body,
+    ];
 }
 
 /**
@@ -809,6 +839,46 @@
     return $scheme . '://' . $host . '/' . ltrim($path, '/');
 }
 
+/**
+ * Get a short summary of the message body
+ *
+ * Will return `null` if the response is not printable.
+ *
+ * @param MessageInterface $message    The message to get the body summary
+ * @param int              $truncateAt The maximum allowed size of the summary
+ *
+ * @return null|string
+ */
+function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
+{
+    $body = $message->getBody();
+
+    if (!$body->isSeekable() || !$body->isReadable()) {
+        return null;
+    }
+
+    $size = $body->getSize();
+
+    if ($size === 0) {
+        return null;
+    }
+
+    $summary = $body->read($truncateAt);
+    $body->rewind();
+
+    if ($size > $truncateAt) {
+        $summary .= ' (truncated...)';
+    }
+
+    // Matches any printable character, including unicode characters:
+    // letters, marks, numbers, punctuation, spacing, and separators.
+    if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
+        return null;
+    }
+
+    return $summary;
+}
+
 /** @internal */
 function _caseless_remove($keys, array $data)
 {