Hi All,

I am sure the problem is irrelevant to the CGI and mod_CGI. Because I try to load a image file, the result is the same.
And I forget to say one thing, the platform I'm using is a PowerPC architecture in an embedded system, so the apache is cross-compiled.

I guess it might be the cause, and may be located in APR or APR-util?

Anyway, that's really a tough issue for me...


On Tue, Jun 1, 2010 at 4:25 PM, Chen Chien-Yu <honercek@gmail.com> wrote:
Hi All,

After using the strace tools, there's a new find. It will stop at the function call read()....
A infinite loop happens in server/core_filters.c ap_core_input_filter().

    if (mode == AP_MODE_EATCRLF) {
        apr_bucket *e;
        const char *c;

        while (1) {
            if (APR_BRIGADE_EMPTY(ctx->b)) {
                return APR_EOF;

            e = APR_BRIGADE_FIRST(ctx->b);

            rv = apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ); <--------------- I guess this is the place gets stuck...

            if (rv != APR_SUCCESS) {
                return rv;                <---- successful case will exit via this place with the value of rv = 11. (APR_ENOSOCKET ??)

            c = str;
            while (c < str + len) {
                if (*c == APR_ASCII_LF)
                else if (*c == APR_ASCII_CR && *(c + 1) == APR_ASCII_LF)
                    c += 2;
                    return APR_SUCCESS;

            /* If we reach here, we were a bucket just full of CRLFs, so
             * just toss the bucket. */
            /* FIXME: Is this the right thing to do in the core? */

I don't know why it's stuck here, and does it relate to the zero-chunk packet that doesn't see in the client?


Best regards,

On Mon, May 31, 2010 at 8:14 AM, Chen Chien-Yu <honercek@gmail.com> wrote:
Hi William,

I'm sorry to confuse you.
Please let me reorganize the problem and my observations.

Client ---- HTTP ---- Apache ---- Mod-CGI ---- xxx.cgi ---- login.html

A client(browser) access the URI, http://xxx.xxx.xxx/xxx.cgi which is located on the Apache 2.2.15, but finally what it got was only the content of page and lack of the last chunk, which made the browser stuck and loading continually.

xxx.cgi is written with the GNU library looks like this. It will read the file login.html and put it on the network stream to the client.
I've also tried to return a string only "Hello" instead of the file content, the result is the same stuck.

If the directive HTTPS exists (Listen 443), the HTTP will not work correctly(Case A). But if I comment out the directives HTTPS, the HTTP will work without any problem(Case B). So I compared them by adding some debug messages in Apache.
There is another case that is workable as well, even the HTTP and HTTPS exist at the same time.(disable the KeepAlive mechanism, but it a must option for us in the performance point of view)

All the output filters are the built in ones, I didn't insert any one I write. (There are the filters I found, byterange, content length, http_header, http_outerror, core)


Client ---- HTTP ---- Apache ---- Mod-CGI ---- xxx.cgi ---- login.html

In Mod-CGI, there's a function called cgi_bucket_read(). It's a read method of CGI bucket: polls on stdout of the child. I found it read 806 bytes via a function call cgi_read_stdout() from stdout followed by a 0 byte read.

Then in Apache core filter, a function called ap_core_output_filter(), in the case of EOS, the function apr_bucket_read() inside it reads two times in a row, a 0 byte followed by a 5 bytes(0\r\n\r\n). Seems that, the 5 bytes bucket is the one the client expect.

Until now, there's no difference between Case A and Case B.

After this, I found the successful one(Case B) will flush out a 5 bytes bucket in the core filter. I have no idea who triggers this event. But nothing happens in Case A.


Best regards,

On Fri, May 28, 2010 at 8:58 PM, William A. Rowe Jr. <wrowe@rowe-clan.net> wrote:
On 5/28/2010 3:08 AM, Chen Chien-Yu wrote:
> Hi William,
> I gave you the incorrect information in the previous post.
> cgi_read_stdout() in cgi_bucket_read() in mod_cgi.c, the data length is
> 806 followed by 0. (Not the 0 and 5 buckets)
> then ap_core_output_filter() found a 0 length bucket, and appended a
> last-chunk bucket?

What you describe sounds like correct HTTP behavior.  The last-chunk
bucket is being correctly transmitted after the 806 byte bucket?

I'm losing track of what the exact problem is.

Also do you insert any additional filters for the output of this filter?