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