nginx-0.0.1-2003-10-22-20:38:26 import
diff --git a/src/http/modules/ngx_http_charset_filter.c b/src/http/modules/ngx_http_charset_filter.c
index c0925ef..dd48f0b 100644
--- a/src/http/modules/ngx_http_charset_filter.c
+++ b/src/http/modules/ngx_http_charset_filter.c
@@ -50,9 +50,9 @@
 };
 
 
-static int (*next_header_filter) (ngx_http_request_t *r);
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
 #if 0
-static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
 #endif
 
 
@@ -62,12 +62,12 @@
 
     if (r->headers_out.content_type == NULL
         || ngx_strncasecmp(r->headers_out.content_type->value.data,
-                                                           "text/", 5) != 0
+                                                              "text/", 5) != 0
         || ngx_strstr(r->headers_out.content_type->value.data, "charset")
                                                                        != NULL
        )
     {
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
@@ -75,15 +75,19 @@
     if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY
         && r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY)
     {
-        /* do not set charset for the redirect because NN 4.x uses this
-           charset instead of the next page charset */
+
+        /*
+         * do not set charset for the redirect because NN 4.x uses this
+         * charset instead of the next page charset
+         */
+
         r->headers_out.charset.len = 0;
 
     } else if (r->headers_out.charset.len == 0) {
         r->headers_out.charset = lcf->default_charset;
     }
 
-    return next_header_filter(r);
+    return ngx_http_next_header_filter(r);
 }
 
 
@@ -91,18 +95,18 @@
 static int ngx_http_charset_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
 {
     ngx_log_debug(r->connection->log, "CHARSET BODY");
-    return next_body_filter(r, in);
+    return ngx_http_next_body_filter(r, in);
 }
 #endif
 
 
 static int ngx_http_charset_filter_init(ngx_cycle_t *cycle)
 {
-    next_header_filter = ngx_http_top_header_filter;
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
     ngx_http_top_header_filter = ngx_http_charset_header_filter;
 
 #if 0
-    next_body_filter = ngx_http_top_body_filter;
+    ngx_http_next_body_filter = ngx_http_top_body_filter;
     ngx_http_top_body_filter = ngx_http_charset_body_filter;
 #endif
 
diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c
index 83981ba..20a5d0d 100644
--- a/src/http/modules/ngx_http_chunked_filter.c
+++ b/src/http/modules/ngx_http_chunked_filter.c
@@ -29,14 +29,14 @@
 };
 
 
-static int (*next_header_filter) (ngx_http_request_t *r);
-static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
+static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
 
 
 static int ngx_http_chunked_header_filter(ngx_http_request_t *r)
 {
     if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     if (r->headers_out.content_length_n == -1) {
@@ -48,7 +48,7 @@
         }
     }
 
-    return next_header_filter(r);
+    return ngx_http_next_header_filter(r);
 }
 
 
@@ -57,36 +57,31 @@
     char         *chunk;
     size_t        size, len;
     ngx_hunk_t   *h;
-    ngx_chain_t  *out, *ce, *te, **le;
+    ngx_chain_t  *out, *cl, *tl, **ll;
 
     if (in == NULL || !r->chunked) {
-        return next_body_filter(r, in);
+        return ngx_http_next_body_filter(r, in);
     }
 
-    ngx_test_null(out, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-    le = &out->next;
+    ngx_test_null(out, ngx_alloc_chain_link(r->pool), NGX_ERROR);
+    ll = &out->next;
 
     size = 0;
-    ce = in;
+    cl = in;
 
     for ( ;; ) {
+        size += ngx_hunk_size(cl->hunk);
 
-        if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
-            size += ce->hunk->last - ce->hunk->pos;
-        } else {
-            size += (size_t) (ce->hunk->file_last - ce->hunk->file_pos);
-        }
+        ngx_test_null(tl, ngx_alloc_chain_link(r->pool), NGX_ERROR);
+        tl->hunk = cl->hunk;
+        *ll = tl;
+        ll = &tl->next;
 
-        ngx_test_null(te, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-        te->hunk = ce->hunk;
-        *le = te;
-        le = &te->next;
-
-        if (ce->next == NULL) {
+        if (cl->next == NULL) {
             break;
         }
 
-        ce = ce->next;
+        cl = cl->next;
     }
 
     ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR);
@@ -101,8 +96,8 @@
 
     ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
 
-    if (ce->hunk->type & NGX_HUNK_LAST) {
-        ce->hunk->type &= ~NGX_HUNK_LAST;
+    if (cl->hunk->type & NGX_HUNK_LAST) {
+        cl->hunk->type &= ~NGX_HUNK_LAST;
         h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_MEMORY|NGX_HUNK_LAST;
         h->pos = CRLF "0" CRLF CRLF;
         h->last = h->pos + 7;
@@ -113,21 +108,19 @@
         h->last = h->pos + 2;
     }
 
-    ngx_test_null(te, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-    te->hunk = h;
-    te->next = NULL;
-    *le = te;
+    ngx_alloc_link_and_set_hunk(tl, h, r->pool, NGX_ERROR);
+    *ll = tl;
 
-    return next_body_filter(r, out);
+    return ngx_http_next_body_filter(r, out);
 }
 
 
 static int ngx_http_chunked_filter_init(ngx_cycle_t *cycle)
 {
-    next_header_filter = ngx_http_top_header_filter;
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
     ngx_http_top_header_filter = ngx_http_chunked_header_filter;
 
-    next_body_filter = ngx_http_top_body_filter;
+    ngx_http_next_body_filter = ngx_http_top_body_filter;
     ngx_http_top_body_filter = ngx_http_chunked_body_filter;
 
     return NGX_OK;
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c
index 5b8cebb..6cdc56a 100644
--- a/src/http/modules/ngx_http_gzip_filter.c
+++ b/src/http/modules/ngx_http_gzip_filter.c
@@ -7,9 +7,9 @@
 
 
 typedef struct {
-    int         enable;
-    ngx_bufs_t  bufs;
-    int         no_buffer;
+    int            enable;
+    ngx_bufs_t     bufs;
+    int            no_buffer;
 } ngx_http_gzip_conf_t;
 
 
@@ -111,9 +111,8 @@
 #endif
 
 
-
-static int (*next_header_filter) (ngx_http_request_t *r);
-static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
+static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
 
 
 static int ngx_http_gzip_header_filter(ngx_http_request_t *r)
@@ -134,7 +133,7 @@
         || ngx_strstr(r->headers_in.accept_encoding->value.data, "gzip") == NULL
        )
     {
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     /* TODO: "text/html" -> custom types */
@@ -142,7 +141,7 @@
         && ngx_strncasecmp(r->headers_out.content_type->value.data,
                                                           "text/html", 5) != 0)
     {
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     ngx_http_create_ctx(r, ctx, ngx_http_gzip_filter_module,
@@ -162,7 +161,7 @@
     r->headers_out.content_length = NULL;
     r->filter |= NGX_HTTP_FILTER_NEED_IN_MEMORY;
 
-    return next_header_filter(r);
+    return ngx_http_next_header_filter(r);
 }
 
 
@@ -171,14 +170,14 @@
     int                    rc, wbits, mem_level, zin, zout, last;
     struct gztrailer      *trailer;
     ngx_hunk_t            *h;
-    ngx_chain_t           *ce;
+    ngx_chain_t           *cl;
     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) {
-        return next_body_filter(r, in);
+        return ngx_http_next_body_filter(r, in);
     }
 
     conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
@@ -218,12 +217,9 @@
         h->pos = gzheader;
         h->last = h->pos + 10;
 
-        ngx_test_null(ce, ngx_alloc_chain_entry(r->pool),
-                      ngx_http_gzip_error(ctx));
-        ce->hunk = h;
-        ce->next = NULL;
-        ctx->out = ce;
-        ctx->last_out = &ce->next;
+        ngx_alloc_link_and_set_hunk(cl, h, r->pool, ngx_http_gzip_error(ctx));
+        ctx->out = cl;
+        ctx->last_out = &cl->next;
 
         ctx->crc32 = crc32(0L, Z_NULL, 0);
         ctx->flush = Z_NO_FLUSH;
@@ -319,10 +315,10 @@
 
             if (ctx->zstream.avail_out == 0) {
                 ctx->out_hunk->last += conf->bufs.size;
-                ngx_add_hunk_to_chain(ce, ctx->out_hunk, r->pool,
-                                      ngx_http_gzip_error(ctx));
-                *ctx->last_out = ce;
-                ctx->last_out = &ce->next;
+                ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool,
+                                            ngx_http_gzip_error(ctx));
+                *ctx->last_out = cl;
+                ctx->last_out = &cl->next;
                 ctx->redo = 1;
 
             } else {
@@ -333,10 +329,10 @@
                     ctx->out_hunk->type |= NGX_HUNK_FLUSH;
                     ctx->flush = Z_NO_FLUSH;
 
-                    ngx_add_hunk_to_chain(ce, ctx->out_hunk, r->pool,
-                                          ngx_http_gzip_error(ctx));
-                    *ctx->last_out = ce;
-                    ctx->last_out = &ce->next;
+                    ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool,
+                                                ngx_http_gzip_error(ctx));
+                    *ctx->last_out = cl;
+                    ctx->last_out = &cl->next;
 
                     break;
 
@@ -355,10 +351,10 @@
 
                     ctx->flush = Z_NO_FLUSH;
 
-                    ngx_add_hunk_to_chain(ce, ctx->out_hunk, r->pool,
-                                          ngx_http_gzip_error(ctx));
-                    *ctx->last_out = ce;
-                    ctx->last_out = &ce->next;
+                    ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool,
+                                                ngx_http_gzip_error(ctx));
+                    *ctx->last_out = cl;
+                    ctx->last_out = &cl->next;
 
                     if (ctx->zstream.avail_out >= 8) {
                         trailer = (struct gztrailer *) ctx->out_hunk->last;
@@ -372,12 +368,10 @@
 
                         h->type |= NGX_HUNK_LAST;
 
-                        ngx_test_null(ce, ngx_alloc_chain_entry(r->pool),
-                                      ngx_http_gzip_error(ctx));
-                        ce->hunk = h;
-                        ce->next = NULL;
-                        *ctx->last_out = ce;
-                        ctx->last_out = &ce->next;
+                        ngx_alloc_link_and_set_hunk(cl, h, r->pool,
+                                                    ngx_http_gzip_error(ctx));
+                        *ctx->last_out = cl;
+                        ctx->last_out = &cl->next;
                         trailer = (struct gztrailer *) h->pos;
                         h->last += 8;
                     }
@@ -399,10 +393,10 @@
                     break;
 
                 } else if (conf->no_buffer && ctx->in == NULL) {
-                    ngx_add_hunk_to_chain(ce, ctx->out_hunk, r->pool,
-                                          ngx_http_gzip_error(ctx));
-                    *ctx->last_out = ce;
-                    ctx->last_out = &ce->next;
+                    ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool,
+                                                ngx_http_gzip_error(ctx));
+                    *ctx->last_out = cl;
+                    ctx->last_out = &cl->next;
 
                     break;
                 }
@@ -413,7 +407,7 @@
             return last;
         }
 
-        last = next_body_filter(r, ctx->out);
+        last = ngx_http_next_body_filter(r, ctx->out);
 
         if (last == NGX_ERROR) {
             return ngx_http_gzip_error(ctx);
@@ -443,10 +437,10 @@
 
 static int ngx_http_gzip_filter_init(ngx_cycle_t *cycle)
 {
-    next_header_filter = ngx_http_top_header_filter;
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
     ngx_http_top_header_filter = ngx_http_gzip_header_filter;
 
-    next_body_filter = ngx_http_top_body_filter;
+    ngx_http_next_body_filter = ngx_http_top_body_filter;
     ngx_http_top_body_filter = ngx_http_gzip_body_filter;
 
     return NGX_OK;
diff --git a/src/http/modules/ngx_http_not_modified_filter.c b/src/http/modules/ngx_http_not_modified_filter.c
index 3435ed5..b00e2ff 100644
--- a/src/http/modules/ngx_http_not_modified_filter.c
+++ b/src/http/modules/ngx_http_not_modified_filter.c
@@ -30,7 +30,7 @@
 };
 
 
-static int (*next_header_filter) (ngx_http_request_t *r);
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
 
 
 static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
@@ -41,7 +41,7 @@
         || r->headers_in.if_modified_since == NULL
         || r->headers_out.last_modified_time == -1)
     {
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
@@ -50,7 +50,9 @@
     ngx_log_debug(r->connection->log, "%d %d" _
                   ims _ r->headers_out.last_modified_time);
 
-    /* I think that the equality of the dates is correcter */
+    /*
+     * I think that the equality of the dates is correcter
+     */
 
     if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
         r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
@@ -61,13 +63,13 @@
         r->headers_out.accept_ranges->key.len = 0;
     }
 
-    return next_header_filter(r);
+    return ngx_http_next_header_filter(r);
 }
 
 
 static int ngx_http_not_modified_filter_init(ngx_cycle_t *cycle)
 {
-    next_header_filter = ngx_http_top_header_filter;
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
     ngx_http_top_header_filter = ngx_http_not_modified_header_filter;
 
     return NGX_OK;
diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c
index c51a5f0..61669ca 100644
--- a/src/http/modules/ngx_http_range_filter.c
+++ b/src/http/modules/ngx_http_range_filter.c
@@ -34,8 +34,8 @@
 };
 
 
-static int (*next_header_filter) (ngx_http_request_t *r);
-static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
+static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
 
 
 static int ngx_http_range_header_filter(ngx_http_request_t *r)
@@ -53,7 +53,7 @@
         /* STUB: we currently support ranges for file hunks only */
         || r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
     {
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     if (r->headers_in.range == NULL
@@ -69,7 +69,7 @@
         r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
         r->headers_out.accept_ranges->value.data = "bytes";
 
-        return next_header_filter(r);
+        return ngx_http_next_header_filter(r);
     }
 
     ngx_init_array(r->headers_out.ranges, r->pool, 5, sizeof(ngx_http_range_t),
@@ -279,7 +279,7 @@
         }
     }
 
-    return next_header_filter(r);
+    return ngx_http_next_header_filter(r);
 }
 
 
@@ -287,16 +287,18 @@
 {
     int                           i;
     ngx_hunk_t                   *h;
-    ngx_chain_t                  *out, *hce, *rce, *dce, **le;
+    ngx_chain_t                  *out, *hcl, *rcl, *dcl, **ll;
     ngx_http_range_t             *range;
     ngx_http_range_filter_ctx_t  *ctx;
 
     if (r->headers_out.ranges.nelts == 0) {
-        return next_body_filter(r, in);
+        return ngx_http_next_body_filter(r, in);
     }
 
-    /* the optimized version for the static files only
-       that are passed in the single file hunk */
+    /*
+     * the optimized version for the static files only
+     * that are passed in the single file hunk
+     */
 
     if (in
         && in->hunk->type & NGX_HUNK_FILE
@@ -307,11 +309,11 @@
             in->hunk->file_pos = range->start;
             in->hunk->file_last = range->end;
 
-            return next_body_filter(r, in);
+            return ngx_http_next_body_filter(r, in);
         }
 
         ctx = ngx_http_get_module_ctx(r, ngx_http_range_filter_module);
-        le = &out;
+        ll = &out;
 
         range = r->headers_out.ranges.elts;
         for (i = 0; i < r->headers_out.ranges.nelts; i++) {
@@ -321,16 +323,16 @@
             h->pos = ctx->boundary_header.data;
             h->last = ctx->boundary_header.data + ctx->boundary_header.len;
 
-            ngx_test_null(hce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-            hce->hunk = h;
+            ngx_test_null(hcl, ngx_alloc_chain_link(r->pool), NGX_ERROR);
+            hcl->hunk = h;
 
             ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
             h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
             h->pos = range[i].content_range.data;
             h->last = range[i].content_range.data + range[i].content_range.len;
 
-            ngx_test_null(rce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-            rce->hunk = h;
+            ngx_test_null(rcl, ngx_alloc_chain_link(r->pool), NGX_ERROR);
+            rcl->hunk = h;
 
             ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
             h->type = NGX_HUNK_FILE;
@@ -338,14 +340,12 @@
             h->file_last = range[i].end;
             h->file = in->hunk->file;
 
-            ngx_test_null(dce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-            dce->hunk = h;
-            dce->next = NULL;
+            ngx_alloc_link_and_set_hunk(dcl, h, r->pool, NGX_ERROR);
 
-            *le = hce;
-            hce->next = rce;
-            rce->next = dce;
-            le = &dce->next;
+            *ll = hcl;
+            hcl->next = rcl;
+            rcl->next = dcl;
+            ll = &dcl->next;
         }
 
         ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
@@ -355,27 +355,25 @@
         *h->last++ = '-'; *h->last++ = '-';
         *h->last++ = CR; *h->last++ = LF;
 
-        ngx_test_null(hce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
-        hce->hunk = h;
-        hce->next = NULL;
-        *le = hce;
+        ngx_alloc_link_and_set_hunk(hcl, h, r->pool, NGX_ERROR);
+        *ll = hcl;
 
-        return next_body_filter(r, out);
+        return ngx_http_next_body_filter(r, out);
     }
 
     /* TODO: several incoming hunks of proxied responses
              and memory hunks on platforms that have no sendfile() */
 
-    return next_body_filter(r, in);
+    return ngx_http_next_body_filter(r, in);
 }
 
 
 static int ngx_http_range_filter_init(ngx_cycle_t *cycle)
 {
-    next_header_filter = ngx_http_top_header_filter;
+    ngx_http_next_header_filter = ngx_http_top_header_filter;
     ngx_http_top_header_filter = ngx_http_range_header_filter;
 
-    next_body_filter = ngx_http_top_body_filter;
+    ngx_http_next_body_filter = ngx_http_top_body_filter;
     ngx_http_top_body_filter = ngx_http_range_body_filter;
 
     return NGX_OK;
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index e3157d8..dda8e9b 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -26,6 +26,8 @@
 
 static int ngx_http_proxy_init(ngx_cycle_t *cycle);
 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
+static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
+                                           void *parent, void *child);
 
 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
                                      void *conf);
@@ -42,6 +44,62 @@
      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_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_null_command
 };
 
@@ -54,11 +112,7 @@
     NULL,                                  /* merge server configuration */
 
     ngx_http_proxy_create_loc_conf,        /* create location configration */
-#if 0
-    ngx_http_proxy_merge_conf              /* merge location configration */
-#endif
-
-    NULL
+    ngx_http_proxy_merge_loc_conf          /* merge location configration */
 };
 
 
@@ -108,7 +162,7 @@
 
 static char http_version[] = " HTTP/1.0" CRLF;
 static char host_header[] = "Host: ";
-static char conn_close_header[] = "Connection: close" CRLF;
+static char connection_close_header[] = "Connection: close" CRLF;
 
 
 
@@ -168,7 +222,7 @@
           + sizeof(http_version) - 1
           + sizeof(host_header) - 1 + p->host_header.len + 2
                                                           /* 2 is for "\r\n" */
-          + sizeof(conn_close_header) - 1
+          + sizeof(connection_close_header) - 1
           + 2;                          /* 2 is for "\r\n" at the header end */
 
     header = (ngx_table_elt_t *) r->headers_in.headers->elts;
@@ -189,7 +243,7 @@
     /* STUB */ len++;
 
     ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL);
-    ngx_add_hunk_to_chain(chain, h, r->pool, NULL);
+    ngx_alloc_link_and_set_hunk(chain, h, r->pool, NULL);
 
 
     /* the request line */
@@ -220,8 +274,8 @@
 
     /* the "Connection: close" header */
 
-    h->last = ngx_cpymem(h->last, conn_close_header,
-                         sizeof(conn_close_header) - 1);
+    h->last = ngx_cpymem(h->last, connection_close_header,
+                         sizeof(connection_close_header) - 1);
 
 
     for (i = 0; i < r->headers_in.headers->nelts; i++) {
@@ -341,8 +395,7 @@
 #if (NGX_SUPPRESS_WARN)
                 le = NULL;
 #endif
-                p->work_request_hunks =
-                                       ngx_alloc_chain_entry(p->request->pool);
+                p->work_request_hunks = ngx_alloc_chain_link(p->request->pool);
                 if (p->work_request_hunks == NULL) {
                     ngx_http_proxy_finalize_request(p,
                                                NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -357,7 +410,7 @@
                     le = &te->next;
                     ce->hunk->pos = ce->hunk->start;
 
-                    te = ngx_alloc_chain_entry(p->request->pool);
+                    te = ngx_alloc_chain_link(p->request->pool);
                     if (te == NULL) {
                         ngx_http_proxy_finalize_request(p,
                                                NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -404,7 +457,7 @@
 
     if (p->header_in == NULL) {
         p->header_in = ngx_create_temp_hunk(p->request->pool,
-                                            p->lcf->header_size,
+                                            p->lcf->header_buffer_size,
                                             0, 0);
         if (p->header_in == NULL) {
             ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -563,10 +616,6 @@
 
             /* there was error while a header line parsing */
 
-#if 0
-            ngx_http_header_parse_error(r, rc);
-            ngx_http_proxy_next_upstream(p);
-#endif
             ngx_http_proxy_finalize_request(p, NGX_HTTP_BAD_GATEWAY);
             return;
         }
@@ -692,10 +741,8 @@
 
     /* */
 
-#if 0
-    /* TODO: look "Content-Length" */
-    p->block_size = p->lcf->block_size;
-#endif
+
+    /* TODO: preallocate event_pipe hunks, look "Content-Length" */
 
     r->headers_out.status = p->status;
 
@@ -715,7 +762,7 @@
     ep->output_ctx = r;
     ep->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
     ep->bufs = p->lcf->bufs;
-    ep->max_busy_len = p->lcf->max_busy_len;
+    ep->busy_size = p->lcf->busy_buffers_size;
     ep->upstream = p->upstream.connection;
     ep->downstream = r->connection;
     ep->pool = r->pool;
@@ -736,7 +783,7 @@
     ep->temp_file_warn = "an upstream response is buffered "
                          "to a temporary file";
 
-    ep->preread_hunks = ngx_alloc_chain_entry(r->pool);
+    ep->preread_hunks = ngx_alloc_chain_link(r->pool);
     if (ep->preread_hunks == NULL) {
         ngx_http_proxy_finalize_request(p, 0);
         return;
@@ -758,8 +805,8 @@
 
         /*
          * we need to disable the use of sendfile() if we use cyclic temp file
-         * because the writing a new data can interfere with sendfile
-         * that uses the same kernel file pages
+         * because the writing a new data can interfere with sendfile()
+         * that uses the same kernel file pages (at least on FreeBSD)
          */
 
         ep->cyclic_temp_file = 1;
@@ -1160,58 +1207,72 @@
                   ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)),
                   NGX_CONF_ERROR);
 
-    /* STUB */
-    ngx_test_null(conf->peers, ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)),
-                  NGX_CONF_ERROR);
+    /* set by ngx_pcalloc():
 
-    conf->peers->number = 1;
-    conf->peers->peers[0].addr = inet_addr("127.0.0.1");
-    conf->peers->peers[0].host.data = "localhost";
-    conf->peers->peers[0].host.len = sizeof("localhost") - 1;
-    conf->peers->peers[0].port = htons(9000);
-    conf->peers->peers[0].addr_port_text.data = "127.0.0.1:9000";
-    conf->peers->peers[0].addr_port_text.len = sizeof("127.0.0.1:9000") - 1;
+    conf->bufs.num = 0;
 
-    conf->connect_timeout = 30000;
-    conf->send_timeout = 30000;
-    conf->header_size = 4096;
-    conf->read_timeout = 30000;
+    conf->path = NULL;
 
-    conf->bufs.num = 5;
-    conf->bufs.size = 4096;
-    conf->max_busy_len = 8192;
+    conf->upstreams = NULL;
+    conf->peers = NULL;
 
+    */
 
-    /* CHECK in _init conf->max_temp_size >= conf->bufs.size !!! */
-    conf->max_temp_file_size = 4096 * 3;
+    conf->connect_timeout = NGX_CONF_UNSET;
+    conf->send_timeout = NGX_CONF_UNSET;
+    conf->header_buffer_size = NGX_CONF_UNSET;
+    conf->read_timeout = NGX_CONF_UNSET;
+    conf->busy_buffers_size = NGX_CONF_UNSET;
 
+    /*
+     * "proxy_max_temp_file_size" is hardcoded to 1G for reverse proxy,
+     * it should be configurable in the generic proxy
+     */
+    conf->max_temp_file_size = 1024 * 1024 * 1024;
 
-    conf->temp_file_write_size = 4096 * 2;
-    conf->cyclic_temp_file= 1;
+    conf->temp_file_write_size = NGX_CONF_UNSET;
 
-    ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),
-                  NULL);
-
-    conf->temp_path->name.data = "temp";
-    conf->temp_path->name.len = 4;
-    conf->temp_path->level[0] = 1;
-    conf->temp_path->level[1] = 2;
-    conf->temp_path->level[2] = 3;
-    conf->temp_path->len = 0;
-
-    for (i = 0; i < 3; i++) {
-        if (conf->temp_path->level[i] == 0) {
-            break;
-        }
-        conf->temp_path->len += conf->temp_path->level[i] + 1;
-    }
-
-    /* */
+    /* "proxy_cyclic_temp_file" is disabled */
+    conf->cyclic_temp_file = 0;
 
     return conf;
 }
 
 
+static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
+                                           void *parent, void *child)
+{
+    ngx_http_proxy_loc_conf_t *prev = parent;
+    ngx_http_proxy_loc_conf_t *conf = child;
+
+    ngx_conf_merge_msec_value(conf->connect_timeout,
+                              prev->connect_timeout, 60000);
+    ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 30000);
+    ngx_conf_merge_size_value(conf->header_buffer_size,
+                              prev->header_buffer_size, 4096);
+    ngx_conf_merge_msec_value(conf->read_timeout, prev->read_timeout, 30000);
+    ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 8, 4096);
+    ngx_conf_merge_size_value(conf->busy_buffers_size,
+                              prev->busy_buffers_size, 8192);
+
+#if 0
+    if (conf->max_temp_file_size > conf->bufs.size) {
+        return "\"proxy_max_temp_file\" must be greater "
+               "than one of the \"proxy_buffers\"";
+    }
+#endif
+
+    ngx_conf_merge_size_value(conf->temp_file_write_size,
+                              prev->temp_file_write_size, 16384);
+
+    ngx_conf_merge_path_value(conf->temp_path, prev->temp_path,
+                              "temp", 1, 2, 0, cf->pool);
+
+    return NULL;
+}
+
+
+
 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
                                      void *conf)
 {
@@ -1337,6 +1398,7 @@
     return NULL;
 }
 
+
 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
                                            ngx_http_proxy_upstream_t *u)
 {
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h
index 597c309..dedb06a 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.h
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.h
@@ -21,17 +21,15 @@
 typedef struct {
     ngx_msec_t                  connect_timeout;
     ngx_msec_t                  send_timeout;
-    ssize_t                     header_size;
+    ssize_t                     header_buffer_size;
     ngx_msec_t                  read_timeout;
 
     ngx_bufs_t                  bufs;
+    ssize_t                     busy_buffers_size;
 
-    /* STUB names */
-    int                         max_busy_len;
-    int                         max_temp_file_size;
-    int                         temp_file_write_size;
+    ssize_t                     max_temp_file_size;
+    ssize_t                     temp_file_write_size;
     int                         cyclic_temp_file;
-    /* */
 
     ngx_path_t                 *temp_path;
 
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 63a6adb..09a690a 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -17,12 +17,6 @@
 } ngx_http_log_ctx_t;
 
 
-typedef int (*ngx_http_output_header_filter_p)(ngx_http_request_t *r);
-
-typedef int (*ngx_http_output_body_filter_p)
-                                   (ngx_http_request_t *r, ngx_chain_t *chain);
-
-
 #define ngx_http_get_module_ctx(r, module)       r->ctx[module.ctx_index]
 
 #define ngx_http_create_ctx(r, cx, module, size, error)                       \
@@ -82,13 +76,6 @@
 extern int  ngx_max_module;
 
 
-extern ngx_array_t  ngx_http_translate_handlers;
-extern ngx_array_t  ngx_http_index_handlers;
-
-extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
-extern int (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
-
-
 /* STUB */
 int ngx_http_log_handler(ngx_http_request_t *r);
 /**/
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 6015683..8c96d0e 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -226,6 +226,7 @@
     }
 
 #if 0
+    /* TEST STUB */ r->http_version = NGX_HTTP_VERSION_10;
     /* TEST STUB */ r->keepalive = 0;
 #endif
 
diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_filter.h
index 343afd0..c8fa8df 100644
--- a/src/http/ngx_http_filter.h
+++ b/src/http/ngx_http_filter.h
@@ -7,12 +7,17 @@
 #define NGX_HTTP_FILTER_NEED_TEMP           4
 
 
-int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in);
-int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
+typedef int (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);
+typedef int (*ngx_http_output_body_filter_pt)
+                                   (ngx_http_request_t *r, ngx_chain_t *chain);
 
 
-extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
-extern int (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
+int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
+
+
+extern ngx_http_output_header_filter_pt  ngx_http_top_header_filter;
+extern ngx_http_output_body_filter_pt    ngx_http_top_body_filter;
 
 
 #endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index a2e21e3..e8cd5b8 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -371,5 +371,6 @@
 static int ngx_http_header_filter_init(ngx_cycle_t *cycle)
 {
     ngx_http_top_header_filter = ngx_http_header_filter;
+
     return NGX_OK;
 }
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
index 061798e..a58f422 100644
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -32,6 +32,8 @@
 } ngx_http_output_filter_ctx_t;
 
 
+ngx_inline static int ngx_http_output_filter_need_to_copy(ngx_http_request_t *r,
+                                                          ngx_hunk_t *hunk);
 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src,
                                             int sendfile);
 static void *ngx_http_output_filter_create_conf(ngx_conf_t *cf);
@@ -74,23 +76,12 @@
 };
 
 
-#define ngx_next_filter  (*ngx_http_top_body_filter)
-
-#define need_to_copy(r, hunk)                                             \
-            (!ngx_hunk_special(hunk)                                      \
-             && (!r->sendfile                                             \
-                 || ((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)         \
-                   && (hunk->type & NGX_HUNK_IN_MEMORY) == 0)             \
-                 || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)              \
-                  && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))))
-
-
 
 int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
 {
     int                             rc, last;
     ssize_t                         size;
-    ngx_chain_t                    *ce;
+    ngx_chain_t                    *cl;
     ngx_http_output_filter_ctx_t   *ctx;
     ngx_http_output_filter_conf_t  *conf;
 
@@ -112,11 +103,13 @@
     if (ctx->in == NULL) {
 
         if (in == NULL) {
-            return ngx_next_filter(r, in);
+            return ngx_http_top_body_filter(r, in);
         }
 
-        if (in->next == NULL && (!need_to_copy(r, in->hunk))) {
-            return ngx_next_filter(r, in);
+        if (in->next == NULL
+            && (!ngx_http_output_filter_need_to_copy(r, in->hunk)))
+        {
+            return ngx_http_top_body_filter(r, in);
         }
     }
 
@@ -137,16 +130,16 @@
 
         while (ctx->in) {
 
-            if (!need_to_copy(r, ctx->in->hunk)) {
+            if (!ngx_http_output_filter_need_to_copy(r, ctx->in->hunk)) {
 
-                /* move the chain entry to the chain ctx->out */
+                /* move the chain link to the chain ctx->out */
 
-                ce = ctx->in;
-                ctx->in = ce->next;
+                cl = ctx->in;
+                ctx->in = cl->next;
 
-                *ctx->last_out = ce;
-                ctx->last_out = &ce->next;
-                ce->next = NULL;
+                *ctx->last_out = cl;
+                ctx->last_out = &cl->next;
+                cl->next = NULL;
 
                 continue;
             }
@@ -204,9 +197,9 @@
                 ctx->in = ctx->in->next;
             }
 
-            ngx_add_hunk_to_chain(ce, ctx->hunk, r->pool, NGX_ERROR);
-            *ctx->last_out = ce;
-            ctx->last_out = &ce->next;
+            ngx_alloc_link_and_set_hunk(cl, ctx->hunk, r->pool, NGX_ERROR);
+            *ctx->last_out = cl;
+            ctx->last_out = &cl->next;
             ctx->hunk = NULL;
 
             if (ctx->free == NULL) {
@@ -218,7 +211,7 @@
             return last;
         }
 
-        last = ngx_next_filter(r, ctx->out);
+        last = ngx_http_top_body_filter(r, ctx->out);
 
         ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out,
                                (ngx_hunk_tag_t) &ngx_http_output_filter_module);
@@ -227,6 +220,34 @@
 }
 
 
+ngx_inline static int ngx_http_output_filter_need_to_copy(ngx_http_request_t *r,
+                                                          ngx_hunk_t *hunk)
+{
+    if (ngx_hunk_special(hunk)) {
+        return 0;
+    }
+
+    if (!r->sendfile) {
+        return 1;
+    }
+
+    if ((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
+        && (!(hunk->type & NGX_HUNK_IN_MEMORY)))
+    {
+        return 1;
+    }
+
+
+    if ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)
+        && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
+
 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src,
                                             int sendfile)
 {
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 3374512..0778c66 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -49,17 +49,17 @@
     { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection) },
     { ngx_string("If-Modified-Since"),
                          offsetof(ngx_http_headers_in_t, if_modified_since) },
+    { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent) },
+
     { ngx_string("Content-Length"),
                             offsetof(ngx_http_headers_in_t, content_length) },
     { ngx_string("Accept-Encoding"),
                            offsetof(ngx_http_headers_in_t, accept_encoding) },
-
     { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range) },
 #if 0
     { ngx_string("If-Range"), offsetof(ngx_http_headers_in_t, if_range) },
 #endif
 
-    { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent) },
     { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive) },
 
     { ngx_null_string, 0 }
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 913a036..eb0d2d5 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -66,12 +66,12 @@
     ngx_table_elt_t  *host;
     ngx_table_elt_t  *connection;
     ngx_table_elt_t  *if_modified_since;
+    ngx_table_elt_t  *user_agent;
+
     ngx_table_elt_t  *content_length;
+    ngx_table_elt_t  *accept_encoding;
     ngx_table_elt_t  *range;
 
-    ngx_table_elt_t  *accept_encoding;
-
-    ngx_table_elt_t  *user_agent;
     ngx_table_elt_t  *keep_alive;
 
     size_t            host_name_len;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index a45d361..2b274d5 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -154,7 +154,7 @@
 {
     int           err, rc;
     ngx_hunk_t   *h;
-    ngx_chain_t  *out, **le, *ce;
+    ngx_chain_t  *out, **ll, *cl;
 
     r->headers_out.status = error;
 
@@ -219,15 +219,15 @@
     }
 
     out = NULL;
-    le = NULL;
+    ll = NULL;
 
     ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
     h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
     h->pos = error_pages[err].data;
     h->last = error_pages[err].data + error_pages[err].len;
 
-    ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
-    ngx_chain_add_ce(out, le, ce);
+    ngx_alloc_link_and_set_hunk(cl, h, r->pool, NGX_ERROR);
+    ngx_chain_add_link(out, ll, cl);
 
 
     ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
@@ -235,8 +235,8 @@
     h->pos = error_tail;
     h->last = error_tail + sizeof(error_tail) - 1;
 
-    ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
-    ngx_chain_add_ce(out, le, ce);
+    ngx_alloc_link_and_set_hunk(cl, h, r->pool, NGX_ERROR);
+    ngx_chain_add_link(out, ll, cl);
 
     if (/* STUB: "msie_padding on/off" */ 1
         && r->http_version >= NGX_HTTP_VERSION_10
@@ -249,8 +249,8 @@
         h->pos = msie_stub;
         h->last = msie_stub + sizeof(msie_stub) - 1;
 
-        ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
-        ngx_chain_add_ce(out, le, ce);
+        ngx_alloc_link_and_set_hunk(cl, h, r->pool, NGX_ERROR);
+        ngx_chain_add_link(out, ll, cl);
     }
 
     h->type |= NGX_HUNK_LAST;
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 109a9f4..b7cb16c 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -60,7 +60,7 @@
 {
     int                            last;
     off_t                          size, flush;
-    ngx_chain_t                   *ce, **le, *chain;
+    ngx_chain_t                   *cl, **ll, *chain;
     ngx_http_write_filter_ctx_t   *ctx;
     ngx_http_write_filter_conf_t  *conf;
 
@@ -74,20 +74,20 @@
 
     size = flush = 0;
     last = 0;
-    le = &ctx->out;
+    ll = &ctx->out;
 
-    /* find the size, the flush point and the last entry of the saved chain */
+    /* find the size, the flush point and the last link of the saved chain */
 
-    for (ce = ctx->out; ce; ce = ce->next) {
-        le = &ce->next;
+    for (cl = ctx->out; cl; cl = cl->next) {
+        ll = &cl->next;
 
-        size += ngx_hunk_size(ce->hunk);
+        size += ngx_hunk_size(cl->hunk);
 
-        if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
+        if (cl->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
             flush = size;
         }
 
-        if (ce->hunk->type & NGX_HUNK_LAST) {
+        if (cl->hunk->type & NGX_HUNK_LAST) {
             last = 1;
         }
     }
@@ -95,20 +95,17 @@
     /* add the new chain to the existent one */
 
     for (/* void */; in; in = in->next) {
-        ngx_test_null(ce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
+        ngx_alloc_link_and_set_hunk(cl, in->hunk, r->pool, NGX_ERROR);
+        *ll = cl;
+        ll = &cl->next;
 
-        ce->hunk = in->hunk;
-        ce->next = NULL;
-        *le = ce;
-        le = &ce->next;
+        size += ngx_hunk_size(cl->hunk);
 
-        size += ngx_hunk_size(ce->hunk);
-
-        if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
+        if (cl->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
             flush = size;
         }
 
-        if (ce->hunk->type & NGX_HUNK_LAST) {
+        if (cl->hunk->type & NGX_HUNK_LAST) {
             last = 1;
         }
     }
@@ -124,7 +121,7 @@
 
     /*
      * avoid the output if there is no last hunk, no flush point and
-     * size of the hunks is smaller then "buffer_output"
+     * the size of the hunks is smaller than "buffer_output" directive
      */
 
     if (!last && flush == 0 && size < conf->buffer_output) {