lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Jul 16, 2014 at 12:32:46PM +0200, Pierre Chapuis wrote:
> The new RFC (7230) says very clearly:
> 
> > A client MUST send a Host header field in all HTTP/1.1 request
> > messages.  If the target URI includes an authority component, then a
> > client MUST send a field-value for Host that is identical to that
> > authority component, excluding any userinfo subcomponent and its "@"
> > delimiter (Section 2.7.1).  If the authority component is missing or
> > undefined for the target URI, then a client MUST send a Host header
> > field with an empty field-value.
> 
> What this means is that if the user writes:
> 
>     http.request("http://www.example.com:80";)
> 
> then the Host header must be: www.example.com:80

"Must" doesn't follow from the RFC, that's just an unrelated decision about
the semantics of the LuaSocket API; to not normalize the authority section
of the provided URL. You could normalize the authority so as to not include
the port in the Host field. This is what browsers do. If you type
www.google.com:80 into the browser bar, it's not going to send Host:
www.google.com:80. Likewise if you click on a link. I just tested Chrome
using this simple script

	local cqueues = require"cqueues"
	local socket = require"cqueues.socket"
	local bind, port = ...

	assert(cqueues.new():wrap(function()
	        for con in socket.listen(bind, port):clients() do
	                cqueues.running():wrap(function()
	                        for ln in con:lines("*l") do
	                                print(ln)
	                        end
	                end)
	        end
	end):loop())

which echos to stdout everything the browser sends. (Be sure to use port 80
otherwise it _will_ send the port.)

All that passage is saying is that _if_ you send an absolute URI in the
request line, then the authority section must match that in the Host header.

But sending absolute URIs in the request line leads to interoperability
problems, and it's perfectly acceptable (and legal) to only use the path
component from the user-specified URL when generating the request line, and
to normalize the authority component to excise default ports when generating
the Host header.

> If the user writes:
> 
>     http.request("http://foo:bar@example.com/baz";)
> 
> then the Host header must be: example.com

Again, it doesn't follow from the RFC, that's just a decision taken by the
API developer.
 
> This RFC was not out when I wrote that patch, otherwise
> I would have implemented it this way, which is what Diego
> proposes to do now. It solves the problem, in that if you
> are dealing with a webserver that does not accept some
> form of the header you can just change the URL. (Note:
> even with LuaSocket as it is now you can always specify
> the Host header manually as a temporary fix).

In my opinion _choosing_ to do things this way is perfectly acceptable also.
If the port is explicitly included in the URI string passed to http.request,
then use it. It's a simple and straight-forward API decision. It's just not
mandated in any way, shape, or form by the RFC.

It's also likely to catch many people by surprise who will be unaware that
by explicitly including the port in the URI passed to http.request that they
may get different behavior from the exact same server.