# HG changeset patch # User Igor Sysoev # Date 1081964668 0 # Node ID 39b6f2df45c0521b119bbd6e3b085f7681e66717 # Parent d71c87d11b16c47df6797daffd393ad6b137e15e nginx-0.0.3-2004-04-14-21:44:28 import diff --git a/auto/cc b/auto/cc --- a/auto/cc +++ b/auto/cc @@ -1,3 +1,5 @@ + +CFLAGS="$CFLAGS $CC_OPT" case $CC in diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -6,6 +6,7 @@ CPP= OBJS=objs DEBUG=NO +CC_OPT= CPU=NO TEST_BUILD_DEVPOLL=NO @@ -72,6 +73,7 @@ do --with-cc=*) CC="$value" ;; --with-cpp=*) CPP="$value" ;; + --with-cc-opt=*) CC_OPT="$value" ;; --with-cpu-opt=*) CPU="$value" ;; --with-debug) DEBUG=YES ;; diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -356,7 +356,11 @@ int ngx_epoll_process_events(ngx_cycle_t timer = ngx_event_find_timer(); ngx_old_elapsed_msec = ngx_elapsed_msec; - if (timer == 0) { + if (timer == -1) { + timer = 0; + expire = 1; + + } else if (timer == 0) { timer = (ngx_msec_t) -1; expire = 0; @@ -369,7 +373,9 @@ int ngx_epoll_process_events(ngx_cycle_t return NGX_ERROR; } - if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) { + if (ngx_accept_mutex_held == 0 + && (timer == -1 || timer > ngx_accept_mutex_delay)) + { timer = ngx_accept_mutex_delay; expire = 0; } diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -383,7 +383,12 @@ static ngx_int_t ngx_kqueue_process_even } } - if (timer) { + if (timer == -1) { + ts.tv_sec = 0; + ts.tv_nsec = 0; + tp = &ts; + + } else if (timer) { ts.tv_sec = timer / 1000; ts.tv_nsec = (timer % 1000) * 1000000; tp = &ts; diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -125,6 +125,8 @@ static int ngx_poll_add_event(ngx_event_ c = ev->data; + ev->active = 1; + if (ev->index != NGX_INVALID_INDEX) { ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "poll event fd:%d ev:%d is already set", c->fd, event); @@ -163,7 +165,6 @@ static int ngx_poll_add_event(ngx_event_ ev->index = e->index; } - ev->active = 1; ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; return NGX_OK; @@ -278,7 +279,11 @@ int ngx_poll_process_events(ngx_cycle_t } else { timer = ngx_event_find_timer(); - if (timer == 0) { + if (timer == -1) { + timer = 0; + expire = 1; + + } else if (timer == 0) { timer = (ngx_msec_t) INFTIM; expire = 0; @@ -302,7 +307,9 @@ int ngx_poll_process_events(ngx_cycle_t return NGX_ERROR; } - if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) { + if (ngx_accept_mutex_held == 0 + && (timer == (ngx_msec_t) INFTIM || timer > ngx_accept_mutex_delay)) + { timer = ngx_accept_mutex_delay; expire = 0; } @@ -348,8 +355,11 @@ int ngx_poll_process_events(ngx_cycle_t } } - if (timer == 0 && ready == 0) { + if ((ngx_event_flags & NGX_OVERFLOW_EVENT) && timer == 0 && ready == 0) { + /* the overflowed rt signals queue has been drained */ + + ngx_accept_mutex_unlock(); return NGX_OK; } diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -263,34 +263,26 @@ static int ngx_select_process_events(ngx static ngx_epoch_msec_t deltas = 0; #endif - work_read_fd_set = master_read_fd_set; - work_write_fd_set = master_write_fd_set; - timer = ngx_event_find_timer(); ngx_old_elapsed_msec = ngx_elapsed_msec; - if (timer) { - tv.tv_sec = timer / 1000; - tv.tv_usec = (timer % 1000) * 1000; - tp = &tv; - expire = 1; - - } else { - tp = NULL; - expire = 0; - } - -#if (NGX_DEBUG) - for (i = 0; i < nevents; i++) { - ev = event_index[i]; - c = ev->data; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "select event: fd:%d wr:%d", c->fd,ev->write); - } -#endif + expire = 1; #if !(WIN32) + if (ngx_accept_mutex) { + if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { + return NGX_ERROR; + } + + if (ngx_accept_mutex_held == 0 + && (timer == 0 || timer > ngx_accept_mutex_delay)) + { + timer = ngx_accept_mutex_delay; + expire = 0; + } + } + if (max_fd == -1) { for (i = 0; i < nevents; i++) { c = event_index[i]->data; @@ -303,22 +295,41 @@ static int ngx_select_process_events(ngx "change max_fd: %d", max_fd); } - if (ngx_accept_mutex) { - if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { - return NGX_ERROR; - } +#endif + +#if (NGX_DEBUG) + for (i = 0; i < nevents; i++) { + ev = event_index[i]; + c = ev->data; + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "select event: fd:%d wr:%d", c->fd, ev->write); + } +#endif - if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) { - timer = ngx_accept_mutex_delay; - expire = 0; - } + if (timer == -1) { + tv.tv_sec = 0; + tv.tv_usec = 0; + tp = &tv; + + } else if (timer) { + tv.tv_sec = timer / 1000; + tv.tv_usec = (timer % 1000) * 1000; + tp = &tv; + + } else { + tp = NULL; + expire = 0; } -#endif - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "select timer: %d", timer); + work_read_fd_set = master_read_fd_set; + work_write_fd_set = master_write_fd_set; + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "select read fd_set: %08X", *(int *) &work_read_fd_set); + #if (WIN32) ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); #else @@ -359,6 +370,7 @@ static int ngx_select_process_events(ngx if (ready == 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select() returned no events without timeout"); + ngx_accept_mutex_unlock(); return NGX_ERROR; } } @@ -381,6 +393,7 @@ static int ngx_select_process_events(ngx if (ready == 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select() returned no events without timeout"); + ngx_accept_mutex_unlock(); return NGX_ERROR; } } @@ -397,6 +410,7 @@ static int ngx_select_process_events(ngx ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, cycle->log, err, "select() failed"); #endif + ngx_accept_mutex_unlock(); return NGX_ERROR; } diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -402,6 +402,10 @@ ngx_int_t ngx_disable_accept_events(ngx_ */ if (ngx_event_flags & NGX_USE_SIGIO_EVENT) { + if (!cycle->connections[s[i].fd].read->active) { + continue; + } + if (ngx_del_conn(&cycle->connections[s[i].fd], NGX_DISABLE_EVENT) == NGX_ERROR) { @@ -409,6 +413,10 @@ ngx_int_t ngx_disable_accept_events(ngx_ } } else { + if (!cycle->read_events[s[i].fd].active) { + continue; + } + if (ngx_del_event(&cycle->read_events[s[i].fd], NGX_READ_EVENT, NGX_DISABLE_EVENT) == NGX_ERROR) { diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c --- a/src/event/ngx_event_posted.c +++ b/src/event/ngx_event_posted.c @@ -25,9 +25,6 @@ void ngx_event_process_posted(ngx_cycle_ return; } - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "posted event handler " PTR_FMT, ev->event_handler); - ngx_posted_events = ev->next; if (ev->accept) { diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -36,6 +36,7 @@ ngx_int_t ngx_event_timer_init(ngx_log_t ngx_msec_t ngx_event_find_timer(void) { + ngx_msec_t timer; ngx_rbtree_t *node; if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) { @@ -51,12 +52,14 @@ ngx_msec_t ngx_event_find_timer(void) ngx_mutex_unlock(ngx_event_timer_mutex); - return (ngx_msec_t) + timer = (ngx_msec_t) (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION); #if 0 (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec); #endif + + return timer > 0 ? timer: -1 ; } diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -12,10 +12,10 @@ /* * 32 bit timer key value resolution * - * 1 msec - 49 days - * 10 msec - 1 years 4 months - * 50 msec - 6 years 10 months - * 100 msec - 13 years 8 months + * 1 msec - 24 days + * 10 msec - 8 months + * 50 msec - 3 years 5 months + * 100 msec - 6 years 10 months */ #define NGX_TIMER_RESOLUTION 1 diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -96,10 +96,8 @@ static ngx_conf_enum_t ngx_http_gzip_ht static ngx_conf_enum_t ngx_http_gzip_proxied[] = { { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF }, -#if 0 { ngx_string("nocachable"), NGX_HTTP_GZIP_PROXIED_NOCACHABLE }, { ngx_string("poor_cachable"), NGX_HTTP_GZIP_PROXIED_POOR_CACHABLE }, -#endif { ngx_string("on"), NGX_HTTP_GZIP_PROXIED_ON }, { ngx_null_string, 0 } }; @@ -223,6 +221,7 @@ static ngx_http_output_body_filter_pt static int ngx_http_gzip_header_filter(ngx_http_request_t *r) { + time_t date, expires; ngx_http_gzip_ctx_t *ctx; ngx_http_gzip_conf_t *conf; @@ -250,9 +249,67 @@ static int ngx_http_gzip_header_filter(n } - /* TODO: proxied */ - if (r->headers_in.via && conf->proxied == NGX_HTTP_GZIP_PROXIED_OFF) { - return ngx_http_next_header_filter(r); + if (r->headers_in.via && conf->proxied != NGX_HTTP_GZIP_PROXIED_ON) { + + if (conf->proxied == NGX_HTTP_GZIP_PROXIED_OFF) { + return ngx_http_next_header_filter(r); + } + + if (r->headers_out.expires) { + expires = ngx_http_parse_time(r->headers_out.expires->value.data, + r->headers_out.expires->value.len); + if (expires == NGX_ERROR) { + return ngx_http_next_header_filter(r); + } + + if (r->headers_out.date) { + date = ngx_http_parse_time(r->headers_out.date->value.data, + r->headers_out.date->value.len); + if (date == NGX_ERROR) { + return ngx_http_next_header_filter(r); + } + + } else { + date = ngx_cached_time; + } + + if (expires >= date) { + return ngx_http_next_header_filter(r); + } + + } else if (r->headers_out.cache_control) { + + if (conf->proxied == NGX_HTTP_GZIP_PROXIED_NOCACHABLE) { + if (ngx_strstr(r->headers_out.cache_control->value.data, + "no-cache") == NULL) + { + return ngx_http_next_header_filter(r); + } + + } else { /* NGX_HTTP_GZIP_PROXIED_POOR_CACHABLE */ + + /* STUB: should be one cycle for all values */ + + if (ngx_strstr(r->headers_out.cache_control->value.data, + "no-cache") == NULL + && ngx_strstr(r->headers_out.cache_control->value.data, + "private") == NULL + && ngx_strstr(r->headers_out.cache_control->value.data, + "no-store") == NULL) + { + return ngx_http_next_header_filter(r); + } + } + + } else if (conf->proxied == NGX_HTTP_GZIP_PROXIED_NOCACHABLE) { + return ngx_http_next_header_filter(r); + + } else { /* NGX_HTTP_GZIP_PROXIED_POOR_CACHABLE */ + + if (r->headers_out.last_modified || r->headers_out.etag) { + return ngx_http_next_header_filter(r); + } + } } @@ -533,7 +590,7 @@ static int ngx_http_gzip_body_filter(ngx trailer->crc32 = ctx->crc32; trailer->zlen = ctx->zin; #else - /* STUB */ + /* STUB */ Oops ! #endif ctx->zstream.avail_in = 0; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -262,6 +262,7 @@ ngx_http_header_t ngx_http_proxy_headers { ngx_string("Expires"), offsetof(ngx_http_proxy_headers_in_t, expires) }, { ngx_string("Cache-Control"), offsetof(ngx_http_proxy_headers_in_t, cache_control) }, + { ngx_string("ETag"), offsetof(ngx_http_proxy_headers_in_t, etag) }, { ngx_string("X-Accel-Expires"), offsetof(ngx_http_proxy_headers_in_t, x_accel_expires) }, diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -114,6 +114,7 @@ typedef struct { ngx_table_elt_t *expires; ngx_table_elt_t *cache_control; + ngx_table_elt_t *etag; ngx_table_elt_t *x_accel_expires; ngx_table_elt_t *connection; diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c --- a/src/http/modules/proxy/ngx_http_proxy_header.c +++ b/src/http/modules/proxy/ngx_http_proxy_header.c @@ -20,6 +20,8 @@ int ngx_http_proxy_copy_header(ngx_http_ h = headers_in->headers.elts; for (i = 0; i < headers_in->headers.nelts; i++) { + /* ignore some headers */ + if (&h[i] == headers_in->connection) { continue; } @@ -51,12 +53,18 @@ int ngx_http_proxy_copy_header(ngx_http_ } } + + /* "Content-Type" is handled specially */ + if (&h[i] == headers_in->content_type) { r->headers_out.content_type = &h[i]; r->headers_out.content_type->key.len = 0; continue; } + + /* copy some header pointers and set up r->headers_out */ + if (!(ho = ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) { return NGX_ERROR; @@ -64,9 +72,30 @@ int ngx_http_proxy_copy_header(ngx_http_ *ho = h[i]; + if (&h[i] == headers_in->expires) { + r->headers_out.expires = ho; + continue; + } + + if (&h[i] == headers_in->cache_control) { + r->headers_out.cache_control = ho; + continue; + } + + if (&h[i] == headers_in->etag) { + r->headers_out.etag = ho; + continue; + } + + if (&h[i] == headers_in->last_modified) { + r->headers_out.last_modified = ho; + /* TODO: update r->headers_out.last_modified_time */ + continue; + } + /* - * ngx_http_header_filter() does not handle specially - * the following headers if they are set: + * ngx_http_header_filter() passes the following headers as is + * and does not handle them specially if they are set: * r->headers_out.server, * r->headers_out.date, * r->headers_out.content_length diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -338,9 +338,7 @@ static void ngx_http_proxy_init_upstream r->connection->read->event_handler = ngx_http_proxy_check_broken_connection; - if (ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT)) { - - /* kqueue allows to detect when client closes prematurely connection */ + if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { r->connection->write->event_handler = ngx_http_proxy_check_broken_connection; @@ -627,11 +625,6 @@ static void ngx_http_proxy_connect(ngx_h if (rc == NGX_AGAIN) { ngx_add_timer(c->write, p->lcf->connect_timeout); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http proxy connect handler: " PTR_FMT, - c->write->event_handler); - return; } diff --git a/src/http/ngx_http_headers.c b/src/http/ngx_http_headers.c --- a/src/http/ngx_http_headers.c +++ b/src/http/ngx_http_headers.c @@ -53,6 +53,10 @@ ngx_http_header_t ngx_http_headers_out[ offsetof(ngx_http_headers_out_t, last_modified) }, { ngx_string("Accept-Ranges"), offsetof(ngx_http_headers_out_t, accept_ranges) }, + { ngx_string("Expires"), offsetof(ngx_http_headers_out_t, expires) }, + { ngx_string("Cache-Control"), + offsetof(ngx_http_headers_out_t, cache_control) }, + { ngx_string("ETag"), offsetof(ngx_http_headers_out_t, etag) }, { ngx_null_string, 0 } }; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -140,12 +140,14 @@ typedef struct { ngx_table_elt_t *last_modified; ngx_table_elt_t *content_range; ngx_table_elt_t *accept_ranges; + ngx_table_elt_t *expires; + ngx_table_elt_t *cache_control; + ngx_table_elt_t *etag; ngx_str_t charset; ngx_array_t ranges; off_t content_length_n; - u_char *etag; time_t date_time; time_t last_modified_time; } ngx_http_headers_out_t; diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -82,13 +82,13 @@ void ngx_master_process_cycle(ngx_cycle_ /* * we have to limit the maximum life time of the worker processes - * by 1 month because our millisecond event timer is limited - * by 49 days on 32-bit platforms + * by 10 days because our millisecond event timer is limited + * by 24 days on 32-bit platforms */ itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = 0; - itv.it_value.tv_sec = 30 * 24 * 60 * 60; + itv.it_value.tv_sec = 10 * 24 * 60 * 60; itv.it_value.tv_usec = 0; if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -8,7 +8,7 @@ typedef uint64_t ngx_epoch_msec_t; -typedef u_int ngx_msec_t; +typedef ngx_int_t ngx_msec_t; #define NGX_MAX_MSEC (ngx_msec_t) -1 typedef struct tm ngx_tm_t; diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h --- a/src/os/win32/ngx_time.h +++ b/src/os/win32/ngx_time.h @@ -8,7 +8,7 @@ typedef uint64_t ngx_epoch_msec_t; -typedef u_int ngx_msec_t; +typedef ngx_int_t ngx_msec_t; #define NGX_MAX_MSEC (ngx_msec_t) -1