Chris@0: nextHandler = $nextHandler; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param RequestInterface $request Chris@0: * @param array $options Chris@0: * Chris@0: * @return PromiseInterface Chris@0: */ Chris@0: public function __invoke(RequestInterface $request, array $options) Chris@0: { Chris@0: $fn = $this->nextHandler; Chris@0: Chris@0: // Don't do anything if the request has no body. Chris@0: if ($request->getBody()->getSize() === 0) { Chris@0: return $fn($request, $options); Chris@0: } Chris@0: Chris@0: $modify = []; Chris@0: Chris@0: // Add a default content-type if possible. Chris@0: if (!$request->hasHeader('Content-Type')) { Chris@0: if ($uri = $request->getBody()->getMetadata('uri')) { Chris@0: if ($type = Psr7\mimetype_from_filename($uri)) { Chris@0: $modify['set_headers']['Content-Type'] = $type; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: // Add a default content-length or transfer-encoding header. Chris@0: if (!$request->hasHeader('Content-Length') Chris@0: && !$request->hasHeader('Transfer-Encoding') Chris@0: ) { Chris@0: $size = $request->getBody()->getSize(); Chris@0: if ($size !== null) { Chris@0: $modify['set_headers']['Content-Length'] = $size; Chris@0: } else { Chris@0: $modify['set_headers']['Transfer-Encoding'] = 'chunked'; Chris@0: } Chris@0: } Chris@0: Chris@0: // Add the expect header if needed. Chris@0: $this->addExpectHeader($request, $options, $modify); Chris@0: Chris@0: return $fn(Psr7\modify_request($request, $modify), $options); Chris@0: } Chris@0: Chris@0: private function addExpectHeader( Chris@0: RequestInterface $request, Chris@0: array $options, Chris@0: array &$modify Chris@0: ) { Chris@0: // Determine if the Expect header should be used Chris@0: if ($request->hasHeader('Expect')) { Chris@0: return; Chris@0: } Chris@0: Chris@0: $expect = isset($options['expect']) ? $options['expect'] : null; Chris@0: Chris@0: // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 Chris@0: if ($expect === false || $request->getProtocolVersion() < 1.1) { Chris@0: return; Chris@0: } Chris@0: Chris@0: // The expect header is unconditionally enabled Chris@0: if ($expect === true) { Chris@0: $modify['set_headers']['Expect'] = '100-Continue'; Chris@0: return; Chris@0: } Chris@0: Chris@0: // By default, send the expect header when the payload is > 1mb Chris@0: if ($expect === null) { Chris@0: $expect = 1048576; Chris@0: } Chris@0: Chris@0: // Always add if the body cannot be rewound, the size cannot be Chris@0: // determined, or the size is greater than the cutoff threshold Chris@0: $body = $request->getBody(); Chris@0: $size = $body->getSize(); Chris@0: Chris@0: if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { Chris@0: $modify['set_headers']['Expect'] = '100-Continue'; Chris@0: } Chris@0: } Chris@0: }