private function assignCommonHeaders($fileInfo, Response $response) { $response->setHeader("Accept-Ranges", "bytes"); $response->setHeader("Cache-Control", "public"); $response->setHeader("Etag", $fileInfo->etag); $response->setHeader("Last-Modified", \gmdate('D, d M Y H:i:s', $fileInfo->mtime) . " GMT"); $canCache = $this->expiresPeriod > 0; if ($canCache && $this->useAggressiveCacheHeaders) { $postCheck = (int) ($this->expiresPeriod * $this->aggressiveCacheMultiplier); $preCheck = $this->expiresPeriod - $postCheck; $expiry = $this->expiresPeriod; $value = "post-check={$postCheck}, pre-check={$preCheck}, max-age={$expiry}"; $response->setHeader("Cache-Control", $value); } elseif ($canCache) { $expiry = $this->now + $this->expiresPeriod; $response->setHeader("Expires", \gmdate('D, d M Y H:i:s', $expiry) . " GMT"); } else { $response->setHeader("Expires", "0"); } }
private function doRangeResponse($range, $fileInfo, Response $response) { $this->assignCommonHeaders($fileInfo); $range->contentType = $mime = $this->selectMimeTypeFromPath($fileInfo->path); if (isset($range->ranges[1])) { $response->setHeader("Content-Type", "multipart/byteranges; boundary={$range->boundary}"); } else { list($startPos, $endPos) = $range->ranges[0]; $response->setHeader("Content-Length", (string) ($endPos - $startPos)); $response->setHeader("Content-Range", "bytes {$startPos}-{$endPos}/{$fileInfo->size}"); $response->setHeader("Content-Type", $mime); } $response->setStatus(HTTP_STATUS["PARTIAL_CONTENT"]); return $this->finalizeResponse($response, $fileInfo, $range); }
public function getAllRooms(AerysRequest $request, AerysResponse $response) { $result = []; /** @var ChatRoom $room */ foreach ($this->chatRooms as $room) { $result[] = ['host' => $room->getIdentifier()->getHost(), 'room_id' => $room->getIdentifier()->getId()]; } $response->setHeader('Content-Type', 'application/json'); $response->end(json_encode($result)); }
public function doLogOut(Request $request, Response $response) { $session = new Session($request); (yield $session->open()); (yield $session->destroy()); $response->setStatus(302); $response->setHeader("location", "/"); $response->send(""); }
private function tryErrorResponse(\Throwable $error, InternalRequest $ireq, Response $response, array $filters) { try { $status = HTTP_STATUS["INTERNAL_SERVER_ERROR"]; $msg = $this->options->debug ? "<pre>" . htmlspecialchars($error) . "</pre>" : "<p>Something went wrong ...</p>"; $body = makeGenericBody($status, ["sub_heading" => "Requested: {$ireq->uri}", "msg" => $msg]); $response->setStatus(HTTP_STATUS["INTERNAL_SERVER_ERROR"]); $response->setHeader("Connection", "close"); $response->end($body); } catch (ClientException $error) { return; } catch (\Throwable $error) { if ($ireq->filterErrorFlag) { $this->tryFilterErrorResponse($error, $ireq, $filters); } else { $this->logger->error($error); $this->close($ireq->client); } } }
/** * Handles all hooks. * * @param Request $request HTTP request * @param Response $response HTTP response * @param array $args URL args */ public function handle(Request $request, Response $response, array $args) { $response->setHeader("content-type", "text/plain"); $token = $request->getQueryVars()["token"] ?? ""; if (!$token || !is_string($token)) { $response->setStatus(401); $response->send("Failure: No token was provided."); return; } // use @ so we don't have to check for invalid strings manually $token = (string) @hex2bin($token); $hook = (yield $this->hookRepository->get($args["id"])); if (!$hook) { $response->setStatus(404); $response->send("Failure: Hook does not exist."); return; } if (!hash_equals($hook->token, $token)) { $response->setStatus(403); $response->send("Failure: Provided token doesn't match."); return; } $name = $args["service"]; if (!isset($this->services[$name])) { $response->setStatus(404); $response->send("Failure: Unknown service."); return; } $contentType = strtok($request->getHeader("content-type"), ";"); $body = (yield $request->getBody()); switch ($contentType) { case "application/json": $payload = json_decode($body); break; case "application/x-www-form-urlencoded": parse_str($body, $payload); $payload = json_decode(json_encode($payload)); break; default: $response->setStatus(415); $response->send("Failure: Content-type not supported."); return; } $service = $this->services[$name]; $headers = $request->getAllHeaders(); $event = $service->getEventName($headers, $payload); if (!isset($this->schemas[$name][$event])) { $response->setStatus(400); $response->send("Failure: Event not supported."); return; } $schema = $this->schemas[$name][$event]; $this->validator->reset(); $this->validator->check($payload, $schema); if (!$this->validator->isValid()) { $errors = $this->validator->getErrors(); $errors = array_reduce($errors, function (string $carry, array $item) : string { if ($item["property"]) { return $carry . sprintf("\n%s: %s", $item["property"], $item["message"]); } else { return $carry . "\n" . $item["message"]; } }, ""); $response->setStatus(400); $response->send("Failure: Payload validation failed." . $errors); return; } $message = $service->handle($headers, $payload); try { if ($message) { $req = (new HttpRequest())->setMethod("PUT")->setUri($this->config["api"] . "/messages")->setHeader("authorization", "Basic " . base64_encode("{$this->config['user_id']}:{$this->config['token']}"))->setBody(json_encode(["room_id" => $hook->room_id, "text" => $message->getText(), "data" => $message->getData()])); $resp = (yield $this->http->request($req)); if (intval($resp->getStatus() / 100) !== 2) { $message = "API request failed: " . $resp->getStatus(); if ($resp->getBody()) { $message .= "\n" . $resp->getBody(); } throw new Exception($message); } } $response->send("Success: " . ($message ? "Message sent." : "Message skipped.")); } catch (Exception $e) { $response->setStatus(500); $response->send("Failure: Couldn't persist message."); } }
public function rateLimit(Request $request, Response $response) { $user = $request->getLocalVar("chat.api.user"); if (!$user) { // if this happens, something's really wrong, e.g. wrong order of callables $response->setStatus(500); $response->send(""); return; } $count = (yield resolve($this->rateLimit->increment("limit:u:{$user->id}"))); $ttl = (yield resolve($this->rateLimit->ttl("limit:u:{$user->id}"))); $remaining = self::RATE_LIMIT - $count; $response->setHeader("x-rate-limit-limit", self::RATE_LIMIT); $response->setHeader("x-rate-limit-remaining", max(0, $remaining)); $response->setHeader("x-rate-limit-reset", $ttl); if ($remaining < 0) { $response->setHeader("retry-after", $ttl); $error = new Error("too_many_requests", "your application exceeded its rate limit", 429); $this->writeResponse($request, $response, $error); } // a callable further down the chain will send the body }