[racket] webserver : "chunked tail no NL" error in varnish

From: Guillaume Coré (g at fridim.org)
Date: Tue Mar 11 12:45:25 EDT 2014

That works with both varnish and nginx!

Guillaume

On 03/11/2014 12:38 PM, Jay McCarthy wrote:
> I agree with your interpretation of the spec Greg.
> 
> Guillaume, would it be possible for you to put in this code and try it out:
> 
> (define (output-response-body/chunked conn bresp)
>   (define-values (from-servlet to-chunker) (make-pipe))
>   (define to-client (connection-o-port conn))
>   (define to-chunker-t
>     (thread (λ ()
>               ((response-output bresp) to-chunker)
>               (close-output-port to-chunker))))
>   (define buffer (make-bytes 1024))
>   (let loop ()
>     (define bytes-read-or-eof
>       (read-bytes-avail! buffer from-servlet))
>     (unless (eof-object? bytes-read-or-eof)
>       (fprintf to-client "~a\r\n" (number->string bytes-read-or-eof 16))
>       (write-bytes buffer to-client 0 bytes-read-or-eof)
>       (fprintf to-client "\r\n")
>       (loop)))
>   (thread-wait to-chunker-t)
>   (fprintf to-client "0\r\n")
>   (fprintf to-client "\r\n")
>   (flush-output to-client))
> 
> On Tue, Mar 11, 2014 at 9:53 AM, Greg Hendershott
> <greghendershott at gmail.com> wrote:
>>> The code in webserver-lib seems alright though :
>>>
>>> (define (output-response-body/chunked conn bresp)
>>>   (define-values (from-servlet to-chunker) (make-pipe))
>>>   (define to-client (connection-o-port conn))
>>>   (define to-chunker-t
>>>     (thread (λ ()
>>>               ((response-output bresp) to-chunker)
>>>               (close-output-port to-chunker))))
>>>   (define buffer (make-bytes 1024))
>>>   (define total-size
>>>     (let loop ([total-size 0])
>>>       (define bytes-read-or-eof
>>>         (read-bytes-avail! buffer from-servlet))
>>>       (if (eof-object? bytes-read-or-eof)
>>>         total-size
>>>         (begin
>>>           (fprintf to-client "~a\r\n" (number->string bytes-read-or-eof 16))
>>>           (write-bytes buffer to-client 0 bytes-read-or-eof)
>>>           (fprintf to-client "\r\n")
>>>           (loop (+ total-size bytes-read-or-eof))))))
>>>   (thread-wait to-chunker-t)
>>>   (fprintf to-client "0\r\n")
>>>   (print-headers
>>>    to-client
>>>    (list (header #"Content-Length"
>>>                  (string->bytes/utf-8 (number->string total-size)))))
>>>   (flush-output to-client))
>>
>> Apologies in advance if I'm confused, but I'm not sure that the
>> `print-headers` near the end is correct.
>>
>> My understanding:
>>
>> 1. Trailing headers should only be sent if there was a TE request
>> header (I don't see that checked for.)
>>
>> 2. Trailing headers should be listed in a Trailer response header (I
>> don't see one sent here.)
>>
>> 3. A few headers "MUST NOT" be trailing headers: Trailer,
>> Transfer-Encoding, and Content-Length (but the last _is_ sent here).
>>
>> Source: http://tools.ietf.org/html/rfc2616#section-14.40
>>
>> Assuming that's correct the `(print-headers ... #"Content-Length"
>> ...)` should simply be deleted, I think?
>>
>> Maybe the trailing Content-Length header is what Varnish is being strict about.
>>
>> I haven't studied web-server code, so again, apologies if I'm misunderstanding!
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
> 
> 
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 815 bytes
Desc: OpenPGP digital signature
URL: <http://lists.racket-lang.org/users/archive/attachments/20140311/e01feb2a/attachment.sig>

Posted on the users mailing list.