Exemple #1
0
 public function onHandshake(Request $request, Response $response)
 {
     // During handshakes, you should always check the origin header, otherwise any site will
     // be able to connect to your endpoint. Websockets are not restricted by the same-origin-policy!
     $origin = $request->getHeader("origin");
     if ($origin !== "http://localhost:1337") {
         $response->setStatus(403);
         $response->send("<h1>origin not allowed</h1>");
         return null;
     }
     // returned values will be passed to onOpen, that way you can pass cookie values or the whole request object.
     return $request->getConnectionInfo()["client_addr"];
 }
Exemple #2
0
 private function sendMultiRange($handle, Response $response, $fileInfo, $range) : \Generator
 {
     foreach ($range->ranges as list($startPos, $endPos)) {
         $header = sprintf("--%s\r\nContent-Type: %s\r\nContent-Range: bytes %d-%d/%d\r\n\r\n", $range->boundary, $range->contentType, $startPos, $endPos, $fileInfo->size);
         $response->stream($header);
         yield from $this->sendSingleRange($handle, $response, $startPos, $endPos);
         $response->stream("\r\n");
     }
     $response->stream("--{$range->boundary}--");
 }
Exemple #3
0
 /**
  * @param \Aerys\Response $response The server Response to wrap for the handshake
  * @param string $acceptKey The client request's SEC-WEBSOCKET-KEY header value
  */
 public function __construct(Response $response, string $acceptKey)
 {
     $this->response = $response;
     $this->acceptKey = $acceptKey;
     $response->setStatus($this->status);
 }
Exemple #4
0
 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));
 }
Exemple #5
0
 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("");
 }
Exemple #6
0
 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);
         }
     }
 }
Exemple #7
0
 /**
  * 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.");
     }
 }
Exemple #8
0
 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);
 }
Exemple #9
0
 public function handle(Request $request, Response $response, array $args)
 {
     $endpoint = $request->getLocalVar("chat.api.endpoint");
     $user = $request->getLocalVar("chat.api.user");
     if (!$endpoint || !$user) {
         // if this happens, something's really wrong, e.g. wrong order of callables
         $response->setStatus(500);
         $response->send("");
     }
     foreach ($args as $key => $arg) {
         if (is_numeric($arg)) {
             $args[$key] = (int) $arg;
         }
     }
     foreach ($request->getQueryVars() as $key => $value) {
         // Don't allow overriding URL parameters
         if (isset($args[$key])) {
             continue;
         }
         if (is_numeric($value)) {
             $args[$key] = (int) $value;
         } else {
             if (is_string($value)) {
                 $args[$key] = $value;
             } else {
                 $result = new Error("bad_request", "invalid query parameter types", 400);
                 $this->writeResponse($request, $response, $result);
                 return;
             }
         }
     }
     $args = $args ? (object) $args : new stdClass();
     $body = (yield $request->getBody());
     $payload = $body ? json_decode($body) : null;
     $result = (yield $this->chat->process(new StandardRequest($endpoint, $args, $payload), $user));
     $this->writeResponse($request, $response, $result);
 }
Exemple #10
0
 public function onHandshake(Request $request, Response $response)
 {
     $origin = $request->getHeader("origin");
     if (!isOriginAllowed($origin)) {
         $response->setStatus(400);
         $response->setReason("Invalid Origin");
         $response->send("<h1>Invalid Origin</h1>");
         return null;
     }
     if ($this->eventSub->getConnectionState() !== ConnectionState::CONNECTED) {
         $response->setStatus(503);
         $response->setReason("Service unavailable");
         $response->send("");
         return null;
     }
     return new Session($request);
 }