/** * Respond to HTTP requests for filesystem resources */ public function __invoke(Request $request, Response $response) { $uri = $request->getLocalVar("aerys.sendfile") ?: $request->getUri(); $path = ($qPos = \strpos($uri, "?")) ? \substr($uri, 0, $qPos) : $uri; // IMPORTANT! Do NOT remove this. If this is left in, we'll be able to use /path\..\../outsideDocRoot defeating the removeDotPathSegments() function! (on Windows at least) $path = \str_replace("\\", "/", $path); $path = self::removeDotPathSegments($path); // We specifically break the lookup generator out into its own method // so that we can potentially avoid forcing the server to resolve a // coroutine when the file is already cached. return ($fileInfo = $this->fetchCachedStat($path, $request)) ? $this->respond($fileInfo, $request, $response) : $this->respondWithLookup($this->root . $path, $path, $request, $response); }
private function writeResponse(Request $request, Response $response, ApiResponse $result) { $response->setStatus($result->getStatus()); $response->setHeader("content-type", "application/json"); foreach ($result->getLinks() as $rel => $params) { $uri = strtok($request->getUri(), "?"); $uri .= "?" . http_build_query($params); $elements[] = "<{$uri}>; rel=\"{$rel}\""; } if (isset($elements)) { $response->addHeader("link", implode(", ", $elements)); } $response->send(json_encode($result->getData(), JSON_PRETTY_PRINT)); }
/** * Respond to HTTP requests for filesystem resources * * @param \Aerys\Request $request * @return mixed */ public function __invoke(Request $request, Response $response) { $uri = $request->getLocalVar("aerys.sendfile") ?: $request->getUri(); $path = ($qPos = \stripos($uri, "?")) ? \substr($uri, 0, $qPos) : $uri; $path = $reqPath = \str_replace("\\", "/", $path); $path = $this->root . $path; $path = self::removeDotPathSegments($path); // IMPORTANT! // Protect against dot segment path traversal above the document root by // verifying that the path actually resides in the document root. if (\strpos($path, $this->root) !== 0) { $response->setStatus(HTTP_STATUS["FORBIDDEN"]); $response->setHeader("Aerys-Generic-Response", "enable"); $response->end(); } // We specifically break the lookup generator out into its own method // so that we can potentially avoid forcing the server to resolve a // coroutine when the file is already cached. return ($fileInfo = $this->fetchCachedStat($reqPath, $request)) ? $this->respond($fileInfo, $request, $response) : $this->respondWithLookup($path, $reqPath, $request, $response); }
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); }