Mercurial > hg > nginx-quic
changeset 429:694cd6cdb714
nginx-0.0.11-2004-09-17-20:07:35 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 17 Sep 2004 16:07:35 +0000 |
parents | 5e73d0ea4dab |
children | 1fa5daf7558e |
files | src/core/ngx_palloc.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_header_filter.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/os/unix/ngx_writev_chain.c |
diffstat | 7 files changed, 128 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/src/core/ngx_palloc.c +++ b/src/core/ngx_palloc.c @@ -70,8 +70,9 @@ void *ngx_palloc(ngx_pool_t *pool, size_ ngx_pool_t *p, *n; ngx_pool_large_t *large, *last; - if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL) { - + if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL + && size <= (size_t) (pool->end - (char *) pool)) + { for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { m = ngx_align(p->last);
--- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -37,6 +37,7 @@ static char *ngx_set_server_name(ngx_con static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_set_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data); @@ -227,10 +228,10 @@ static ngx_command_t ngx_http_core_comm NULL }, { ngx_string("keepalive_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, + ngx_set_keepalive, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_core_loc_conf_t, keepalive_timeout), + 0, NULL }, { ngx_string("lingering_time"), @@ -1370,6 +1371,7 @@ static void *ngx_http_core_create_loc_co lcf->limit_rate = NGX_CONF_UNSET_SIZE; lcf->discarded_buffer_size = NGX_CONF_UNSET_SIZE; lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC; + lcf->keepalive_header = NGX_CONF_UNSET; lcf->lingering_time = NGX_CONF_UNSET_MSEC; lcf->lingering_timeout = NGX_CONF_UNSET_MSEC; lcf->reset_timedout_connection = NGX_CONF_UNSET; @@ -1457,7 +1459,9 @@ static char *ngx_http_core_merge_loc_con ngx_conf_merge_size_value(conf->discarded_buffer_size, prev->discarded_buffer_size, 1500); ngx_conf_merge_msec_value(conf->keepalive_timeout, - prev->keepalive_timeout, 70000); + prev->keepalive_timeout, 75000); + ngx_conf_merge_sec_value(conf->keepalive_header, + prev->keepalive_header, 0); ngx_conf_merge_msec_value(conf->lingering_time, prev->lingering_time, 30000); ngx_conf_merge_msec_value(conf->lingering_timeout, @@ -1711,6 +1715,44 @@ static char *ngx_set_error_page(ngx_conf } +static char *ngx_set_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_core_loc_conf_t *lcf = conf; + + ngx_str_t *value; + + if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) { + return "is duplicate"; + } + + value = cf->args->elts; + + lcf->keepalive_timeout = ngx_parse_time(&value[1], 0); + if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) { + return "invalid value"; + } + + if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) { + return "value must be less than 597 hours"; + } + + if (cf->args->nelts == 2) { + return NGX_CONF_OK; + } + + lcf->keepalive_header = ngx_parse_time(&value[2], 1); + if (lcf->keepalive_header == NGX_ERROR) { + return "invalid value"; + } + + if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) { + return "value must be less than 68 years"; + } + + return NGX_CONF_OK; +} + + static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *lcf = conf;
--- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -160,6 +160,7 @@ struct ngx_http_core_loc_conf_s { ngx_msec_t client_body_timeout; /* client_body_timeout */ ngx_msec_t send_timeout; /* send_timeout */ ngx_msec_t keepalive_timeout; /* keepalive_timeout */ + time_t keepalive_header; /* keepalive_timeout */ ngx_msec_t lingering_time; /* lingering_time */ ngx_msec_t lingering_timeout; /* lingering_timeout */
--- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -114,13 +114,14 @@ ngx_http_header_t ngx_http_headers_out[ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r) { - u_char *p; - size_t len; - ngx_uint_t status, i; - ngx_buf_t *b; - ngx_chain_t *ln; - ngx_list_part_t *part; - ngx_table_elt_t *header; + u_char *p; + size_t len; + ngx_uint_t status, i; + ngx_buf_t *b; + ngx_chain_t *ln; + ngx_list_part_t *part; + ngx_table_elt_t *header; + ngx_http_core_loc_conf_t *clcf; if (r->http_version < NGX_HTTP_VERSION_10) { return NGX_OK; @@ -222,8 +223,25 @@ static ngx_int_t ngx_http_header_filter( len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + if (r->keepalive) { len += sizeof("Connection: keep-alive" CRLF) - 1; + + /* + * MSIE and Opera ignore the "Keep-Alive: timeout=<N>" header. + * MSIE keeps the connection alive for about 60-65 seconds. + * Opera keeps the connection alive very long. + * Mozilla keeps the connection alive for N plus about 1-10 seconds. + * Konqueror keeps the connection alive for about N seconds. + */ + + if (clcf->keepalive_header + && (r->headers_in.gecko || r->headers_in.konqueror)) + { + len += sizeof("Keep-Alive: timeout=") - 1 + TIME_T_LEN + 2; + } + } else { len += sizeof("Connection: closed" CRLF) - 1; } @@ -243,11 +261,6 @@ static ngx_int_t ngx_http_header_filter( i = 0; } -#if 0 - header = r->headers_out.headers.elts; - for (i = 0; i < r->headers_out.headers.nelts; i++) { -#endif - if (header[i].key.len == 0) { continue; } @@ -357,6 +370,15 @@ static ngx_int_t ngx_http_header_filter( b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF, sizeof("Connection: keep-alive" CRLF) - 1); + if (clcf->keepalive_header + && (r->headers_in.gecko || r->headers_in.konqueror)) + { + b->last += ngx_snprintf((char *) b->last, + sizeof("Keep-Alive: timeout=") + TIME_T_LEN + 2, + "Keep-Alive: timeout=" TIME_T_FMT CRLF, + clcf->keepalive_header); + } + } else { b->last = ngx_cpymem(b->last, "Connection: close" CRLF, sizeof("Connection: close" CRLF) - 1); @@ -377,10 +399,6 @@ static ngx_int_t ngx_http_header_filter( i = 0; } -#if 0 - for (i = 0; i < r->headers_out.headers.nelts; i++) { -#endif - if (header[i].key.len == 0) { continue; }
--- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1023,7 +1023,7 @@ static ssize_t ngx_http_read_request_hea static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { - u_char *ua; + u_char *ua, *user_agent; size_t len; ngx_uint_t i; ngx_http_server_name_t *name; @@ -1126,13 +1126,14 @@ static ngx_int_t ngx_http_process_reques * in CPU cache */ - ua = (u_char *) ngx_strstr(r->headers_in.user_agent->value.data, - "MSIE"); - if (ua - && ua + 8 < r->headers_in.user_agent->value.data - + r->headers_in.user_agent->value.len) - { + user_agent = r->headers_in.user_agent->value.data; + + ua = (u_char *) ngx_strstr(user_agent, "MSIE"); + + if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) { + r->headers_in.msie = 1; + if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') { r->headers_in.msie4 = 1; } @@ -1144,11 +1145,21 @@ static ngx_int_t ngx_http_process_reques #endif } - if (ngx_strstr(r->headers_in.user_agent->value.data, "Opera")) { + if (ngx_strstr(user_agent, "Opera")) { r->headers_in.opera = 1; r->headers_in.msie = 0; r->headers_in.msie4 = 0; } + + if (!r->headers_in.msie && !r->headers_in.opera) { + + if (ngx_strstr(user_agent, "Gecko")) { + r->headers_in.gecko = 1; + + } else if (ngx_strstr(user_agent, "Konqueror")) { + r->headers_in.konqueror = 1; + } + } } return NGX_OK;
--- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -149,6 +149,8 @@ typedef struct { unsigned msie:1; unsigned msie4:1; unsigned opera:1; + unsigned gecko:1; + unsigned konqueror:1; } ngx_http_headers_in_t;
--- a/src/os/unix/ngx_writev_chain.c +++ b/src/os/unix/ngx_writev_chain.c @@ -4,17 +4,20 @@ #include <ngx_event.h> +#define NGX_IOVS 8 + + ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { - u_char *prev; - ssize_t n, size; - off_t send, sprev, sent; - struct iovec *iov; - ngx_uint_t eintr, complete; - ngx_err_t err; - ngx_array_t vec; - ngx_chain_t *cl; - ngx_event_t *wev; + u_char *prev; + ssize_t n, size; + off_t send, sprev, sent; + ngx_uint_t eintr, complete; + ngx_err_t err; + ngx_array_t vec; + ngx_chain_t *cl; + ngx_event_t *wev; + struct iovec *iov, iovs[NGX_IOVS]; wev = c->write; @@ -34,17 +37,22 @@ ngx_chain_t *ngx_writev_chain(ngx_connec #endif - ngx_init_array(vec, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); - send = 0; complete = 0; + vec.elts = iovs; + vec.size = sizeof(struct iovec); + vec.nalloc = NGX_IOVS; + vec.pool = c->pool; + for ( ;; ) { prev = NULL; iov = NULL; eintr = 0; sprev = send; + vec.nelts = 0; + /* create the iovec and coalesce the neighbouring bufs */ for (cl = in; cl && vec.nelts < IOV_MAX && send < limit; cl = cl->next) @@ -63,7 +71,10 @@ ngx_chain_t *ngx_writev_chain(ngx_connec iov->iov_len += size; } else { - ngx_test_null(iov, ngx_push_array(&vec), NGX_CHAIN_ERROR); + if (!(iov = ngx_array_push(&vec))) { + return NGX_CHAIN_ERROR; + } + iov->iov_base = (void *) cl->buf->pos; iov->iov_len = size; }