|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2008-03-27 13:24 UTC] Richard dot Krehbiel at gmail dot com
[2008-03-27 13:54 UTC] jani@php.net
[2008-03-27 14:27 UTC] Richard dot Krehbiel at gmail dot com
[2008-03-28 13:55 UTC] Richard dot Krehbiel at gmail dot com
[2011-04-08 21:05 UTC] jani@php.net
-Package: Feature/Change Request
+Package: IIS related
[2021-02-11 17:40 UTC] cmb@php.net
-Status: Open
+Status: Closed
-Assigned To:
+Assigned To: cmb
[2021-02-11 17:40 UTC] cmb@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 23:00:01 2025 UTC |
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; }