Completed
Push — master ( 8d12ff...458df2 )
by Guillaume
02:56
created

PrepareBodyMiddleware::__invoke()   D

Complexity

Conditions 10
Paths 13

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 20
nc 13
nop 2
dl 0
loc 40
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
}
113