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