public function __invoke(Request $req, Response $res)
{
$headers = $req->getAllHeaders();
unset($headers["accept-encoding"]);
$connection = $headers["connection"];
unset($headers["connection"]);
foreach ($connection as $value) {
foreach (explode(",", strtolower($value)) as $type) {
$type = trim($type);
if ($type == "upgrade") {
$headers["connection"][0] = "upgrade";
} else {
unset($headers[$type]);
}
}
}
if ($this->headers) {
if (is_callable($this->headers)) {
$headers = ($this->headers)($headers);
} else {
$headers = $this->headers + $headers;
}
}
$promise = $this->client->request((new \Amp\Artax\Request())->setMethod($req->getMethod())->setUri($this->target . $req->getUri())->setAllHeaders($headers)->setBody((yield $req->getBody())));
// no async sending possible :-( [because of redirects]
$promise->watch(function ($update) use($req, $res, &$hasBody, &$status, &$zlib) {
list($type, $data) = $update;
if ($type == Notify::RESPONSE_HEADERS) {
$headers = array_change_key_case($data["headers"], CASE_LOWER);
foreach ($data["headers"] as $header => $values) {
foreach ($values as $value) {
$res->addHeader($header, $value);
}
}
$res->setStatus($status = $data["status"]);
$res->setReason($data["reason"]);
if (isset($headers["content-encoding"]) && strcasecmp(trim(current($headers["content-encoding"])), 'gzip') === 0) {
$zlib = inflate_init(ZLIB_ENCODING_GZIP);
}
$hasBody = true;
}
if ($type == Notify::RESPONSE_BODY_DATA) {
if ($zlib) {
$data = inflate_add($zlib, $data);
}
$res->stream($data);
}
if ($type == Notify::RESPONSE) {
if (!$hasBody) {
foreach ($data->getAllHeaders() as $header => $values) {
foreach ($values as $value) {
$res->addHeader($header, $value);
}
}
$res->setStatus($status = $data->getStatus());
$res->setReason($data->getReason());
}
if ($status == 101) {
$req->setLocalVar("aerys.reverse.socket", $update["export_socket"]());
}
$res->end($zlib ? inflate_add("", ZLIB_FINISH) : null);
}
});
(yield $promise);
}