# HG changeset patch # User Igor Sysoev # Date 1067503866 0 # Node ID 389d7ee9fa60009dc12ef9cfd875d9f9af1f9d90 # Parent 894a01c6aea30f1f74b69459651abacecd103eb1 nginx-0.0.1-2003-10-30-11:51:06 import diff -r 894a01c6aea3 -r 389d7ee9fa60 src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/core/ngx_conf_file.c Thu Oct 30 08:51:06 2003 +0000 @@ -61,7 +61,7 @@ } ngx_test_null(cf->conf_file->hunk, - ngx_create_temp_hunk(cf->pool, 1024, 0, 0), + ngx_create_temp_hunk(cf->pool, 1024), NGX_CONF_ERROR); cf->conf_file->file.fd = fd; @@ -722,7 +722,7 @@ char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - char *p = conf; + char *p = conf; ngx_str_t *value; ngx_bufs_t *bufs; @@ -749,6 +749,51 @@ } +char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *p = conf; + + int *np, i, m; + ngx_str_t *value; + ngx_conf_bitmask_t *mask; + + + np = (int *) (p + cmd->offset); + value = (ngx_str_t *) cf->args->elts; + mask = cmd->post; + + for (i = 1; i < cf->args->nelts; i++) { + for (m = 0; mask[m].name.len != 0; m++) { + + if (mask[m].name.len != value[i].len + && ngx_strcasecmp(mask[m].name.data, value[i].data) != 0) + { + continue; + } + + if (*np & mask[m].mask) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "duplicate value \"%s\"", value[i].data); + + } else { + *np |= mask[m].mask; + } + + break; + } + + if (mask[m].name.len == 0) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "invalid value \"%s\"", value[i].data); + + return NGX_CONF_ERROR; + } + } + + return NGX_CONF_OK; +} + + char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { return "unsupported on this platform"; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h Wed Oct 29 17:39:05 2003 +0000 +++ b/src/core/ngx_conf_file.h Thu Oct 30 08:51:06 2003 +0000 @@ -150,6 +150,12 @@ } ngx_conf_num_bounds_t; +typedef struct { + ngx_str_t name; + int mask; +} ngx_conf_bitmask_t; + + char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data); @@ -214,6 +220,11 @@ } \ } +#define ngx_conf_merge_bitmask_value(conf, prev, default) \ + if (conf == 0) { \ + conf = (prev == 0) ? default : prev; \ + } + #define addressof(addr) ((int) &addr) @@ -233,6 +244,7 @@ char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_conf_set_core_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); diff -r 894a01c6aea3 -r 389d7ee9fa60 src/core/ngx_hunk.c --- a/src/core/ngx_hunk.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/core/ngx_hunk.c Thu Oct 30 08:51:06 2003 +0000 @@ -3,19 +3,21 @@ #include -ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size, - int before, int after) +ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size) { ngx_hunk_t *h; - ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL); + ngx_test_null(h, ngx_alloc_hunk(pool), NULL); - ngx_test_null(h->pre_start, ngx_palloc(pool, size + before + after), NULL); + ngx_test_null(h->start, ngx_palloc(pool, size), NULL); - h->start = h->pos = h->last = h->pre_start + before; - h->file_pos = h->file_last = 0; + h->pos = h->start; + h->last = h->start; + + h->file_pos = 0; + h->file_last = 0; + h->end = h->last + size; - h->post_end = h->end + after; h->type = NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY; h->file = NULL; @@ -68,80 +70,6 @@ } -ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size) -{ - ngx_hunk_t *h; - - ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL); - - if (hunk->type & NGX_HUNK_TEMP && hunk->pos - hunk->pre_start >= size) { - /* keep hunk->start unchanged - used in restore */ - h->pre_start = hunk->pre_start; - h->end = h->post_end = hunk->pre_start = hunk->pos; - h->start = h->pos = h->last = h->end - size; - h->file_pos = h->file_last = 0; - - h->type = NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY; - h->file = NULL; - h->shadow = NULL; - - h->tag = 0; - - } else { - ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL); - h->start = h->pos = h->last = h->pre_start; - h->end = h->post_end = h->start + size; - h->file_pos = h->file_last = 0; - - h->type = NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY; - h->file = NULL; - h->shadow = NULL; - - h->tag = 0; - } - - return h; -} - - -ngx_hunk_t *ngx_create_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size) -{ - ngx_hunk_t *h; - - ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL); - - if (hunk->type & NGX_HUNK_TEMP - && hunk->last == hunk->end - && hunk->post_end - hunk->end >= size) - { - h->post_end = hunk->post_end; - h->pre_start = h->start = h->pos = h->last = hunk->post_end = - hunk->last; - h->file_pos = h->file_last = 0; - - h->type = NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY; - h->file = NULL; - h->shadow = NULL; - - h->tag = 0; - - } else { - ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL); - h->start = h->pos = h->last = h->pre_start; - h->end = h->post_end = h->start + size; - h->file_pos = h->file_last = 0; - - h->type = NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY; - h->file = NULL; - h->shadow = NULL; - - h->tag = 0; - } - - return h; -} - - int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in) { ngx_chain_t *cl, **ll; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/core/ngx_hunk.h --- a/src/core/ngx_hunk.h Wed Oct 29 17:39:05 2003 +0000 +++ b/src/core/ngx_hunk.h Thu Oct 30 08:51:06 2003 +0000 @@ -50,8 +50,6 @@ int type; char *start; /* start of hunk */ char *end; /* end of hunk */ - char *pre_start; /* start of pre-allocated hunk */ - char *post_end; /* end of post-allocated hunk */ ngx_hunk_tag_t tag; ngx_file_t *file; ngx_hunk_t *shadow; @@ -100,7 +98,7 @@ ngx_chain_t **last; ngx_connection_t *connection; ngx_pool_t *pool; -} ngx_chain_write_ctx_t; +} ngx_chain_writer_ctx_t; #define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR @@ -123,8 +121,7 @@ (size_t) (h->file_last - h->file_pos)) -ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size, - int before, int after); +ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size); #define ngx_alloc_hunk(pool) ngx_palloc(pool, sizeof(ngx_hunk_t)) #define ngx_calloc_hunk(pool) ngx_pcalloc(pool, sizeof(ngx_hunk_t)) @@ -151,7 +148,7 @@ int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in); -int ngx_chain_write(void *data, ngx_chain_t *in); +int ngx_chain_writer(void *data, ngx_chain_t *in); int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in); void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy, diff -r 894a01c6aea3 -r 389d7ee9fa60 src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/core/ngx_output_chain.c Thu Oct 30 08:51:06 2003 +0000 @@ -108,7 +108,7 @@ } ngx_test_null(ctx->hunk, - ngx_create_temp_hunk(ctx->pool, size, 0, 0), + ngx_create_temp_hunk(ctx->pool, size), NGX_ERROR); ctx->hunk->tag = ctx->tag; ctx->hunk->type |= NGX_HUNK_RECYCLED; @@ -253,9 +253,9 @@ } -int ngx_chain_write(void *data, ngx_chain_t *in) +int ngx_chain_writer(void *data, ngx_chain_t *in) { - ngx_chain_write_ctx_t *ctx = data; + ngx_chain_writer_ctx_t *ctx = data; ngx_chain_t *cl; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/event/modules/ngx_kqueue_module.c Thu Oct 30 08:51:06 2003 +0000 @@ -437,8 +437,8 @@ break; case EVFILT_AIO: - ev->aio_complete = 1; - ev->active = 0; + ev->complete = 1; + ev->ready = 1; ev->event_handler(ev); diff -r 894a01c6aea3 -r 389d7ee9fa60 src/event/ngx_event.h --- a/src/event/ngx_event.h Wed Oct 29 17:39:05 2003 +0000 +++ b/src/event/ngx_event.h Thu Oct 30 08:51:06 2003 +0000 @@ -61,18 +61,15 @@ /* * the event was passed or would be passed to a kernel; - * aio mode: 1 - the posted aio operation, - * 0 - the complete aio operation or no aio operation. + * in aio mode - operation was posted. */ unsigned active:1; - /* - * the ready event; - * in aio mode "ready" is always set - it makes things simple - * to learn whether the aio operation complete use aio_complete flag - */ + /* the ready event; in aio mode 0 means that no operation can be posted */ unsigned ready:1; - unsigned aio_complete:1; + + /* aio operation is complete */ + unsigned complete:1; unsigned eof:1; unsigned error:1; @@ -89,12 +86,20 @@ unsigned deferred_accept:1; + /* TODO: aio_eof and kq_eof can be the single pending_eof */ + /* the pending eof in aio chain operation */ + unsigned aio_eof:1; + + /* the pending eof reported by kqueue */ + unsigned kq_eof:1; + #if (WIN32) + /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was succesfull */ unsigned accept_context_updated:1; #endif #if (HAVE_KQUEUE) - unsigned kq_eof:1; + /* the pending errno reported by kqueue */ int kq_errno; #endif diff -r 894a01c6aea3 -r 389d7ee9fa60 src/event/ngx_event_acceptex.c --- a/src/event/ngx_event_acceptex.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/event/ngx_event_acceptex.c Thu Oct 30 08:51:06 2003 +0000 @@ -120,6 +120,9 @@ wev->write = 1; rev->event_handler = ngx_event_acceptex; + rev->ready = 1; + wev->ready = 1; + ngx_test_null(c->pool, ngx_create_pool(ls->pool_size, ls->log), NGX_ERROR); @@ -127,8 +130,7 @@ ngx_test_null(c->buffer, ngx_create_temp_hunk(c->pool, ls->post_accept_buffer_size - + 2 * (c->listening->socklen + 16), - 0, 0), + + 2 * (c->listening->socklen + 16)), NGX_ERROR); ngx_test_null(c->local_sockaddr, ngx_palloc(c->pool, ls->socklen), diff -r 894a01c6aea3 -r 389d7ee9fa60 src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/event/ngx_event_connect.c Thu Oct 30 08:51:06 2003 +0000 @@ -204,12 +204,13 @@ if (ngx_event_flags & NGX_USE_AIO_EVENT) { /* aio, iocp */ - rev->ready = 1; #if 1 /* TODO: NGX_EINPROGRESS */ + rev->ready = 1; wev->ready = 1; + return NGX_OK; #endif } diff -r 894a01c6aea3 -r 389d7ee9fa60 src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/event/ngx_event_pipe.c Thu Oct 30 08:51:06 2003 +0000 @@ -101,71 +101,52 @@ } else { -#if (HAVE_KQUEUE) - /* * kqueue notifies about the end of file or a pending error. * This test allows not to allocate a hunk on these conditions * and not to call ngx_recv_chain(). */ - if (ngx_event_flags == NGX_HAVE_KQUEUE_EVENT) { - - if (p->upstream->read->available == 0) { - if (p->upstream->read->kq_eof) { - p->upstream->read->ready = 0; - p->upstream->read->eof = 0; - p->upstream_eof = 1; - p->read = 1; + if (p->upstream->read->available == 0 + && (p->upstream->read->kq_eof || p->upstream->read->aio_eof)) + { + p->upstream->read->ready = 0; + p->upstream->read->eof = 0; + p->upstream_eof = 1; + p->read = 1; - if (p->upstream->read->kq_errno) { - p->upstream->read->error = 1; - p->upstream_error = 1; - p->upstream_eof = 0; +#if (HAVE_KQUEUE) + if (p->upstream->read->kq_errno) { + p->upstream->read->error = 1; + p->upstream_error = 1; + p->upstream_eof = 0; - ngx_log_error(NGX_LOG_ERR, p->log, - p->upstream->read->kq_errno, - "readv() failed"); - } - - break; - } - } - -#if 0 - if (p->upstream->read->kq_errno) { ngx_log_error(NGX_LOG_ERR, p->log, p->upstream->read->kq_errno, "readv() failed"); - p->upstream_error = 1; - - break; - - } else if (p->upstream->read->kq_eof - && p->upstream->read->available == 0) { - p->upstream_eof = 1; - p->read = 1; - - break; } #endif + break; } -#endif if (p->free_raw_hunks) { /* use the free hunks if they exist */ chain = p->free_raw_hunks; - p->free_raw_hunks = NULL; + if (p->single_buf) { + p->free_raw_hunks = p->free_raw_hunks->next; + chain->next = NULL; + } else { + p->free_raw_hunks = NULL; + } } else if (p->hunks < p->bufs.num) { /* allocate a new hunk if it's still allowed */ - ngx_test_null(h, ngx_create_temp_hunk(p->pool, - p->bufs.size, 0, 0), + ngx_test_null(h, ngx_create_temp_hunk(p->pool, p->bufs.size), NGX_ABORT); p->hunks++; @@ -214,7 +195,12 @@ } chain = p->free_raw_hunks; - p->free_raw_hunks = NULL; + if (p->single_buf) { + p->free_raw_hunks = p->free_raw_hunks->next; + chain->next = NULL; + } else { + p->free_raw_hunks = NULL; + } } else { @@ -229,6 +215,9 @@ ngx_log_debug(p->log, "recv_chain: %d" _ n); + if (p->free_raw_hunks) { + chain->next = p->free_raw_hunks; + } p->free_raw_hunks = chain; if (n == NGX_ERROR) { @@ -237,6 +226,10 @@ } if (n == NGX_AGAIN) { + if (p->single_buf) { + ngx_event_pipe_remove_shadow_links(chain->hunk); + } + break; } @@ -283,8 +276,11 @@ return NGX_ABORT; } - /* TODO: p->free_raw_hunk->next can be free()ed */ p->free_raw_hunks = p->free_raw_hunks->next; + + for (cl = p->free_raw_hunks; cl; cl = cl->next) { + ngx_pfree(p->pool, cl->hunk->start); + } } if (p->cachable && p->in) { diff -r 894a01c6aea3 -r 389d7ee9fa60 src/event/ngx_event_pipe.h --- a/src/event/ngx_event_pipe.h Wed Oct 29 17:39:05 2003 +0000 +++ b/src/event/ngx_event_pipe.h Thu Oct 30 08:51:06 2003 +0000 @@ -38,6 +38,7 @@ unsigned read:1; unsigned cachable:1; + unsigned single_buf:1; unsigned upstream_done:1; unsigned upstream_error:1; unsigned upstream_eof:1; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/http/modules/ngx_http_gzip_filter.c --- a/src/http/modules/ngx_http_gzip_filter.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/http/modules/ngx_http_gzip_filter.c Thu Oct 30 08:51:06 2003 +0000 @@ -190,9 +190,9 @@ sizeof(ngx_http_gzip_ctx_t), NGX_ERROR); ctx->request = r; - if (!(r->headers_out.content_encoding = - ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) - { + r->headers_out.content_encoding = + ngx_http_add_header(&r->headers_out, ngx_http_headers_out); + if (r->headers_out.content_encoding == NULL) { return NGX_ERROR; } @@ -222,9 +222,7 @@ ngx_http_gzip_ctx_t *ctx; ngx_http_gzip_conf_t *conf; - ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module); - - if (ctx == NULL) { + if (!(ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module))) { return ngx_http_next_body_filter(r, in); } @@ -344,9 +342,8 @@ } else if (ctx->hunks < conf->bufs.num) { ngx_test_null(ctx->out_hunk, - ngx_create_temp_hunk(r->pool, conf->bufs.size, - 0, 0), - ngx_http_gzip_error(ctx)); + ngx_create_temp_hunk(r->pool, conf->bufs.size), + ngx_http_gzip_error(ctx)); ctx->out_hunk->tag = (ngx_hunk_tag_t) &ngx_http_gzip_filter_module; ctx->out_hunk->type |= NGX_HUNK_RECYCLED; @@ -429,7 +426,7 @@ } else { ngx_test_null(h, - ngx_create_temp_hunk(r->pool, 8, 0, 0), + ngx_create_temp_hunk(r->pool, 8), ngx_http_gzip_error(ctx)); h->type |= NGX_HUNK_LAST; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c Thu Oct 30 08:51:06 2003 +0000 @@ -38,86 +38,101 @@ ngx_http_proxy_upstream_t *u); -static ngx_command_t ngx_http_proxy_commands[] = { +static ngx_conf_bitmask_t next_upstream_masks[] = { + { ngx_string("error"), NGX_HTTP_PROXY_FT_ERROR }, + { ngx_string("timeout"), NGX_HTTP_PROXY_FT_TIMEOUT }, + { ngx_string("http_header"), NGX_HTTP_PROXY_FT_HTTP_HEADER }, + { ngx_string("http_500"), NGX_HTTP_PROXY_FT_HTTP_500 }, + { ngx_null_string, 0 } +}; - {ngx_string("proxy_pass"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_http_proxy_set_pass, - NGX_HTTP_LOC_CONF_OFFSET, - 0, - NULL}, +static ngx_command_t ngx_http_proxy_commands[] = { - {ngx_string("proxy_request_buffer_size"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, request_buffer_size), - NULL}, + { ngx_string("proxy_pass"), + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_proxy_set_pass, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, - {ngx_string("proxy_connect_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, connect_timeout), - NULL}, + { ngx_string("proxy_request_buffer_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, request_buffer_size), + NULL }, + + { ngx_string("proxy_connect_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, connect_timeout), + NULL }, - {ngx_string("proxy_send_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, send_timeout), - NULL}, + { ngx_string("proxy_send_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, send_timeout), + NULL }, - {ngx_string("proxy_header_buffer_size"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, header_buffer_size), - NULL}, + { ngx_string("proxy_header_buffer_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, header_buffer_size), + NULL }, - {ngx_string("proxy_read_timeout"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, read_timeout), - NULL}, + { ngx_string("proxy_read_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, read_timeout), + NULL }, - {ngx_string("proxy_buffers"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, - ngx_conf_set_bufs_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, bufs), - NULL}, + { ngx_string("proxy_buffers"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, + ngx_conf_set_bufs_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, bufs), + NULL }, - {ngx_string("proxy_busy_buffers_size"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size), - NULL}, + { ngx_string("proxy_busy_buffers_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size), + NULL }, - {ngx_string("proxy_temp_path"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, - ngx_conf_set_path_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, temp_path), - NULL}, + { ngx_string("proxy_temp_path"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, + ngx_conf_set_path_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, temp_path), + NULL }, + + { ngx_string("proxy_temp_file_write_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size), + NULL }, - {ngx_string("proxy_temp_file_write_size"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size), - NULL}, + { ngx_string("proxy_pass_server"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, pass_server), + NULL }, - {ngx_string("proxy_pass_server"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, pass_server), - NULL}, + { ngx_string("proxy_next_upstream"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, + ngx_conf_set_bitmask_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, next_upstream), + &next_upstream_masks }, - ngx_null_command + ngx_null_command }; @@ -231,8 +246,8 @@ ngx_chain_t *cl; ngx_http_request_t *r; - ngx_output_chain_ctx_t *out_ctx; - ngx_chain_write_ctx_t *write_ctx; + ngx_output_chain_ctx_t *octx; + ngx_chain_writer_ctx_t *wctx; r = p->request; @@ -262,38 +277,38 @@ r->connection->log->handler = ngx_http_proxy_log_error; p->action = "connecting to upstream"; - out_ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); - if (out_ctx == NULL) { + octx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); + if (octx == NULL) { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } - p->output_chain_ctx = out_ctx; + p->output_chain_ctx = octx; if (r->request_body_hunk) { - out_ctx->free = ngx_alloc_chain_link(r->pool); - if (out_ctx->free == NULL) { + octx->free = ngx_alloc_chain_link(r->pool); + if (octx->free == NULL) { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); } - out_ctx->free->hunk = r->request_body_hunk; - out_ctx->free->next = NULL; + octx->free->hunk = r->request_body_hunk; + octx->free->next = NULL; } - out_ctx->sendfile = r->sendfile; - out_ctx->pool = r->pool; - out_ctx->bufs.num = 1; - out_ctx->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; - out_ctx->output_filter = (ngx_output_chain_filter_pt) ngx_chain_write; + octx->sendfile = r->sendfile; + octx->pool = r->pool; + octx->bufs.num = 1; + octx->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; + octx->output_filter = (ngx_output_chain_filter_pt) ngx_chain_writer; - write_ctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_write_ctx_t)); - if (write_ctx == NULL) { + wctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_writer_ctx_t)); + if (wctx == NULL) { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } - out_ctx->output_ctx = write_ctx; - write_ctx->pool = r->pool; - write_ctx->last = &write_ctx->out; + octx->output_ctx = wctx; + wctx->pool = r->pool; + wctx->last = &wctx->out; ngx_http_proxy_send_request(p); } @@ -339,7 +354,7 @@ /* STUB */ len++; - ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL); + ngx_test_null(h, ngx_create_temp_hunk(r->pool, len), NULL); ngx_alloc_link_and_set_hunk(chain, h, r->pool, NULL); @@ -439,7 +454,7 @@ int rc; ngx_chain_t *cl; ngx_connection_t *c; - ngx_chain_write_ctx_t *ctx; + ngx_chain_writer_ctx_t *wctx; c = p->upstream.connection; @@ -447,8 +462,8 @@ if (c) { p->action = "sending request to upstream"; - ctx = p->output_chain_ctx->output_ctx; - ctx->connection = c; + wctx = p->output_chain_ctx->output_ctx; + wctx->connection = c; rc = ngx_output_chain(p->output_chain_ctx, !p->request_sent ? p->request->request_hunks: NULL); @@ -504,6 +519,20 @@ ngx_event_connect_peer_failed(&p->upstream); ngx_http_proxy_close_connection(c); + + if (p->upstream.tries == 0 + || !(p->lcf->next_upstream & NGX_HTTP_PROXY_FT_ERROR)) + { + ngx_http_proxy_finalize_request(p, + p->timedout ? NGX_HTTP_GATEWAY_TIME_OUT: + NGX_HTTP_BAD_GATEWAY); + return; + } + + if (!p->fatal_error) { + ngx_http_proxy_send_request(p); + return; + } } for ( ;; ) { @@ -586,8 +615,7 @@ if (p->header_in == NULL) { p->header_in = ngx_create_temp_hunk(p->request->pool, - p->lcf->header_buffer_size, - 0, 0); + p->lcf->header_buffer_size); if (p->header_in == NULL) { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); return; @@ -746,8 +774,8 @@ } } - ngx_log_debug(c->log, "HTTP proxy header: %08X '%s: %s'" _ - h _ h->key.data _ h->value.data); + ngx_log_debug(c->log, "HTTP proxy header: '%s: %s'" _ + h->key.data _ h->value.data); continue; @@ -952,6 +980,12 @@ ep->preread_size = p->header_in->last - p->header_in->pos; + if (ngx_event_flags & NGX_USE_AIO_EVENT) { + + /* the posted aio operation can currupt shadow buf */ + ep->single_buf = 1; + } + /* * event_pipe would do p->header_in->last += ep->preread_size * as though these bytes were read. @@ -1405,6 +1439,8 @@ conf->path = NULL; + conf->next_upstream = 0; + conf->upstreams = NULL; conf->peers = NULL; @@ -1428,8 +1464,6 @@ /* "proxy_cyclic_temp_file" is disabled */ conf->cyclic_temp_file = 0; - conf->next_upstream = NGX_CONF_UNSET; - conf->pass_server = NGX_CONF_UNSET; return conf; @@ -1464,8 +1498,8 @@ ngx_conf_merge_size_value(conf->temp_file_write_size, prev->temp_file_write_size, 16384); - ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, - (NGX_HTTP_PROXY_FT_ERROR|NGX_HTTP_PROXY_FT_TIMEOUT)); + ngx_conf_merge_bitmask_value(conf->next_upstream, prev->next_upstream, + (NGX_HTTP_PROXY_FT_ERROR|NGX_HTTP_PROXY_FT_TIMEOUT)); ngx_conf_merge_path_value(conf->temp_path, prev->temp_path, "temp", 1, 2, 0, cf->pool); diff -r 894a01c6aea3 -r 389d7ee9fa60 src/http/ngx_http_header_filter.c --- a/src/http/ngx_http_header_filter.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/http/ngx_http_header_filter.c Thu Oct 30 08:51:06 2003 +0000 @@ -210,7 +210,7 @@ len += header[i].key.len + 2 + header[i].value.len + 2; } - ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 0), NGX_ERROR); + ngx_test_null(h, ngx_create_temp_hunk(r->pool, len), NGX_ERROR); /* "HTTP/1.x " */ h->last = ngx_cpymem(h->last, "HTTP/1.1 ", sizeof("HTTP/1.x ") - 1); diff -r 894a01c6aea3 -r 389d7ee9fa60 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/http/ngx_http_request.c Thu Oct 30 08:51:06 2003 +0000 @@ -68,8 +68,7 @@ return; } - lctx = ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)); - if (lctx == NULL) { + if (!(lctx = ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)))) { ngx_http_close_connection(c); return; } @@ -133,8 +132,7 @@ ngx_memzero(r, sizeof(ngx_http_request_t)); } else { - r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); - if (r == NULL) { + if (!(r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)))) { ngx_http_close_connection(c); return; } @@ -212,23 +210,20 @@ c->log->log_level = clcf->err_log->log_level; if (c->buffer == NULL) { - c->buffer = ngx_create_temp_hunk(c->pool, - cscf->client_header_buffer_size, - 0, 0); + c->buffer = + ngx_create_temp_hunk(c->pool, cscf->client_header_buffer_size); if (c->buffer == NULL) { ngx_http_close_connection(c); return; } } - r->pool = ngx_create_pool(cscf->request_pool_size, c->log); - if (r->pool == NULL) { + if (!(r->pool = ngx_create_pool(cscf->request_pool_size, c->log))) { ngx_http_close_connection(c); return; } - r->headers_out.headers = ngx_create_table(r->pool, 20); - if (r->headers_out.headers == NULL) { + if (!(r->headers_out.headers = ngx_create_table(r->pool, 20))) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_close_connection(c); return; @@ -290,7 +285,7 @@ /* the request line has been parsed successfully */ - /* STUB: we need to handle such URIs */ + /* TODO: we need to handle such URIs */ if (r->complex_uri || r->unusual_uri) { r->request_line.len = r->request_end - r->request_start; r->request_line.data = r->request_start; @@ -323,8 +318,7 @@ r->uri.len = r->uri_end - r->uri_start; } - r->uri.data = ngx_palloc(r->pool, r->uri.len + 1); - if (r->uri.data == NULL) { + if (!(r->uri.data = ngx_palloc(r->pool, r->uri.len + 1))) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_close_connection(c); return; @@ -378,8 +372,7 @@ r->exten.len = r->uri_end - r->uri_ext; } - r->exten.data = ngx_palloc(r->pool, r->exten.len + 1); - if (r->exten.data == NULL) { + if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_close_connection(c); return; @@ -393,8 +386,7 @@ if (r->args_start && r->uri_end > r->args_start) { r->args.len = r->uri_end - r->args_start; - r->args.data = ngx_palloc(r->pool, r->args.len + 1); - if (r->args.data == NULL) { + if (!(r->args.data = ngx_palloc(r->pool, r->args.len + 1))) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_close_connection(c); return; @@ -531,8 +523,8 @@ /* a header line has been parsed successfully */ - if (!(h = ngx_http_add_header(&r->headers_in, ngx_http_headers_in))) - { + h = ngx_http_add_header(&r->headers_in, ngx_http_headers_in); + if (h == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_close_connection(c); return; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/http/ngx_http_request_body.c Thu Oct 30 08:51:06 2003 +0000 @@ -47,8 +47,7 @@ size = request_buffer_size; } - ngx_test_null(r->request_body_hunk, - ngx_create_temp_hunk(r->pool, size, 0, 0), + ngx_test_null(r->request_body_hunk, ngx_create_temp_hunk(r->pool, size), NGX_HTTP_INTERNAL_SERVER_ERROR); r->connection->read->event_handler = diff -r 894a01c6aea3 -r 389d7ee9fa60 src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/http/ngx_http_write_filter.c Thu Oct 30 08:51:06 2003 +0000 @@ -21,16 +21,16 @@ static int ngx_http_write_filter_init(ngx_cycle_t *cycle); -static ngx_command_t ngx_http_write_filter_commands[] = { +static ngx_command_t ngx_http_write_filter_commands[] = { - {ngx_string("buffer_output"), - NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_write_filter_conf_t, buffer_output), - NULL}, + { ngx_string("buffer_output"), + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_write_filter_conf_t, buffer_output), + NULL }, - ngx_null_command + ngx_null_command }; diff -r 894a01c6aea3 -r 389d7ee9fa60 src/os/unix/ngx_aio_read.c --- a/src/os/unix/ngx_aio_read.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/os/unix/ngx_aio_read.c Thu Oct 30 08:51:06 2003 +0000 @@ -24,12 +24,15 @@ rev = c->read; - if (rev->active) { + if (!rev->ready) { ngx_log_error(NGX_LOG_ALERT, rev->log, 0, "SECOND AIO POST"); return NGX_AGAIN; } - if (!rev->aio_complete) { + ngx_log_debug(rev->log, "rev->complete: %d" _ rev->complete); + ngx_log_debug(rev->log, "aio size: %d" _ size); + + if (!rev->complete) { ngx_memzero(&rev->aiocb, sizeof(struct aiocb)); rev->aiocb.aio_fildes = c->fd; @@ -49,12 +52,13 @@ return NGX_ERROR; } - ngx_log_debug(rev->log, "aio_read: OK"); + ngx_log_debug(rev->log, "aio_read: #%d OK" _ c->fd); rev->active = 1; + rev->ready = 0; } - rev->aio_complete = 0; + rev->complete = 0; n = aio_error(&rev->aiocb); if (n == -1) { @@ -65,15 +69,17 @@ if (n != 0) { if (n == NGX_EINPROGRESS) { - if (!rev->active) { + if (rev->ready) { ngx_log_error(NGX_LOG_ALERT, rev->log, n, "aio_read() still in progress"); + rev->ready = 0; } return NGX_AGAIN; } ngx_log_error(NGX_LOG_CRIT, rev->log, n, "aio_read() failed"); rev->error = 1; + rev->ready = 0; return NGX_ERROR; } @@ -83,16 +89,20 @@ "aio_return() failed"); rev->error = 1; + rev->ready = 0; return NGX_ERROR; } + ngx_log_debug(rev->log, "aio_read: #%d %d" _ c->fd _ n); + + if (n == 0) { + rev->eof = 1; + rev->ready = 0; + } else { + rev->ready = 1; + } + rev->active = 0; - ngx_log_debug(rev->log, "aio_read: %d" _ n); - - if (n == 0) { - rev->eof = 1; - } - return n; } diff -r 894a01c6aea3 -r 389d7ee9fa60 src/os/unix/ngx_aio_read_chain.c --- a/src/os/unix/ngx_aio_read_chain.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/os/unix/ngx_aio_read_chain.c Thu Oct 30 08:51:06 2003 +0000 @@ -12,25 +12,30 @@ size_t size, total; ngx_err_t err; + if (c->read->aio_eof) { + c->read->ready = 0; + return 0; + } + total = 0; while (cl) { /* we can post the single aio operation only */ - if (c->read->active) { + if (!c->read->ready) { return total ? total : NGX_AGAIN; } - buf = cl->hunk->pos; - prev = buf; + buf = cl->hunk->last; + prev = cl->hunk->last; size = 0; /* coalesce the neighbouring hunks */ - while (cl && prev == cl->hunk->pos) { - size += cl->hunk->last - cl->hunk->pos; - prev = cl->hunk->last; + while (cl && prev == cl->hunk->last) { + size += cl->hunk->end - cl->hunk->last; + prev = cl->hunk->end; cl = cl->next; } @@ -46,6 +51,15 @@ return NGX_ERROR; } + if (n == 0) { + c->read->aio_eof = 1; + if (total) { + c->read->eof = 0; + c->read->ready = 1; + } + return total; + } + if (n > 0) { total += n; } diff -r 894a01c6aea3 -r 389d7ee9fa60 src/os/unix/ngx_aio_write.c --- a/src/os/unix/ngx_aio_write.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/os/unix/ngx_aio_write.c Thu Oct 30 08:51:06 2003 +0000 @@ -24,13 +24,13 @@ wev = c->write; - if (wev->active) { + if (!wev->ready) { return NGX_AGAIN; } -ngx_log_debug(wev->log, "aio: wev->aio_complete: %d" _ wev->aio_complete); +ngx_log_debug(wev->log, "aio: wev->complete: %d" _ wev->complete); - if (!wev->aio_complete) { + if (!wev->complete) { ngx_memzero(&wev->aiocb, sizeof(struct aiocb)); wev->aiocb.aio_fildes = c->fd; @@ -52,9 +52,10 @@ ngx_log_debug(wev->log, "aio_write: OK"); wev->active = 1; + wev->ready = 0; } - wev->aio_complete = 0; + wev->complete = 0; n = aio_error(&wev->aiocb); if (n == -1) { @@ -65,15 +66,28 @@ if (n != 0) { if (n == NGX_EINPROGRESS) { - if (!wev->active) { + if (wev->ready) { ngx_log_error(NGX_LOG_ALERT, wev->log, n, "aio_write() still in progress"); + wev->ready = 0; } return NGX_AGAIN; } ngx_log_error(NGX_LOG_CRIT, wev->log, n, "aio_write() failed"); wev->error = 1; + wev->ready = 0; + +#if 1 + n = aio_return(&wev->aiocb); + if (n == -1) { + ngx_log_error(NGX_LOG_ALERT, wev->log, ngx_errno, + "aio_return() failed"); + } + + ngx_log_error(NGX_LOG_CRIT, wev->log, n, "aio_return() %d", n); +#endif + return NGX_ERROR; } @@ -83,16 +97,15 @@ "aio_return() failed"); wev->error = 1; + wev->ready = 0; return NGX_ERROR; } - wev->active = 0; ngx_log_debug(wev->log, "aio_write: %d" _ n); - if (n == 0) { - wev->eof = 1; - } + wev->active = 0; + wev->ready = 1; return n; } diff -r 894a01c6aea3 -r 389d7ee9fa60 src/os/unix/ngx_aio_write_chain.c --- a/src/os/unix/ngx_aio_write_chain.c Wed Oct 29 17:39:05 2003 +0000 +++ b/src/os/unix/ngx_aio_write_chain.c Thu Oct 30 08:51:06 2003 +0000 @@ -26,7 +26,7 @@ /* we can post the single aio operation only */ - if (c->write->active) { + if (!c->write->ready) { return cl; }