ID: 44393 Comment by: Richard dot Krehbiel at gmail dot com Reported By: richard dot krehbiel at gmail dot com Status: Open Bug Type: Feature/Change Request Operating System: Windows PHP Version: 5.2.5 New Comment:
To alleviate SSL session setup/takedown costs, the "Keep-Alive" allows a single socket connection to be used for multiple transactions. However, for simplicity of implementation, the original php5isapi module did not allow keep-alive. This patch allows Keep-Alive by implementing "Transfer-Encoding: chunked" (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.41). Previous Comments: ------------------------------------------------------------------------ [2008-03-27 13:54:11] [EMAIL PROTECTED] Note: I deleted your other comments since they only had that badly formatted patch, so please add some information what your patch exactly does. ------------------------------------------------------------------------ [2008-03-27 13:24:07] Richard dot Krehbiel at gmail dot com I haven't been paying attention. The patch is badly word-wrapped, and so doesn't apply. Here's a link to an unformatted plain-text version: http://home.comcast.net/~krehbiel3/php5isapi.c.patch ------------------------------------------------------------------------ [2008-03-10 14:53:18] richard dot krehbiel at gmail dot com 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 this bug report at http://bugs.php.net/?id=44393&edit=1