123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- <?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';
- }
- }
- }
|