Skip to content

Absolute domain names get trailing dot stripped from host request header #8290

@ccazabon

Description

@ccazabon

curl doesn't honour the domain name part of the redirected URL if it is an absolute name; curl strips the trailing dot. This causes problems loading some pages where the servers are configured to redirect non-absolute requests to the absolute ones:

$ curl -v -IL --max-redirs 1 http://pyropus.ca./
> HEAD / HTTP/1.1
> Host: pyropus.ca
> User-Agent: curl/7.74.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Location: https://pyropus.ca./
< 
* Connection #0 to host pyropus.ca left intact
* Issue another request to this URL: 'https://pyropus.ca./'
*   Trying 96.126.125.117:443...
*  SSL certificate verify ok.
> HEAD / HTTP/1.1
> Host: pyropus.ca
> User-Agent: curl/7.74.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Location: https://pyropus.ca./

... so that loops until max-redirects is hit.

The RFCs seem to say that the location value should be used as presented by the server. It should only strip the dot from SNI, not from the Host: request header.

This has come up a couple of times before:
#716
#3022

... but those seem to be about requests to servers that accidentally (?) include the trailing dot, i.e. the servers are not expecting it. The server itself isn't issuing a redirect to the absolute version of its domain name. So accidental breakage in the cases listed shouldn't be a major issue, I think. While the current behaviour does break sites that are using this feature deliberately.

As for other user agents:

  • all GUI browers, to my knowledge, preserve the absolute domain name in the Host: header - I've tested Firefox, Chromium, Vivaldi, Konqueror, and Safari
  • wget also preserves the absolute domain name on redirect URLs
  • lynx, links, and elinks handle it like curl, erroring out on a redirect loop

I didn't find any other open/closed issues related to this, and the known bugs page doesn't have anything relevant.

I did this

curl -v -IL --max-redirs 1 https://pyropus.ca/

I expected the following

curl to resend the request with the Host: header value set to pyropus.ca. .

curl/libcurl version

curl 7.74.0 (x86_64-pc-linux-gnu) libcurl/7.74.0 OpenSSL/1.1.1k zlib/1.2.11 brotli/1.0.9 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.43.0 librtmp/2.3
Release-Date: 2020-12-09
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

operating system

Linux 5.14.16 #1 SMP Thu Nov 4 11:18:07 CST 2021 x86_64 GNU/Linux

Debian 11 / Bullseye

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions