e6d176b6156cd9816b2af04e34518e906f595e0d
[yaffs-website] / vendor / guzzlehttp / guzzle / src / PrepareBodyMiddleware.php
1 <?php
2 namespace GuzzleHttp;
3
4 use GuzzleHttp\Promise\PromiseInterface;
5 use GuzzleHttp\Psr7;
6 use Psr\Http\Message\RequestInterface;
7
8 /**
9  * Prepares requests that contain a body, adding the Content-Length,
10  * Content-Type, and Expect headers.
11  */
12 class PrepareBodyMiddleware
13 {
14     /** @var callable  */
15     private $nextHandler;
16
17     /** @var array */
18     private static $skipMethods = ['GET' => true, 'HEAD' => true];
19
20     /**
21      * @param callable $nextHandler Next handler to invoke.
22      */
23     public function __construct(callable $nextHandler)
24     {
25         $this->nextHandler = $nextHandler;
26     }
27
28     /**
29      * @param RequestInterface $request
30      * @param array            $options
31      *
32      * @return PromiseInterface
33      */
34     public function __invoke(RequestInterface $request, array $options)
35     {
36         $fn = $this->nextHandler;
37
38         // Don't do anything if the request has no body.
39         if (isset(self::$skipMethods[$request->getMethod()])
40             || $request->getBody()->getSize() === 0
41         ) {
42             return $fn($request, $options);
43         }
44
45         $modify = [];
46
47         // Add a default content-type if possible.
48         if (!$request->hasHeader('Content-Type')) {
49             if ($uri = $request->getBody()->getMetadata('uri')) {
50                 if ($type = Psr7\mimetype_from_filename($uri)) {
51                     $modify['set_headers']['Content-Type'] = $type;
52                 }
53             }
54         }
55
56         // Add a default content-length or transfer-encoding header.
57         if (!isset(self::$skipMethods[$request->getMethod()])
58             && !$request->hasHeader('Content-Length')
59             && !$request->hasHeader('Transfer-Encoding')
60         ) {
61             $size = $request->getBody()->getSize();
62             if ($size !== null) {
63                 $modify['set_headers']['Content-Length'] = $size;
64             } else {
65                 $modify['set_headers']['Transfer-Encoding'] = 'chunked';
66             }
67         }
68
69         // Add the expect header if needed.
70         $this->addExpectHeader($request, $options, $modify);
71
72         return $fn(Psr7\modify_request($request, $modify), $options);
73     }
74
75     private function addExpectHeader(
76         RequestInterface $request,
77         array $options,
78         array &$modify
79     ) {
80         // Determine if the Expect header should be used
81         if ($request->hasHeader('Expect')) {
82             return;
83         }
84
85         $expect = isset($options['expect']) ? $options['expect'] : null;
86
87         // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
88         if ($expect === false || $request->getProtocolVersion() < 1.1) {
89             return;
90         }
91
92         // The expect header is unconditionally enabled
93         if ($expect === true) {
94             $modify['set_headers']['Expect'] = '100-Continue';
95             return;
96         }
97
98         // By default, send the expect header when the payload is > 1mb
99         if ($expect === null) {
100             $expect = 1048576;
101         }
102
103         // Always add if the body cannot be rewound, the size cannot be
104         // determined, or the size is greater than the cutoff threshold
105         $body = $request->getBody();
106         $size = $body->getSize();
107
108         if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
109             $modify['set_headers']['Expect'] = '100-Continue';
110         }
111     }
112 }