cli
cli copied to clipboard
Should use the user-provided Host header for SNI
I'm trying to test Apache configuration in a Vagrant VM that forwards port 8443 to VM's port 443. The command I'm running is:
$ http get https://localhost:443/ Host:www.example.com --verify=no
and I get a 400 Bad Request from Apache, because
[Mon Nov 23 09:43:17 2015] [error] Hostname localhost provided via SNI and hostname www.example.com provided via HTTP are different
I think httpie should use the user-provided Host header for the SSL negotiation, or perhaps even provide a command-line option to explicitly specify a hostname to use in SNI.
The easiest way to get this to work in the short term is to update your hosts file to point to the host in question. This will enable you to avoid needing to set the Host header as well.
In the longer term, I could see some value in HTTPie doing something similar to what curl does, or possibly even something a bit simpler that just works for SNI if we're happy to let people keep setting custom Host headers.
Note, however, that a lot of other things will get done wrong if you set a custom host header. For example, httpie probably won't handle cookies the way you expect. So using the hosts file is the better solution in the general case. Works for all your other tools too!
Good point about cookies! What about
http get https://foo.example.com/ --connect-to 127.0.0.1:8443
then?
I don't like curl's --resolve
solution (aka #362) because it requires me to repeat the host name, which is unnecessary in 99% of use-cases. (It's probably necessary if you want to follow redirects to a different domain name, that you're also testing in Vagrant or something like that.)
I don't like the /etc/hosts solution because:
- it requires root
- it affects the entire system, not just my little experimental shell session
- it's persistent and I have to remember to undo any testing changes I make
Yeah, curl's --resolve solution may be overkill in this case.
I don't like the /etc/hosts solution because:
You can use the HOSTALIASES environment variable to point at a file in your own part of the namespace that is used as a hosts file. That allows you to do something like env HOSTALIASES=~/hosts http get https://foo.example.com/
.
Thank you, I didn't know about HOSTALIASES!
(It still feels like extra work, compared to a command-line argument. Would you look favorably upon a pull request that implemented a --connect-to
option for httpie?)
I am not a maintainer of httpie, so I can't speak for @jkbrzt. However, the idea certainly doesn't bother me. =)
NB: the suggested HOSTALIASES
solution doesn't work for me -- I see httpie connect to the real IP address, and not the fake one provided via my /tmp/hosts, despite HOSTALIASES=/tmp/hosts http get ...
.
HOSTALIASES only works for "name[s] consist[ing] of a single component, that is, contains no dot", ref: http://man7.org/linux/man-pages/man7/hostname.7.html
gnutls-cli
has the --sni-hostname=...
option. It would be great to have that for http
too, and it would prevent unexpected effects when re-using the value of a header for a different purpose (TLS and HTTP live on different OSI layers, so should be treated independently).
Sad this looks stale, something like --connect host:port
seems to me to be the right approach.
Related: https://github.com/httpie/httpie/issues/99#issuecomment-772547367
I'm looking for a way to specify different hosts for connection, TLS and HTTP. Something like,
http https://foo.com --sni-host bar.com Host:baz.com
where I expect the client connect to the IP of the foo.com
, set the SNI to bar.com
and set HTTP Host header to baz.com
.