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?
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With