getHeader() public method

If multiple headers were received for the specified field only the value of the first header is returned. Applications may use Request::getHeaderArray() to retrieve a list of all header values received for a given field. All header $field names are treated case-insensitively. A null return indicates the requested header field was not present.
public getHeader ( string $field ) : string | null
$field string
return string | null
Example #1
0
 public function authorize(Request $request, Response $response)
 {
     if (!$request->getHeader("authorization")) {
         $response->setStatus(401);
         $response->setHeader("www-authenticate", "Basic realm=\"Use your ID as username and token as password!\"");
         $response->send("");
         return;
     }
     $authorization = $request->getHeader("authorization");
     $authorization = explode(" ", $authorization, 2);
     if (count($authorization) < 2) {
         $result = new Error("bad_request", "invalid authorization header", 400);
         $this->writeResponse($request, $response, $result);
         return;
     }
     switch (strtolower($authorization[0])) {
         case "token":
             break;
         case "basic":
             $authorization[1] = (string) @base64_decode($authorization[1]);
             break;
         default:
             $result = new Error("bad_request", "invalid authorization header", 400);
             $this->writeResponse($request, $response, $result);
             return;
     }
     try {
         $user = (yield resolve($this->authentication->authenticateWithToken($authorization[1])));
         $request->setLocalVar("chat.api.user", $user);
     } catch (AuthenticationException $e) {
         $result = new Error("bad_authentication", "invalid token in authorization header", 403);
         $this->writeResponse($request, $response, $result);
     }
     // a callable further down the chain will send the body
 }
Example #2
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"];
 }
Example #3
0
 /**
  * @param Request $req
  * @param array $options available options are:
  *                       - size (default: 131072)
  *                       - input_vars (default: 200)
  *                       - field_len (default: 16384)
  */
 public function __construct(Request $req, array $options = [])
 {
     $this->req = $req;
     $type = $req->getHeader("content-type");
     $this->body = $req->getBody($this->totalSize = $this->size = $options["size"] ?? 131072);
     $this->maxFieldLen = $options["field_len"] ?? 16384;
     $this->maxInputVars = $options["input_vars"] ?? 200;
     if ($type !== null && strncmp($type, "application/x-www-form-urlencoded", \strlen("application/x-www-form-urlencoded"))) {
         if (!preg_match('#^\\s*multipart/(?:form-data|mixed)(?:\\s*;\\s*boundary\\s*=\\s*("?)([^"]*)\\1)?$#', $type, $m)) {
             $this->req = null;
             $this->parsing = true;
             $this->result = new ParsedBody([]);
             return;
         }
         $this->boundary = $m[2];
     }
     $this->body->when(function ($e, $data) {
         $this->req = null;
         \Amp\immediately(function () use($e, $data) {
             if ($e) {
                 if ($e instanceof ClientSizeException) {
                     $e = new ClientException("", 0, $e);
                 }
                 $this->error = $e;
             } else {
                 $this->result = $this->end($data);
             }
             if (!$this->parsing) {
                 $this->parsing = true;
                 foreach ($this->result->getNames() as $field) {
                     foreach ($this->result->getArray($field) as $_) {
                         foreach ($this->watchers as list($cb, $cbData)) {
                             $cb($field, $cbData);
                         }
                     }
                 }
             }
             $this->parsing = true;
             foreach ($this->whens as list($cb, $cbData)) {
                 $cb($this->error, $this->result, $cbData);
             }
             $this->whens = $this->watchers = [];
         });
     });
 }
Example #4
0
 private function getJsonRequestBody(AerysRequest $request, AerysResponse $response) : \Generator
 {
     if ($request->getHeader('Content-Type') !== 'application/json') {
         $this->respondWithError($response, 400, 'Type of request body must be application/json');
         return null;
     }
     $body = $request->getBody();
     $bodyText = '';
     while ((yield $body->valid())) {
         $bodyText .= $body->consume();
     }
     try {
         $json = json_try_decode($bodyText, true);
     } catch (JSONDecodeErrorException $e) {
         $this->respondWithError($response, 400, 'Unable to decode request body as application/json');
         return null;
     }
     if (!is_array($json)) {
         $this->respondWithError($response, 400, 'Invalid request data structure');
         return null;
     }
     return $json;
 }
Example #5
0
 private function checkPreconditions(Request $request, int $mtime, string $etag)
 {
     $ifMatch = $request->getHeader("If-Match");
     if ($ifMatch && \stripos($ifMatch, $etag) === false) {
         return self::PRECOND_FAILED;
     }
     $ifNoneMatch = $request->getHeader("If-None-Match");
     if ($ifNoneMatch && \stripos($ifNoneMatch, $etag) !== false) {
         return self::PRECOND_NOT_MODIFIED;
     }
     $ifModifiedSince = $request->getHeader("If-Modified-Since");
     $ifModifiedSince = $ifModifiedSince ? @\strtotime($ifModifiedSince) : 0;
     if ($ifModifiedSince && $mtime > $ifModifiedSince) {
         return self::PRECOND_NOT_MODIFIED;
     }
     $ifUnmodifiedSince = $request->getHeader("If-Unmodified-Since");
     $ifUnmodifiedSince = $ifUnmodifiedSince ? @\strtotime($ifUnmodifiedSince) : 0;
     if ($ifUnmodifiedSince && $mtime > $ifUnmodifiedSince) {
         return self::PRECOND_FAILED;
     }
     $ifRange = $request->getHeader("If-Range");
     if (!($ifRange || $request->getHeader("Range"))) {
         return self::PRECOND_OK;
     }
     /**
      * This is a really stupid feature of HTTP but ...
      * If-Range headers may be either an HTTP timestamp or an Etag:
      *
      *     If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
      *
      * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.27
      */
     if ($httpDate = @\strtotime($ifRange)) {
         return $httpDate > $mtime ? self::PRECOND_IF_RANGE_OK : self::PRECOND_IF_RANGE_FAILED;
     }
     // If the If-Range header was not an HTTP date we assume it's an Etag
     return $etag === $ifRange ? self::PRECOND_IF_RANGE_OK : self::PRECOND_IF_RANGE_FAILED;
 }
Example #6
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.");
     }
 }
Example #7
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);
 }