Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws;
3
 
4
use GuzzleHttp\Psr7;
5
use Psr\Http\Message\RequestInterface;
6
 
7
/**
8
 * Used to compress request payloads if the service/operation support it.
9
 *
10
 * IMPORTANT: this middleware must be added after the "build" step.
11
 *
12
 * @internal
13
 */
14
class RequestCompressionMiddleware
15
{
16
    private $api;
17
    private $minimumCompressionSize;
18
    private $nextHandler;
19
    private $encodings;
20
    private $encoding;
21
    private $encodingMap = [
22
        'gzip' => 'gzencode'
23
    ];
24
 
25
    /**
26
     * Create a middleware wrapper function.
27
     *
28
     * @return callable
29
     */
30
    public static function wrap(array $config)
31
    {
32
        return function (callable $handler) use ($config) {
33
            return new self($handler, $config);
34
        };
35
    }
36
 
37
    public function __construct(callable $nextHandler, $config)
38
    {
39
        $this->minimumCompressionSize = $this->determineMinimumCompressionSize($config);
40
        $this->api = $config['api'];
41
        $this->nextHandler = $nextHandler;
42
    }
43
 
44
    public function __invoke(CommandInterface $command, RequestInterface $request)
45
    {
46
        if (isset($command['@request_min_compression_size_bytes'])
47
            && is_int($command['@request_min_compression_size_bytes'])
48
            && $this->isValidCompressionSize($command['@request_min_compression_size_bytes'])
49
        ) {
50
            $this->minimumCompressionSize = $command['@request_min_compression_size_bytes'];
51
        }
52
        $nextHandler = $this->nextHandler;
53
        $operation = $this->api->getOperation($command->getName());
54
        $requestBodySize = $request->getBody()->getSize();
55
        $compressionInfo = isset($operation['requestcompression'])
56
            ? $operation['requestcompression']
57
            : null;
58
 
59
        if (!$this->shouldCompressRequestBody(
60
            $compressionInfo,
61
            $command,
62
            $operation,
63
            $requestBodySize
64
        )) {
65
            return $nextHandler($command, $request);
66
        }
67
 
68
        $this->encodings = $compressionInfo['encodings'];
69
        $request = $this->compressRequestBody($request);
70
 
71
        return $nextHandler($command, $request);
72
    }
73
 
74
    private function compressRequestBody(
75
        RequestInterface $request
76
    ) {
77
        $fn = $this->determineEncoding();
78
        if (is_null($fn)) {
79
            return $request;
80
        }
81
 
82
        $body = $request->getBody()->getContents();
83
        $compressedBody = $fn($body);
84
 
85
        return $request->withBody(Psr7\Utils::streamFor($compressedBody))
86
            ->withHeader('content-encoding', $this->encoding);
87
    }
88
 
89
    private function determineEncoding()
90
    {
91
        foreach ($this->encodings as $encoding) {
92
            if (isset($this->encodingMap[$encoding])) {
93
                $this->encoding = $encoding;
94
                return $this->encodingMap[$encoding];
95
            }
96
        }
97
        return null;
98
    }
99
 
100
    private function shouldCompressRequestBody(
101
        $compressionInfo,
102
        $command,
103
        $operation,
104
        $requestBodySize
105
    ){
106
        if ($compressionInfo) {
107
            if (isset($command['@disable_request_compression'])
108
                && $command['@disable_request_compression'] === true
109
            ) {
110
                return false;
111
            } elseif ($this->hasStreamingTraitWithoutRequiresLength($command, $operation)
112
                || $requestBodySize >= $this->minimumCompressionSize
113
            ) {
114
                return true;
115
            }
116
        }
117
        return false;
118
    }
119
 
120
    private function hasStreamingTraitWithoutRequiresLength($command, $operation)
121
    {
122
        foreach ($operation->getInput()->getMembers() as $name => $member) {
123
            if (isset($command[$name])
124
                && !empty($member['streaming'])
125
                && empty($member['requiresLength'])
126
            ){
127
                return true;
128
            }
129
        }
130
        return false;
131
    }
132
 
133
    private function determineMinimumCompressionSize($config) {
134
        if (is_callable($config['request_min_compression_size_bytes'])) {
135
            $minCompressionSz = $config['request_min_compression_size_bytes']();
136
        } else {
137
            $minCompressionSz = $config['request_min_compression_size_bytes'];
138
        }
139
 
140
        if ($this->isValidCompressionSize($minCompressionSz)) {
141
            return $minCompressionSz;
142
        }
143
    }
144
 
145
    private function isValidCompressionSize($compressionSize)
146
    {
147
        if (is_numeric($compressionSize)
148
            && ($compressionSize >= 0 && $compressionSize <= 10485760)
149
        ) {
150
            return true;
151
        }
152
 
153
        throw new \InvalidArgumentException(
154
            'The minimum request compression size must be a '
155
            . 'non-negative integer value between 0 and 10485760 bytes, inclusive.'
156
        );
157
    }
158
}