[racket-dev] Racket web server doesn't handle POST requests with 'Transfer-Encoding: chunked' ?

From: John Clements (clements at brinckerhoff.org)
Date: Fri Mar 9 03:44:19 EST 2012

My students are working on an assignment that has them CPS and defunctionalize a small evaluator so that they can ship computations from one compute server to another:

http://www.brinckerhoff.org/clements/csc430-wi12/Assignments/ass7.html

As part of this assignment, some of the students are writing servers in node.js, and one of them drew my attention to what appears to be a small bug in Racket's web server.  Specifically, it appears that when a request is made with POST data using the 'Transfer-Encoding: chunked" style, that the result of calling request-post-bytes/raw on the request is #f.  I can't tell whether the web server is actually reading the POST data correctly and discarding it when the request is constructed, or actually failing to read the data.

To see this happen, run this racket program:

#lang racket

(require web-server/servlet-env
web-server/http/xexpr
web-server/http)

; the function that handles requests:
(define (start request)
(define post-bytes (request-post-data/raw
request))
(cond [(bytes? post-bytes) (response/xexpr `(html "yep"))]
      [else (response/xexpr `(html "nope"))]))

; start serving the 'start' function on port 8054:
(serve/servlet start
#:servlet-regexp #px".*"
#:port 8054
#:launch-browser? #f)

... and then ping it with curl:

    curl -v -X POST -d "hello" http://localhost:8054 -H 'Transfer-Encoding: chunked'
* About to connect() to localhost port 8054 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8054 (#0)
> POST / HTTP/1.1
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3
> Host: localhost:8054
> Accept: */*
> Transfer-Encoding: chunked
> Content-Type: application/x-www-form-urlencoded
> 
> 5
< HTTP/1.1 200 Okay
< Date: Fri, 09 Mar 2012 08:41:55 GMT
< Last-Modified: Fri, 09 Mar 2012 08:41:55 GMT
< Server: Racket
< Content-Type: text/html; charset=utf-8
< Connection: close
< 
* Closing connection #0
<html>nope</html>


The header lines shown by curl here are exactly what they should be, but the server is getting #f for the post-bytes.

Trying this without the 'Transfer-Encoding: chunked' returns the expected byte-string:

oiseau:~ clements$ curl -v -X POST -d "hello" http://localhost:8054* About to connect() to localhost port 8054 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8054 (#0)
> POST / HTTP/1.1
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3
> Host: localhost:8054
> Accept: */*
> Content-Length: 5
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 200 Okay
< Date: Fri, 09 Mar 2012 08:43:25 GMT
< Last-Modified: Fri, 09 Mar 2012 08:43:25 GMT
< Server: Racket
< Content-Type: text/html; charset=utf-8
< Connection: close
< 
* Closing connection #0
<html>yep</html>

So, is this a bug, or a known problem, or am I just doing something silly? I spent (more time than I want to admit) poking around in the source tree, but I couldn't find the spot where the request was constructed.

John

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4624 bytes
Desc: not available
URL: <http://lists.racket-lang.org/dev/archive/attachments/20120309/a74dab53/attachment.p7s>

Posted on the dev mailing list.