dev_appserver does not properly read POST bodies without content-length header

29 views
Skip to first unread message

Ian Rose

unread,
Aug 30, 2016, 10:34:25 AM8/30/16
to google-appengine-go
I just created an issue here (https://code.google.com/p/googleappengine/issues/detail?id=13237) but figured I would also post on this list in case it gets more attention (I find the Go community tends to be a bit more responsive than app engine at-large)


I've found that if you POST data to a Go App Engine program running under dev_appserver, it does not properly read the body if a Content-Length header field is not present.  This does NOT appear to be a problem with deployed App Engine apps, or with standalone (non-appengine) Go servers running locally.

Here is the client and server I am using:

https://gist.github.com/ianrose14/6b25bcce679b25ff20fe7463f75682ce
https://gist.github.com/ianrose14/6824da861daa6f1e1504fe375e97922b

In the client there are 2 impls of readers on adjacent lines.  If you use my custom reader (rdr = &StrBuf{data: []byte(body)}) then the http lib will NOT write a Content-Length header and dev_appserver will render output like this:

2016/08/30 14:16:40 DEBUG: POST to /foo
2016/08/30 14:16:40 DEBUG: Content-Length: ""
2016/08/30 14:16:40 DEBUG: body (0 bytes):
INFO     2016-08-30 14:16:40,988 module.py:788] default: "POST /foo HTTP/1.1" 200 -

However if you use a strings.Reader (rdr = strings.NewReader(body)) then the http lib WILL write a Content-Length header and dev_appserver will render output like this:

2016/08/30 14:16:50 DEBUG: POST to /foo
2016/08/30 14:16:50 DEBUG: Content-Length: "9"
2016/08/30 14:16:50 DEBUG: body (9 bytes): {"foo":5}
INFO     2016-08-30 14:16:50,198 module.py:788] default: "POST /foo HTTP/1.1" 200 -

If I deploy this server, however, the outputs (respectively) are:

10:15:45.049 POST to http://mn-load.appspot.com/foo
10:15:45.049 Content-Length: ""
10:15:45.049 body (9 bytes): {"foo":5}

and

10:15:33.276 POST to http://mn-load.appspot.com/foo
10:15:33.276 Content-Length: "9"
10:15:33.276 body (9 bytes): {"foo":5}

So basically everything works fine.

I should also note that when running locally in the custom reader (failing) case, I often see "Unsolicited response received on idle HTTP channel starting with "H"; err=<nil>" in the client output.  And if I wireshark the interaction, I see:

request:  POST /foo (with a normal json payload as expected)
response:  200 OK
response:  400 Bad Request (with a body of "Malformed Request-Line")

I don't really understand what's going on here.  Perhaps dev_appserver.py is failing to properly proxy the request to the actual Go server binary?

thanks,
- Ian

Reply all
Reply to author
Forward
0 new messages