Re: Problem with mod_ruby and chunked transfer encoding

Brian Candler <[email protected]> Thu, 14 Oct 2004 16:04:09 +0100
Newsgroups gmane.comp.apache.mod-ruby
Message-ID <[email protected]>

> This seems to say that chunked transfer encoding is explicitly disabled for
> every request. Why should this be? I know that older versions of Apache had
> a bug, but this was fixed in 1.3.26

A simple patch is attached, which allows chunking by default, unless the
Apache version is too old.

It would be better if this behaviour could be user-definable at runtime, but
it looks to be a bit awkward. You have to call ap_setup_client_block *after*
the headers have been read, but *before* you start to read the body. (This
is because ap_setup_client_block checks for the presence of various
headers). Hence you can't call it in apache_request_new and override it
later.

We could add an instance variable to the Apache::Request object, stating
what mode is required (i.e. REQUEST_NO_BODY, REQUEST_CHUNKED_ERROR etc).

Or, we could add an extra parameter to request_read/read_client_block
stating which mode is required. This value would be used on the first read,
but ignored on subsequent ones.

Also, to support chunking properly, the we must pass in a buffer at least
big enough to handle one chunk-size line (with extensions, if any). This
means

        buf = (char *) ap_palloc(r->pool, len);
becomes something like
        buf = (char *) ap_palloc(r->pool, len>80 ? len : 80);

(only necessary if chunking is in use). Otherwise, if someone calls
request_getc, which requests only 1 byte, chunking will not work.

Any other suggestions?

Regards,

Brian.



--- mod_ruby-1.2.4/request.c.orig	Thu Sep 23 19:43:18 2004
+++ mod_ruby-1.2.4/request.c	Wed Oct 13 12:27:48 2004
@@ -890,7 +890,12 @@
     VALUE result;
 
     if (r->read_length == 0) {
+#if (APACHE_RELEASE >= 10326100 && APACHE_RELEASE <= 10399999) || \
+    (APACHE_RELEASE >= 20037100 && APACHE_RELEASE <= 29999999)
+        if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) {
+#else
         if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) {
+#endif
 	    rb_apache_exit(rc);
         }
     }