Misultin doesn't like POST without Content-Length #101

Open
majek opened this Issue Feb 10, 2012 · 5 comments

2 participants

@majek

1. Run simplistic misultin http server, like this

#!/usr/bin/env escript
%%! -smp disable +A1 +K true -pz ./ebin -pa deps/misultin/ebin -input
-module(misultin_ws_close_bug).
-mode(compile).

-export([main/1]).

main(_) ->
    Port = 8000,

    io:format(" [*] Running at http://localhost:~p~n", [Port]),
    misultin:start_link([{port, Port}, {autoexit, false},
                                      {loop,    fun (Req) -> handle_http(Req) end}]),
    receive
        _ -> ok
    end.

handle_http(Req) ->
    Req:respond(404, <<"404 - Nothing here\n">>).

2. Run curl:

curl -v localhost:8000 -X POST

Result:

< HTTP/1.1 400 Bad Request
< Content-Length: 49
< Connection: Close
< 
<h1>400 Bad Request</h1>

Logs say:

=ERROR REPORT==== 10-Feb-2012::17:30:18 ===                                                                                                                                                                                                  
        module: misultin_http                                                                                                                                                                                                                
        line: 392                                                                                                                                                                                                                            
error reading body: no_valid_content_specs

=ERROR REPORT==== 10-Feb-2012::17:30:18 ===
        module: misultin_http
        line: 371
tcp error treating post data: no_valid_content_specs, send bad request error back

3. Run curl with Content-Length set to 0:

curl -v localhost:8000 -X POST -H "Content-Length: 0"

Result:

< HTTP/1.1 404 Not Found
< Date: Fri, 10 Feb 2012 17:31:00 GMT
< Server: misultin/0.9
< Connection: Keep-Alive
< Content-Length: 19
< 
404 - Nothing here

Ie: Misultin crashes when POST is without content-length. I think it is reasonable to assume that when content-length is not present, no content will be sent. This is what other servers do.

@ostinelli
Owner

hi,

thank you for this report.

misultin does not crash. it raises an error on purpose, as per this line:
https://github.com/ostinelli/misultin/blob/master/src/misultin_http.erl#L392

as you can see, it perfectly handles the response error back, and this is intended behaviour.

i see your point and i believe that it should not log an error but just a debug message, so i'll change that. i also believe that it should return a 411 Length Required error instead of a 400, and not do what other servers do, whoever they are :)

i'll provide a patch asap.

@majek

Right. Just a quick dig through rfc:

Section 14.13 of RFC2616 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by the rules in section 4.4.
Any Content-Length greater than or equal to zero is a valid value. Section 4.4 describes how to determine the length of a message-body if a Content-Length is not given.

So, rfc leaves a possiblity of not sending the header.

Later on http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4

(Closing the connection cannot be used to indicate the end of a request body, since that would leave no possibility for the server to send back a response.)

So, if closing a connection is not allowed, thus not sending content-length must mean content-length of zero.

Just saying.

@ostinelli
Owner

The cases are three:

. the client sends a content-length -> handled
. the client sends a content-length of zero -> handled
. the client does not send a content-length -> the server can decide NOT to implement this and returns a 411 (misultin)

Re the closing of a connection: what the RFC states is that obviously the client has to wait for a response so it cannot just close it to say that it's done with sending a request. I am not sure I get why you deduct from it that "not sending content-length must mean content-length of zero". As you pointed out, RFC defines exactly what to do with this case, and it's not "assume that it's zero".

Are you referring to something that I've missed?

r.

@majek

Nope. I'm talking about the 3rd case.

@ostinelli
Owner

thank you for this.

misultin has been discontinued, my reasons here.

r.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment