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

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Wed Mar 12 10:53:11 EDT 2014

Great. I'll be running the normal tests and pushing it.

On Tue, Mar 11, 2014 at 10:45 AM, Guillaume Coré <g at fridim.org> wrote:
> 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
>>
>>
>>
>
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93


Posted on the users mailing list.