From: richard dot krehbiel at gmail dot com Operating system: Windows PHP version: 5.2.5 PHP Bug Type: IIS related Bug description: No support for Keep-Alive connections under IIS
Description: ------------ The ISAPI module for PHP does not support "Keep-Alive" connections. I have a modified sapi/isapi/php5isapi.c that adds "Transfer-Encoding: chunked" support, which allows keep-alive to work. It works but needs polish*. Interested? *It needs to detect the presence of a "Content-Length" header and disable "chunked"; it needs buffering (every little 1-char echo becomes a chunk); I think it doesn't work with dynamic compression. --- /mnt/rich3/c/php-5.2.5/sapi/isapi/php5isapi.c 2007-02-23 17:08:30.000000000 -0500 +++ /mnt/rich3/c/buildphp/php-5.2.5/sapi/isapi/php5isapi.c 2008-03-10 10:46:17.317923500 -0400 @@ -206,10 +206,25 @@ { DWORD num_bytes = str_length; LPEXTENSION_CONTROL_BLOCK ecb; + // Chunked write... + char chunksize[16]; + uint chunksizelen; ecb = (LPEXTENSION_CONTROL_BLOCK) SG(server_context); - if (ecb->WriteClient(ecb->ConnID, (char *) str, &num_bytes, HSE_IO_SYNC) == FALSE) { - php_handle_aborted_connection(); + + if(str_length > 0) { + uint two = 2; + _snprintf(chunksize, sizeof(chunksize), "%lX\r\n", str_length); + chunksizelen = strlen(chunksize); + if (ecb->WriteClient(ecb->ConnID, chunksize, &chunksizelen, HSE_IO_SYNC) == FALSE) { + php_handle_aborted_connection(); + } + if (ecb->WriteClient(ecb->ConnID, (char *) str, &num_bytes, HSE_IO_SYNC) == FALSE) { + php_handle_aborted_connection(); + } + if (ecb->WriteClient(ecb->ConnID, "\r\n", &two, HSE_IO_SYNC) == FALSE) { + php_handle_aborted_connection(); + } } return num_bytes; } @@ -256,16 +271,14 @@ zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) accumulate_header_length, (void *) &total_length TSRMLS_CC); /* Generate headers */ - combined_headers = (char *) emalloc(total_length+1); + combined_headers = (char *) emalloc(total_length+64); combined_headers_ptr = combined_headers; if (SG(sapi_headers).send_default_content_type) { concat_header(&default_content_type, (void *) &combined_headers_ptr TSRMLS_CC); sapi_free_header(&default_content_type); /* we no longer need it */ } zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) concat_header, (void *) &combined_headers_ptr TSRMLS_CC); - *combined_headers_ptr++ = '\r'; - *combined_headers_ptr++ = '\n'; - *combined_headers_ptr = 0; + strcpy(combined_headers_ptr, "Transfer-Encoding: chunked\r\n\r\n"); switch (SG(sapi_headers).http_response_code) { case 200: @@ -300,7 +313,7 @@ header_info.cchStatus = strlen(header_info.pszStatus); header_info.pszHeader = combined_headers; header_info.cchHeader = total_length; - header_info.fKeepConn = FALSE; + header_info.fKeepConn = TRUE; lpECB->dwHttpStatusCode = SG(sapi_headers).http_response_code; lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL); @@ -928,6 +941,15 @@ return HSE_STATUS_ERROR; } zend_end_try(); + // Finish a chunked transmission, send 0 length EOF chunk and trailing headers (none) + + { + uint five = 5; + if (lpECB->WriteClient(lpECB->ConnID, "0\r\n\r\n", &five, HSE_IO_SYNC) == FALSE) { + php_handle_aborted_connection(); + } + } + return HSE_STATUS_SUCCESS; } -- Edit bug report at http://bugs.php.net/?id=44393&edit=1 -- Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=44393&r=trysnapshot52 Try a CVS snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=44393&r=trysnapshot53 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=44393&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=44393&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=44393&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=44393&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=44393&r=needscript Try newer version: http://bugs.php.net/fix.php?id=44393&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=44393&r=support Expected behavior: http://bugs.php.net/fix.php?id=44393&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=44393&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=44393&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=44393&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=44393&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=44393&r=dst IIS Stability: http://bugs.php.net/fix.php?id=44393&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=44393&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=44393&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=44393&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=44393&r=mysqlcfg