Hi, First, I'd like to appreciate the helps from William and Jeff.
This is the mail I posted in APR mail list. http://mail-archives.apache.org/mod_mbox/apr-dev/201006.mbox/ajax/%3caanlktilutimlujysja8pdj7a16ti_gw6lu-e9u6i5...@mail.gmail.com%3e --------------------------------------------------------------------------------------------------------------------------------------------------------------------- I've been suffering from a problem for more than 1 week. The client will get stuck when reading a page from Apache, it just waits for the zero-chunk being sent from the Apache. This post ( http://mail-archives.apache.org/mod_mbox/httpd-users/201005.mbox/%3caanlktinkrr60loyct3eytmclwzavl9or3e8pwgoy7...@mail.gmail.com%3e ) describes the problem I met. After some debugging and analyses ( http://mail-archives.apache.org/mod_mbox/httpd-users/201006.mbox/%3caanlktinwenme6xwgtpokzcmhhk5shkaafcvfaqrlw...@mail.gmail.com%3e ), it seems the problem is caused by the APR library when processing the bucket reading, an infinite loop?! Then I found a post in this mail list with similar symptom as mine ( http://mail-archives.apache.org/mod_mbox/apr-dev/200704.mbox/%3c20070425010624.ga46...@zeus.kimaker.com%3e ), and another discussion that might be related to my problem ( http://mail-archives.apache.org/mod_mbox/apr-dev/200405.mbox/%3c20040507002929.ga19...@manyfish.co.uk%3e ). But the post about "blocking bucket reads on non-blocking sockets" was in 2004, it's 6 years ago. The Apache version I'm using is 2.2.15, the newest stable version, I don't think the bug fix wouldn't include in the version. I've tested the fix "Ryan Phillips" posted in ( http://mail-archives.apache.org/mod_mbox/apr-dev/200704.mbox/%3c20070425010624.ga46...@zeus.kimaker.com%3e). It did work for my case. But I'm not sure if it's right or not.. Index: sockopt.c =================================================================== --- sockopt.c (revision 532161) +++ sockopt.c (working copy) @@ -102,7 +102,7 @@ /* must disable the incomplete read support if we disable * a timeout */ - if (t <= 0) { + if (t < 0) { sock->options &= ~APR_INCOMPLETE_READ; } sock->timeout = t; Thanks Best regards, honercek On Wed, Jun 2, 2010 at 9:25 AM, Chen Chien-Yu <honer...@gmail.com> wrote: > 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... > > Thanks > > > On Tue, Jun 1, 2010 at 4:25 PM, Chen Chien-Yu <honer...@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) >> c++; >> else if (*c == APR_ASCII_CR && *(c + 1) == APR_ASCII_LF) >> c += 2; >> else >> 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? */ >> apr_bucket_delete(e); >> } >> >> 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? >> >> Thanks >> >> Best regards, >> honercek >> >> On Mon, May 31, 2010 at 8:14 AM, Chen Chien-Yu <honer...@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<http://mail-archives.apache.org/mod_mbox/httpd-users/201005.mbox/%3caanlktiktxkb8cv-ezrkfman0gzs4c3-mw7v8kn1vy...@mail.gmail.com%3e>. >>> 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. >>> >>> Thanks >>> >>> Best regards, >>> honercek >>> >>> >>> On Fri, May 28, 2010 at 8:58 PM, William A. Rowe Jr. < >>> wr...@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? >>>> >>> >>> >> >