public function send(RequestInterface $request, MessageFactory $messageFactory)
{
$uri = $request->getUri();
// URIs are required to be absolute for the HttpClient to work
if ($uri->getScheme() === '' || $uri->getHost() === '') {
return Promise\reject(new \InvalidArgumentException('Sending request requires absolute URI with scheme and host'));
}
$body = $request->getBody();
// automatically assign a Content-Length header if the body size is known
if ($body->getSize() !== null && $body->getSize() !== 0 && $request->hasHeader('Content-Length') !== null) {
$request = $request->withHeader('Content-Length', $body->getSize());
}
if ($body instanceof ReadableStreamInterface && $body->isReadable() && !$request->hasHeader('Content-Length')) {
$request = $request->withHeader('Transfer-Encoding', 'chunked');
}
$headers = array();
foreach ($request->getHeaders() as $name => $values) {
$headers[$name] = implode(', ', $values);
}
$deferred = new Deferred();
$requestStream = $this->http->request($request->getMethod(), (string) $uri, $headers, $request->getProtocolVersion());
$requestStream->on('error', function ($error) use($deferred) {
$deferred->reject($error);
});
$requestStream->on('response', function (ResponseStream $responseStream) use($deferred, $messageFactory) {
// apply response header values from response stream
$deferred->resolve($messageFactory->response($responseStream->getVersion(), $responseStream->getCode(), $responseStream->getReasonPhrase(), $responseStream->getHeaders(), $responseStream));
});
if ($body instanceof ReadableStreamInterface) {
if ($body->isReadable()) {
if ($request->hasHeader('Content-Length')) {
// length is known => just write to request
$body->pipe($requestStream);
} else {
// length unknown => apply chunked transfer-encoding
// this should be moved somewhere else obviously
$body->on('data', function ($data) use($requestStream) {
$requestStream->write(dechex(strlen($data)) . "\r\n" . $data . "\r\n");
});
$body->on('end', function () use($requestStream) {
$requestStream->end("0\r\n\r\n");
});
}
} else {
// stream is not readable => end request without body
$requestStream->end();
}
} else {
// body is fully buffered => write as one chunk
$requestStream->end((string) $body);
}
return $deferred->promise();
}