113 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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';
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |