]> git.kaiwu.me - nginx.git/commitdiff
nginx-0.0.1-2003-10-30-11:51:06 import
authorIgor Sysoev <igor@sysoev.ru>
Thu, 30 Oct 2003 08:51:06 +0000 (08:51 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Thu, 30 Oct 2003 08:51:06 +0000 (08:51 +0000)
21 files changed:
src/core/ngx_conf_file.c
src/core/ngx_conf_file.h
src/core/ngx_hunk.c
src/core/ngx_hunk.h
src/core/ngx_output_chain.c
src/event/modules/ngx_kqueue_module.c
src/event/ngx_event.h
src/event/ngx_event_acceptex.c
src/event/ngx_event_connect.c
src/event/ngx_event_pipe.c
src/event/ngx_event_pipe.h
src/http/modules/ngx_http_gzip_filter.c
src/http/modules/proxy/ngx_http_proxy_handler.c
src/http/ngx_http_header_filter.c
src/http/ngx_http_request.c
src/http/ngx_http_request_body.c
src/http/ngx_http_write_filter.c
src/os/unix/ngx_aio_read.c
src/os/unix/ngx_aio_read_chain.c
src/os/unix/ngx_aio_write.c
src/os/unix/ngx_aio_write_chain.c

index e9e931525121264e298836cc0ad960b5dfa4bcc3..5818636a8c3682329c302061221f0b2fd7d7ef62 100644 (file)
@@ -61,7 +61,7 @@ char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
         }
 
         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_sec_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  *p = conf;
+    char *p = conf;
 
     ngx_str_t   *value;
     ngx_bufs_t  *bufs;
@@ -749,6 +749,51 @@ 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  *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";
index c132d07ac17f5dcd6de4c4ca1ffd09dac8e50403..4bf674751e9825f4101de8bc218e528cc629cf1b 100644 (file)
@@ -150,6 +150,12 @@ typedef struct {
 } 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 @@ char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
         }                                                                    \
     }
 
+#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_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 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);
index d69c0df58740b817368844fce97b124e1b10f65d..3799cef78b429d9d36a7c2c5828f01cff6717bab 100644 (file)
@@ -3,19 +3,21 @@
 #include <ngx_core.h>
 
 
-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->pos = h->start;
+    h->last = h->start;
+
+    h->file_pos = 0;
+    h->file_last = 0;
 
-    h->start = h->pos = h->last = h->pre_start + before;
-    h->file_pos = 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_chain_t *ngx_create_chain_of_hunks(ngx_pool_t *pool, ngx_bufs_t *bufs)
 }
 
 
-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;
index 82c5cc6f4ad59245bfac7862445f0f108e28b82f..3de78aa200844212c2a38f23d31f40c15ee6a087 100644 (file)
@@ -50,8 +50,6 @@ struct ngx_hunk_s {
     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 @@ typedef struct {
     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 @@ typedef struct {
                                          (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 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
 
 
 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,
index 4ab9b96aaf7f287d71fb7071f2dfdf99399adeb6..b50cf9074c35ffbd2ffbce0d2e10351fbef5bd90 100644 (file)
@@ -108,7 +108,7 @@ int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
                     }
 
                     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 @@ ngx_log_debug(src->file->log, "READ: %qd:%qd %X:%X %X:%X" _
 }
 
 
-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;
 
index 6f6ed622b3aa3ae1f59754768f98d939bff0fa79..26e109b1a72c2d2e70d8b24b90eef576bf01629c 100644 (file)
@@ -437,8 +437,8 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
             break;
 
         case EVFILT_AIO:
-            ev->aio_complete = 1;
-            ev->active = 0;
+            ev->complete = 1;
+            ev->ready = 1;
 
             ev->event_handler(ev);
 
index 1e5a63a79e85a66551d49333a314484c824cc70e..629e83d14b7e14f9716f471b9f7735465559750b 100644 (file)
@@ -61,18 +61,15 @@ struct ngx_event_s {
 
     /*
      * 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 @@ struct ngx_event_s {
 
     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
 
index 8fd978eb03a886f1ea7a0d8a36e1cbe5f99358ce..c737434b768a185f5ee547c028cf3e61a1918fe0 100644 (file)
@@ -120,6 +120,9 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n)
         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 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n)
         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),
index d47c5429b5f49382c8d5f1b4c3952f6e8986d2b3..c697c1be5183d4df883937fbd8bf8d70f25cf9d8 100644 (file)
@@ -204,12 +204,13 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ peer->addr_port_text.data);
 
     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
     }
index d9f9abcec1f51241a17eb4ef8146fea4f416e167..387d8b8610aeea11225be5cda4205a2a9c59be59 100644 (file)
@@ -101,71 +101,52 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
 
         } 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->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 (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 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");
-                    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 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
                 }
 
                 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 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
 
             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 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
             }
 
             if (n == NGX_AGAIN) {
+                if (p->single_buf) {
+                    ngx_event_pipe_remove_shadow_links(chain->hunk);
+                }
+
                 break;
             }
 
@@ -283,8 +276,11 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
             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) {
index f59b60e7d231f52eca4e8b0a3797e49f554f2b2f..fc68cc6e77d6d3d67040852c1d0c8c46a54d24f2 100644 (file)
@@ -38,6 +38,7 @@ struct ngx_event_pipe_s {
 
     unsigned           read:1;
     unsigned           cachable:1;
+    unsigned           single_buf:1;
     unsigned           upstream_done:1;
     unsigned           upstream_error:1;
     unsigned           upstream_eof:1;
index 9fff90d01e517438d2dab9987f0f458d23b724cb..5a091b475b9f683ffee94635d90f0f2c7a6bdbe2 100644 (file)
@@ -190,9 +190,9 @@ static int ngx_http_gzip_header_filter(ngx_http_request_t *r)
                         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 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
     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 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
                 } 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 @@ ngx_log_debug(r->connection->log, "DEFLATE(): %08x %08x %d %d %d" _
 
                     } 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;
index c9caaa79a05dac1019a95a60ec98bbdeadabdbf0..053b7b5982a2b2fd82ee691d79c4c7c7a4ce0d50 100644 (file)
@@ -38,86 +38,101 @@ static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
                                            ngx_http_proxy_upstream_t *u);
 
 
-static ngx_command_t ngx_http_proxy_commands[] = {
-
-    {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_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_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_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_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_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_null_command
+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 }
+};
+
+static ngx_command_t  ngx_http_proxy_commands[] = {
+
+    { 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_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_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_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_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_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
 };
 
 
@@ -231,8 +246,8 @@ static void ngx_http_proxy_init_request(void *data)
 
     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 @@ ngx_log_debug(r->connection->log, "timer_set: %d" _
     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 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
 
     /* 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 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
     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 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
 
         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 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
 
             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 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev)
 
     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 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
                 }
             }
 
-            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 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
 
     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 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
 
     conf->path = NULL;
 
+    conf->next_upstream = 0;
+
     conf->upstreams = NULL;
     conf->peers = NULL;
 
@@ -1428,8 +1464,6 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
     /* "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 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
     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);
index fe97d29580fdeb4021f549543e264ac8fab7a6ab..f85bd457589808766571b16edb9c8ef7e94a5ba4 100644 (file)
@@ -210,7 +210,7 @@ static int ngx_http_header_filter(ngx_http_request_t *r)
         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);
index be38358e093590fb93de7b0330ff805dfa112147..36fac035277a269a49a5852d8ca041def9b385fb 100644 (file)
@@ -68,8 +68,7 @@ void ngx_http_init_connection(ngx_connection_t *c)
         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 @@ static void ngx_http_init_request(ngx_event_t *rev)
         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 @@ ngx_log_debug(rev->log, "IN: %08x" _ in_port);
     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 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
 
         /* 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 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
             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 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
                 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 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
         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 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
 
             /* 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;
index 19730e7b34ad256068cefe2332d0b2d494b53885..eb82af05c305fdd46bac7ca6b8c62393d5d260fd 100644 (file)
@@ -47,8 +47,7 @@ int ngx_http_read_client_request_body(ngx_http_request_t *r,
         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 =
index b7cb16c3ff2d02b05e538dc7bace4e9e9f37ca27..143f38c7d63361a63292c846b8ad7693f3b45cb6 100644 (file)
@@ -21,16 +21,16 @@ static char *ngx_http_write_filter_merge_conf(ngx_conf_t *cf,
 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
 };
 
 
index cb498eb5dbcc41a0cb04b515cf00783f65827cb5..28deac6d229ac3867ddfb4bd1417cb6088948b4b 100644 (file)
@@ -24,12 +24,15 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
 
     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 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
             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 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
 
     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 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
                       "aio_return() failed");
 
         rev->error = 1;
+        rev->ready = 0;
         return NGX_ERROR;
     }
 
-    rev->active = 0;
-
-    ngx_log_debug(rev->log, "aio_read: %d" _ n);
+    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;
+
     return n;
 }
index 31f7c857377bed36d6d1e98bb075e9603b99f0dc..9af48dd98afcb5d05a0966f87d75a20887a84f38 100644 (file)
@@ -12,25 +12,30 @@ ssize_t ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl)
     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 @@ ssize_t ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl)
             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;
         }
index dcdecc5b661f07a7d62674de88a530ddc4b780d3..dc2c876e538b5189cfa0133ff92a82e639e62a0c 100644 (file)
@@ -24,13 +24,13 @@ ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size)
 
     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: wev->aio_complete: %d" _ wev->aio_complete);
         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 @@ ngx_log_debug(wev->log, "aio: wev->aio_complete: %d" _ wev->aio_complete);
 
     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 @@ ngx_log_debug(wev->log, "aio: wev->aio_complete: %d" _ wev->aio_complete);
                       "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;
 }
index ba24d808e75dd4e541697abb053306e46011beea..73150447f6662278da430eafab8f2e1c68ea1a2d 100644 (file)
@@ -26,7 +26,7 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
 
         /* we can post the single aio operation only */
 
-        if (c->write->active) {
+        if (!c->write->ready) {
             return cl;
         }