Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the Host or :authority header in Cro when using HTTP/2

When using Cro with HTTP1.1 I can access the requested Host via both the host method request.uri.host in Cro::Uri as well as the Host or :authority header sent by the browser via the request.header method in Cro::HTTP::Request.

However, when I use HTTP/2, none of these work. The Uri object only contains the schema and the path.

I'm using an official certificate with a wildcard for subdomains and running this locally by adding these subdomains to my hosts file. Chrome DevTools says it has sent the :authority request header under HTTP/2 and Firefox Developer Tools says it has sent the Host request header under HTTP/2. However if I write the headers to a log like below, I see several headers, but not the Host or :authority header.

sub routes() is export {
  route {
    get -> {
      my $log = "/data/myapp/logs/cro.log";
      my $fh = open $log, :w;
      my $host = request.uri.host;
      $fh.say( "Host with host method: " ~ $host );
      $host = request.header('Host');
      $fh.say( "Host: " ~ $host );
      $host = request.header(':authority');
      $fh.say(":authority: " ~ $host );
      $fh.say( "Request headers:" );
      for request.headers {
        $fh.say( "{.name}: {.value}" );
      }
      $fh.close;
      content 'text/html', "<h1> MyApp </h1><p>Running";
    }
  }
}

I'm aware that HTTP/2 uses Server Name Indication and that the host name is sent as part of the TLS negotiation. On the other hand this is also part of the Cro modules (Cro::TLS) and the headers are sent by the browser nonetheless.

So how to get the host under HTTP/2?

like image 266
acw Avatar asked Jun 08 '20 01:06

acw


People also ask

What is the Host HTTP header?

The HTTP host header is a request header that specifies the domain that a client (browser) wants to access. This header is necessary because it is pretty standard for servers to host websites and applications at the same IP address. However, they don't automatically know where to direct the request.

What is the host header POST request?

The Host request header specifies the host and port number of the server to which the request is being sent. If no port is included, the default port for the service requested is implied (e.g., 443 for an HTTPS URL, and 80 for an HTTP URL). A Host header field must be sent in all HTTP/1.1 request messages.

How do you add a host to a header?

If you want this to be available for one computer only, you can edit /etc/hosts (*nix) or C:\Windows\System32\drivers\etc\hosts (Windows) and add the hostname + ip address in the file. Show activity on this post. You don't. You can't set HTTP headers as part of URL, it's not the way it works.


1 Answers

This appears to be a plain bug (unrelated to ones named by Raiph).

I wrote a patch and sent a PR (https://github.com/croservices/cro-http/pull/104), with it merged you can update your Cro::HTTP distribution and both ways you specified (request.uri construction or asking for header('Host')) will work.

like image 84
Takao Avatar answered Oct 16 '22 17:10

Takao