diff options
author | Sascha Schumann <sas@php.net> | 2002-07-14 18:01:08 +0000 |
---|---|---|
committer | Sascha Schumann <sas@php.net> | 2002-07-14 18:01:08 +0000 |
commit | fa3d840cd1a5c23bc1757703f91c0af18b09ec65 (patch) | |
tree | 49a56f61598d3c134eda0d00cc5e197037ccfceb /sapi/thttpd/thttpd.c | |
parent | 6d992a9f0ddef2c7a07bf8ec7679c8df8d0b32b2 (diff) | |
download | php-git-fa3d840cd1a5c23bc1757703f91c0af18b09ec65.tar.gz |
integrate the public keep-alive patch
the patch did not handle pipeling at all, so that some code had to be added
from Premium thttpd
persistent connections are supported, if a script sets the Content-Length
header
Diffstat (limited to 'sapi/thttpd/thttpd.c')
-rw-r--r-- | sapi/thttpd/thttpd.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/sapi/thttpd/thttpd.c b/sapi/thttpd/thttpd.c index 23266d26f7..1cda5a34f4 100644 --- a/sapi/thttpd/thttpd.c +++ b/sapi/thttpd/thttpd.c @@ -41,6 +41,8 @@ typedef struct { long async_send; smart_str sbuf; + int seen_cl; + int seen_cn; } php_thttpd_globals; @@ -69,12 +71,13 @@ static int sapi_thttpd_ub_write(const char *str, uint str_length TSRMLS_DC) while (str_length > 0) { n = send(TG(hc)->conn_fd, str, str_length, 0); - if (n == -1 && errno == EPIPE) - php_handle_aborted_connection(); - if (n == -1 && errno == EAGAIN) { - smart_str_appendl_ex(&TG(sbuf), str, str_length, 1); + if (n == -1) { + if (errno == EAGAIN) { + smart_str_appendl_ex(&TG(sbuf), str, str_length, 1); - return sent + str_length; + return sent + str_length; + } else + php_handle_aborted_connection(); } TG(hc)->bytes_sent += n; @@ -143,6 +146,12 @@ static int do_writev(struct iovec *vec, int nvec, int len TSRMLS_DC) return 0; } +#define CL_TOKEN "Content-length: " +#define CN_TOKEN "Connection: " +#define KA_DO "Connection: keep-alive\r\n" +#define KA_NO "Connection: close\r\n" +#define DEF_CT "Content-Type: text/html\r\n" + static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) { char buf[1024]; @@ -153,7 +162,7 @@ static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) size_t len = 0; if (!SG(sapi_headers).http_status_line) { - sprintf(buf, "HTTP/1.0 %d Code\r\n", /* SAFE */ + sprintf(buf, "HTTP/1.1 %d Code\r\n", /* SAFE */ SG(sapi_headers).http_response_code); ADD_VEC(buf, strlen(buf)); } else { @@ -163,14 +172,22 @@ static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) } TG(hc)->status = SG(sapi_headers).http_response_code; -#define DEF_CT "Content-Type: text/html\r\n" - if (SG(sapi_headers).send_default_content_type) { ADD_VEC(DEF_CT, strlen(DEF_CT)); } h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); while (h) { + + switch (h->header[0]) { + case 'c': case 'C': + if (!TG(seen_cl) && strncasecmp(h->header, CL_TOKEN, sizeof(CL_TOKEN)-1) == 0) { + TG(seen_cl) = 1; + } else if (!TG(seen_cn) && strncasecmp(h->header, CN_TOKEN, sizeof(CN_TOKEN)-1) == 0) { + TG(seen_cn) = 1; + } + } + ADD_VEC(h->header, h->header_len); if (n >= COMBINE_HEADERS - 1) { len = do_writev(vec, n, len TSRMLS_CC); @@ -180,6 +197,12 @@ static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); } + + if (TG(seen_cl) && !TG(seen_cn) && TG(hc)->do_keep_alive) { + ADD_VEC(KA_DO, sizeof(KA_DO)-1); + } else { + ADD_VEC(KA_NO, sizeof(KA_NO)-1); + } ADD_VEC("\r\n", 2); @@ -392,6 +415,8 @@ static void thttpd_request_ctor(TSRMLS_D) { smart_str s = {0}; + TG(seen_cl) = 0; + TG(seen_cn) = 0; TG(sbuf).c = 0; SG(request_info).query_string = TG(hc)->query?strdup(TG(hc)->query):NULL; @@ -612,8 +637,14 @@ static off_t thttpd_real_php_request(httpd_conn *hc TSRMLS_DC) thttpd_module_main(TSRMLS_C); + /* disable kl, if no content-length was seen or Connection: was set */ + if (TG(seen_cl) == 0 || TG(seen_cn) == 1) { + TG(hc)->do_keep_alive = TG(hc)->keep_alive = 0; + } + if (TG(sbuf).c != 0) { - free(TG(hc)->response); + if (TG(hc)->response) + free(TG(hc)->response); TG(hc)->response = TG(sbuf).c; TG(hc)->responselen = TG(sbuf).len; |