changeset 436:9549fc9508e5

nginx-0.0.11-2004-09-23-10:32:00 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 23 Sep 2004 06:32:00 +0000
parents 5cdc4838d4e8
children 470270fa84d2
files src/core/ngx_buf.c src/core/ngx_palloc.c src/core/ngx_palloc.h src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_request.c src/http/ngx_http_request.h src/os/unix/ngx_freebsd_init.c
diffstat 8 files changed, 424 insertions(+), 461 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_buf.c
+++ b/src/core/ngx_buf.c
@@ -21,6 +21,7 @@ ngx_buf_t *ngx_create_temp_buf(ngx_pool_
     b->temporary = 1;
 
     /*
+
     b->file_pos = 0;
     b->file_last = 0;
 
@@ -28,7 +29,8 @@ ngx_buf_t *ngx_create_temp_buf(ngx_pool_
     b->shadow = NULL;
 
     b->tag = 0;
-    */
+
+     */
 
     return b;
 }
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -44,8 +44,9 @@ void ngx_destroy_pool(ngx_pool_t *pool)
      */
 
     for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
-        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
-                       "free: " PTR_FMT, p);
+        ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
+                       "free: " PTR_FMT ", unused: " SIZE_T_FMT,
+                       p, p->end - p->last);
 
         if (n == NULL) {
             break;
@@ -71,7 +72,7 @@ void *ngx_palloc(ngx_pool_t *pool, size_
     ngx_pool_large_t  *large, *last;
 
     if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL
-        && size <= (size_t) (pool->end - (char *) pool))
+        && size <= (size_t) (pool->end - (char *) pool) - sizeof(ngx_pool_t))
     {
         for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
             m = ngx_align(p->last);
@@ -106,7 +107,7 @@ void *ngx_palloc(ngx_pool_t *pool, size_
     last = NULL;
 
     if (pool->large) {
-        for (last = pool->large; /* void */; last = last->next) {
+        for (last = pool->large; /* void */ ; last = last->next) {
             if (last->alloc == NULL) {
                 large = last;
                 last = NULL;
@@ -150,7 +151,7 @@ void *ngx_palloc(ngx_pool_t *pool, size_
 }
 
 
-void ngx_pfree(ngx_pool_t *pool, void *p)
+ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p)
 {
     ngx_pool_large_t  *l;
 
@@ -160,8 +161,12 @@ void ngx_pfree(ngx_pool_t *pool, void *p
                            "free: " PTR_FMT, l->alloc);
             free(l->alloc);
             l->alloc = NULL;
+
+            return NGX_OK;
         }
     }
+
+    return NGX_DECLINED;
 }
 
 
--- a/src/core/ngx_palloc.h
+++ b/src/core/ngx_palloc.h
@@ -43,7 +43,7 @@ void ngx_destroy_pool(ngx_pool_t *pool);
 
 void *ngx_palloc(ngx_pool_t *pool, size_t size);
 void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
-void ngx_pfree(ngx_pool_t *pool, void *p);
+ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);
 
 
 #endif /* _NGX_PALLOC_H_INCLUDED_ */
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -96,18 +96,11 @@ static ngx_command_t  ngx_http_core_comm
       offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
       NULL },
 
-    { ngx_string("client_large_buffers"),
+    { ngx_string("large_client_header_buffers"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
       ngx_conf_set_bufs_slot,
       NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_core_srv_conf_t, client_large_buffers),
-      NULL },
-
-    { ngx_string("large_client_header"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
-      ngx_conf_set_flag_slot,
-      NGX_HTTP_SRV_CONF_OFFSET,
-      offsetof(ngx_http_core_srv_conf_t, large_client_header),
+      offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
       NULL },
 
     { ngx_string("restrict_host_names"),
@@ -241,6 +234,13 @@ static ngx_command_t  ngx_http_core_comm
       0,
       NULL },
 
+    { ngx_string("keepalive_buffers"),
+      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_core_loc_conf_t, keepalive_buffers),
+      NULL },
+
     { ngx_string("lingering_time"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
@@ -1275,7 +1275,6 @@ static void *ngx_http_core_create_srv_co
     cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
-    cscf->large_client_header = NGX_CONF_UNSET;
     cscf->restrict_host_names = NGX_CONF_UNSET_UINT;
 
     return cscf;
@@ -1333,7 +1332,7 @@ static char *ngx_http_core_merge_srv_con
     }
 
     ngx_conf_merge_size_value(conf->connection_pool_size,
-                              prev->connection_pool_size, 16384);
+                              prev->connection_pool_size, 2048);
     ngx_conf_merge_msec_value(conf->post_accept_timeout,
                               prev->post_accept_timeout, 30000);
     ngx_conf_merge_size_value(conf->request_pool_size,
@@ -1342,10 +1341,17 @@ static char *ngx_http_core_merge_srv_con
                               prev->client_header_timeout, 60000);
     ngx_conf_merge_size_value(conf->client_header_buffer_size,
                               prev->client_header_buffer_size, 1024);
-    ngx_conf_merge_bufs_value(conf->client_large_buffers,
-                              prev->client_large_buffers, 4, ngx_pagesize);
-    ngx_conf_merge_value(conf->large_client_header,
-                         prev->large_client_header, 1);
+    ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
+                              prev->large_client_header_buffers,
+                              4, ngx_pagesize);
+
+    if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "the \"large_client_header_buffers\" size must be "
+                           "equal to or bigger than \"connection_pool_size\"");
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_unsigned_value(conf->restrict_host_names,
                                   prev->restrict_host_names, 0);
 
@@ -1387,9 +1393,9 @@ static void *ngx_http_core_create_loc_co
     lcf->send_lowat = NGX_CONF_UNSET_SIZE;
     lcf->postpone_output = NGX_CONF_UNSET_SIZE;
     lcf->limit_rate = NGX_CONF_UNSET_SIZE;
-    lcf->discarded_buffer_size = NGX_CONF_UNSET_SIZE;
     lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
     lcf->keepalive_header = NGX_CONF_UNSET;
+    lcf->keepalive_buffers = NGX_CONF_UNSET;
     lcf->lingering_time = NGX_CONF_UNSET_MSEC;
     lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
     lcf->reset_timedout_connection = NGX_CONF_UNSET;
@@ -1474,12 +1480,11 @@ static char *ngx_http_core_merge_loc_con
     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
                               1460);
     ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
-    ngx_conf_merge_size_value(conf->discarded_buffer_size,
-                              prev->discarded_buffer_size, 1500);
     ngx_conf_merge_msec_value(conf->keepalive_timeout,
                               prev->keepalive_timeout, 75000);
     ngx_conf_merge_sec_value(conf->keepalive_header,
                               prev->keepalive_header, 0);
+    ngx_conf_merge_value(conf->keepalive_buffers, prev->keepalive_buffers, 1);
     ngx_conf_merge_msec_value(conf->lingering_time,
                               prev->lingering_time, 30000);
     ngx_conf_merge_msec_value(conf->lingering_timeout,
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -66,14 +66,12 @@ typedef struct {
     size_t                request_pool_size;
     size_t                client_header_buffer_size;
 
-    ngx_bufs_t            client_large_buffers;
+    ngx_bufs_t            large_client_header_buffers;
 
     ngx_msec_t            post_accept_timeout;
     ngx_msec_t            client_header_timeout;
 
     ngx_uint_t            restrict_host_names;
-
-    ngx_flag_t            large_client_header;
 } ngx_http_core_srv_conf_t;
 
 
@@ -153,7 +151,6 @@ struct ngx_http_core_loc_conf_s {
     ngx_str_t     default_type;
 
     size_t        client_max_body_size;    /* client_max_body_size */
-    size_t        discarded_buffer_size;   /* discarded_buffer_size */
     size_t        client_body_buffer_size; /* client_body_buffer_size */
     size_t        send_lowat;              /* send_lowat */
     size_t        postpone_output;         /* postpone_output */
@@ -162,10 +159,12 @@ struct ngx_http_core_loc_conf_s {
     ngx_msec_t    client_body_timeout;     /* client_body_timeout */
     ngx_msec_t    send_timeout;            /* send_timeout */
     ngx_msec_t    keepalive_timeout;       /* keepalive_timeout */
-    time_t        keepalive_header;        /* keepalive_timeout */
     ngx_msec_t    lingering_time;          /* lingering_time */
     ngx_msec_t    lingering_timeout;       /* lingering_timeout */
 
+    time_t        keepalive_header;        /* keepalive_timeout */
+
+    ngx_flag_t    keepalive_buffers;       /* keepalive_buffers */
     ngx_flag_t    sendfile;                /* sendfile */
     ngx_flag_t    tcp_nopush;              /* tcp_nopush */
     ngx_flag_t    reset_timedout_connection; /* reset_timedout_connection */
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -12,8 +12,8 @@ static void ngx_http_ssl_handshake(ngx_e
 static void ngx_http_process_request_line(ngx_event_t *rev);
 static void ngx_http_process_request_headers(ngx_event_t *rev);
 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_alloc_header_buf(ngx_http_request_t *r,
-                                           ngx_uint_t request_line);
+static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
+                                                    ngx_uint_t request_line);
 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
 
 static void ngx_http_set_write_handler(ngx_http_request_t *r);
@@ -195,19 +195,9 @@ static void ngx_http_init_request(ngx_ev
         return;
     }
 
-    if (c->data) {
-        hc = c->data;
-        r = hc->request;
-
-        ngx_memzero(r, sizeof(ngx_http_request_t));
-
-        r->pipeline = hc->pipeline;
-
-#if (NGX_STAT_STUB)
-        (*ngx_stat_reading)++;
-#endif
-
-    } else {
+    hc = c->data;
+
+    if (hc == NULL) {
         if (!(hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)))) {
 
 #if (NGX_STAT_STUB)
@@ -217,7 +207,24 @@ static void ngx_http_init_request(ngx_ev
             ngx_http_close_connection(c);
             return;
         }
-
+    }
+
+    r = hc->request;
+
+    if (r) {
+        ngx_memzero(r, sizeof(ngx_http_request_t));
+
+        r->pipeline = hc->pipeline;
+
+        if (hc->nbusy) {
+            r->header_in = hc->busy[0];
+        }
+
+#if (NGX_STAT_STUB)
+        (*ngx_stat_reading)++;
+#endif
+
+    } else {
         if (!(r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)))) {
 
 #if (NGX_STAT_STUB)
@@ -355,6 +362,10 @@ static void ngx_http_init_request(ngx_ev
         }
     }
 
+    if (r->header_in == NULL) {
+        r->header_in = c->buffer;
+    }
+
     if (!(r->pool = ngx_create_pool(cscf->request_pool_size, c->log))) {
         ngx_http_close_connection(c);
         return;
@@ -387,7 +398,6 @@ static void ngx_http_init_request(ngx_ev
 
     c->single_connection = 1;
     r->connection = c;
-    r->header_in = c->buffer;
 
     r->file.fd = NGX_INVALID_FILE;
 
@@ -470,13 +480,12 @@ static void ngx_http_ssl_handshake(ngx_e
 
 static void ngx_http_process_request_line(ngx_event_t *rev)
 {
-    u_char                    *p;
-    ssize_t                    n;
-    ngx_int_t                  rc, offset;
-    ngx_connection_t          *c;
-    ngx_http_request_t        *r;
-    ngx_http_log_ctx_t        *ctx;
-    ngx_http_core_srv_conf_t  *cscf;
+    u_char              *p;
+    ssize_t              n;
+    ngx_int_t            rc, rv, offset;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
+    ngx_http_log_ctx_t  *ctx;
 
     c = rev->data;
     r = c->data;
@@ -489,280 +498,218 @@ static void ngx_http_process_request_lin
         return;
     }
 
-    n = ngx_http_read_request_header(r);
-
-    if (n == NGX_AGAIN || n == NGX_ERROR) {
-        return;
-    }
-
-    rc = ngx_http_parse_request_line(r, r->header_in);
-
-    if (rc == NGX_OK) {
-
-        /* the request line has been parsed successfully */
-
-        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
-        if (r->http_version >= NGX_HTTP_VERSION_10
-            && cscf->large_client_header == 0
-            && r->header_in->pos == r->header_in->end)
-        {
-            /* no space for "\r\n" at the end of the header */
-
-            ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
-                                  NGX_HTTP_REQUEST_URI_TOO_LARGE);
-            return;
-        }
-
-
-        /* copy unparsed URI */
-
-        r->unparsed_uri.len = r->uri_end - r->uri_start;
-        r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
-        if (r->unparsed_uri.data == NULL) {
-            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            ngx_http_close_connection(c);
-            return;
-        }
-
-        ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
-                    r->unparsed_uri.len + 1);
-
-
-        /* copy URI */
-
-        if (r->args_start) {
-            r->uri.len = r->args_start - 1 - r->uri_start;
-        } else {
-            r->uri.len = r->uri_end - r->uri_start;
-        }
-
-        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;
-        }
-
-        if (r->complex_uri) {
-            rc = ngx_http_parse_complex_uri(r);
-
-            if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
-                ngx_http_close_request(r, rc);
-                ngx_http_close_connection(c);
+    rc = NGX_AGAIN;
+
+    for ( ;; ) {
+
+        if (rc == NGX_AGAIN) {
+            n = ngx_http_read_request_header(r);
+
+            if (n == NGX_AGAIN || n == NGX_ERROR) {
                 return;
             }
-
-            if (rc != NGX_OK) {
-                r->request_line.len = r->request_end - r->request_start;
-                r->request_line.data = r->request_start;
-
-                ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
-                return;
-            }
-
-        } else {
-            ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
         }
 
-
-        r->request_line.len = r->request_end - r->request_start;
-
-        if (cscf->large_client_header) {
-
-           /*
-            * if the large client headers are enabled then
-            * we need to copy the request line
-            */
-
-            r->request_line.data = ngx_palloc(r->pool, r->request_line.len + 1);
-            if (r->request_line.data == NULL) {
+        rc = ngx_http_parse_request_line(r, r->header_in);
+
+        if (rc == NGX_OK) {
+
+            /* the request line has been parsed successfully */
+
+            /* copy unparsed URI */
+
+            r->unparsed_uri.len = r->uri_end - r->uri_start;
+            r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
+            if (r->unparsed_uri.data == NULL) {
                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
                 ngx_http_close_connection(c);
                 return;
             }
 
-            ngx_cpystrn(r->request_line.data, r->request_start,
-                        r->request_line.len + 1);
-
-        } else {
-            r->request_line.data = r->request_start;
-            r->request_line.data[r->request_line.len] = '\0';
-        }
-
-        if (r->method == 0) {
-            r->method_name.len = r->method_end - r->request_start + 1;
-            r->method_name.data = r->request_line.data;
-        }
-
-        if (r->uri_ext) {
-
-            /* copy URI extention */
+            ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
+                        r->unparsed_uri.len + 1);
+
+
+            /* copy URI */
 
             if (r->args_start) {
-                r->exten.len = r->args_start - 1 - r->uri_ext;
+                r->uri.len = r->args_start - 1 - r->uri_start;
             } else {
-                r->exten.len = r->uri_end - r->uri_ext;
+                r->uri.len = r->uri_end - r->uri_start;
             }
 
-            if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
+            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;
             }
 
-            ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
-        }
-
-        if (r->args_start && r->uri_end > r->args_start) {
-
-            /* copy URI arguments */
-
-            r->args.len = r->uri_end - r->args_start;
-
-            if (!(r->args.data = ngx_palloc(r->pool, r->args.len + 1))) {
+            if (r->complex_uri) {
+                rc = ngx_http_parse_complex_uri(r);
+
+                if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
+                    ngx_http_close_request(r, rc);
+                    ngx_http_close_connection(c);
+                    return;
+                }
+
+                if (rc != NGX_OK) {
+                    r->request_line.len = r->request_end - r->request_start;
+                    r->request_line.data = r->request_start;
+
+                    ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
+                    return;
+                }
+
+            } else {
+                ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
+            }
+
+
+            r->request_line.len = r->request_end - r->request_start;
+            r->request_line.data = r->request_start;
+            r->request_line.data[r->request_line.len] = '\0';
+
+            if (r->method == 0) {
+                r->method_name.len = r->method_end - r->request_start + 1;
+                r->method_name.data = r->request_line.data;
+            }
+
+            if (r->uri_ext) {
+
+                /* copy URI extention */
+
+                if (r->args_start) {
+                    r->exten.len = r->args_start - 1 - r->uri_ext;
+                } else {
+                    r->exten.len = r->uri_end - r->uri_ext;
+                }
+
+                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;
+                }
+
+                ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
+            }
+
+            if (r->args_start && r->uri_end > r->args_start) {
+
+                /* copy URI arguments */
+
+                r->args.len = r->uri_end - r->args_start;
+
+                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;
+                }
+
+                ngx_cpystrn(r->args.data, r->args_start, r->args.len + 1);
+            }
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http request line: \"%s\"", r->request_line.data);
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http uri: \"%s\"", r->uri.data);
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http args: \"%s\"",
+                           r->args.data ? r->args.data : (u_char *) "");
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http exten: \"%s\"",
+                           r->exten.data ? r->exten.data : (u_char *) "");
+
+            if (r->http_version < NGX_HTTP_VERSION_10) {
+                rev->event_handler = ngx_http_block_read;
+                ngx_http_handler(r);
+                return;
+            }
+
+
+            if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
+                                         sizeof(ngx_table_elt_t)) == NGX_ERROR)
+            {
                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
                 ngx_http_close_connection(c);
                 return;
             }
 
-            ngx_cpystrn(r->args.data, r->args_start, r->args.len + 1);
-        }
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http request line: \"%s\"", r->request_line.data);
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http uri: \"%s\"", r->uri.data);
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http args: \"%s\"",
-                       r->args.data ? r->args.data : (u_char *) "");
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http exten: \"%s\"",
-                       r->exten.data ? r->exten.data : (u_char *) "");
-
-        if (r->http_version < NGX_HTTP_VERSION_10) {
-            rev->event_handler = ngx_http_block_read;
-            ngx_http_handler(r);
+
+            if (ngx_array_init(&r->headers_in.cookies, r->pool, 5,
+                                       sizeof(ngx_table_elt_t *)) == NGX_ERROR)
+            {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                ngx_http_close_connection(c);
+                return;
+            }
+
+
+            ctx = c->log->data;
+            ctx->action = "reading client request headers";
+            ctx->url = r->unparsed_uri.data;
+
+            rev->event_handler = ngx_http_process_request_headers;
+            ngx_http_process_request_headers(rev);
+
             return;
-        }
-
-
-        if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
-                                         sizeof(ngx_table_elt_t)) == NGX_ERROR)
-        {
-            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            ngx_http_close_connection(c);
-            return;
-        }
-
-
-        if (ngx_array_init(&r->headers_in.cookies, r->pool, 5,
-                                       sizeof(ngx_table_elt_t *)) == NGX_ERROR)
-        {
-            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            ngx_http_close_connection(c);
+
+        } else if (rc != NGX_AGAIN) {
+
+            /* there was error while a request line parsing */
+
+            for (p = r->request_start; p < r->header_in->last; p++) {
+                if (*p == CR || *p == LF) {
+                    break;
+                }
+            }
+
+            r->request_line.len = p - r->request_start;
+            r->request_line.data = r->request_start;
+
+            if (rc == NGX_HTTP_PARSE_INVALID_METHOD) {
+                r->http_version = NGX_HTTP_VERSION_10;
+            }
+
+            ngx_http_client_error(r, rc,
+                                  (rc == NGX_HTTP_PARSE_INVALID_METHOD) ?
+                                         NGX_HTTP_NOT_IMPLEMENTED:
+                                         NGX_HTTP_BAD_REQUEST);
             return;
         }
 
-
-        ctx = c->log->data;
-        ctx->action = "reading client request headers";
-        ctx->url = r->unparsed_uri.data;
-
-        if (cscf->large_client_header
-            && r->header_in->pos == r->header_in->last)
-        {
-            r->header_in->pos = r->header_in->last = r->header_in->start;
-        }
-
-        rev->event_handler = ngx_http_process_request_headers;
-        ngx_http_process_request_headers(rev);
-
-        return;
-
-    } else if (rc != NGX_AGAIN) {
-
-        /* there was error while a request line parsing */
-
-        for (p = r->request_start; p < r->header_in->last; p++) {
-            if (*p == CR || *p == LF) {
-                break;
+        /* NGX_AGAIN: a request line parsing is still incomplete */
+
+        if (r->header_in->last == r->header_in->end) {
+
+            rv = ngx_http_alloc_large_header_buffer(r, 1);
+
+            if (rv == NGX_ERROR) {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                ngx_http_close_connection(c);
+                return;
             }
-        }
-
-        r->request_line.len = p - r->request_start;
-        r->request_line.data = r->request_start;
-
-        if (rc == NGX_HTTP_PARSE_INVALID_METHOD) {
-            r->http_version = NGX_HTTP_VERSION_10;
-        }
-
-        ngx_http_client_error(r, rc,
-                              (rc == NGX_HTTP_PARSE_INVALID_METHOD) ?
-                                     NGX_HTTP_NOT_IMPLEMENTED:
-                                     NGX_HTTP_BAD_REQUEST);
-        return;
-    }
-
-    /* NGX_AGAIN: a request line parsing is still not complete */
-
-    if (r->header_in->last == r->header_in->end) {
-
-        /*
-         * If it's a pipelined request and a request line is not complete
-         * then we have to copy it to the start of the r->header_in buf.
-         * We have to copy it here only if the large client headers
-         * are enabled otherwise a request line had been already copied
-         * to the start of the r->header_in buf in ngx_http_set_keepalive().
-         */
-
-        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
-        if (cscf->large_client_header) {
-            offset = r->request_start - r->header_in->start;
-
-            if (offset == 0) {
+
+            if (rv == NGX_DECLINED) {
                 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
                                       NGX_HTTP_REQUEST_URI_TOO_LARGE);
                 return;
             }
-
-            ngx_memcpy(r->header_in->start, r->request_start,
-                       r->header_in->last - r->request_start);
-
-            r->header_in->pos -= offset;
-            r->header_in->last -= offset;
-            r->request_start = r->header_in->start;
-            r->request_end -= offset;
-            r->uri_start -= offset;
-            r->uri_end -= offset;
-            if (r->uri_ext) {
-                r->uri_ext -= offset;
-            }
-            if (r->args_start) {
-                r->args_start -= offset;
-            }
-
-        } else {
-            ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
-                                  NGX_HTTP_REQUEST_URI_TOO_LARGE);
         }
     }
-
-    return;
 }
 
 
 static void ngx_http_process_request_headers(ngx_event_t *rev)
 {
-    ssize_t                    n;
-    ngx_int_t                  rc, i, offset;
-    ngx_table_elt_t           *h, **cookie;
-    ngx_connection_t          *c;
-    ngx_http_request_t        *r;
-    ngx_http_core_srv_conf_t  *cscf;
+    ssize_t              n;
+    ngx_int_t            rc, rv, i, offset;
+    ngx_table_elt_t     *h, **cookie;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
 
     c = rev->data;
     r = c->data;
@@ -775,12 +722,29 @@ static void ngx_http_process_request_hea
         return;
     }
 
-    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
     rc = NGX_AGAIN;
 
     for ( ;; ) {
+
         if (rc == NGX_AGAIN) {
+
+            if (r->header_in->last == r->header_in->end) {
+
+                rv = ngx_http_alloc_large_header_buffer(r, 0);
+
+                if (rv == NGX_ERROR) {
+                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    ngx_http_close_connection(c);
+                    return;
+                }
+
+                if (rv == NGX_DECLINED) {
+                    ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
+                                          NGX_HTTP_BAD_REQUEST);
+                    return;
+                }
+            }
+
             n = ngx_http_read_request_header(r);
 
             if (n == NGX_AGAIN || n == NGX_ERROR) {
@@ -809,35 +773,17 @@ static void ngx_http_process_request_hea
             }
 
             h->key.len = r->header_name_end - r->header_name_start;
+            h->key.data = r->header_name_start;
+            h->key.data[h->key.len] = '\0';
+
             h->value.len = r->header_end - r->header_start;
-
-            /* if the large client headers are enabled then
-               we need to copy the header name and value */
-
-            if (cscf->large_client_header) {
-                h->key.data = ngx_palloc(r->pool,
-                                         h->key.len + 1 + h->value.len + 1);
-                if (h->key.data == NULL) {
-                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                    ngx_http_close_connection(c);
-                    return;
-                }
-
-                h->value.data = h->key.data + h->key.len + 1;
-                ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
-                ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
-
-            } else {
-                h->key.data = r->header_name_start;
-                h->key.data[h->key.len] = '\0';
-                h->value.data = r->header_start;
-                h->value.data[h->value.len] = '\0';
-            }
+            h->value.data = r->header_start;
+            h->value.data[h->value.len] = '\0';
 
             if (h->key.len == sizeof("Cookie") - 1
                 && ngx_strcasecmp(h->key.data, "Cookie") == 0)
             {
-                if (!(cookie = ngx_push_array(&r->headers_in.cookies))) {
+                if (!(cookie = ngx_array_push(&r->headers_in.cookies))) {
                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
                     ngx_http_close_connection(c);
                     return;
@@ -866,12 +812,6 @@ static void ngx_http_process_request_hea
                            "http header: \"%s: %s\"",
                            h->key.data, h->value.data);
 
-            if (cscf->large_client_header
-                && r->header_in->pos == r->header_in->last)
-            {
-                r->header_in->pos = r->header_in->last = r->header_in->start;
-            }
-
             continue;
 
         } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
@@ -935,58 +875,6 @@ static void ngx_http_process_request_hea
 
         /* NGX_AGAIN: a header line parsing is still not complete */
 
-        if (r->header_in->last == r->header_in->end) {
-
-#if 1
-            /* ngx_http_alloc_large_header_buffer() */
-
-            rc = ngx_http_alloc_header_buf(r, 0);
-
-            if (rc == NGX_ERROR) {
-                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                ngx_http_close_connection(c);
-                return;
-            }
-
-            if (rc == NGX_DECLINED) {
-                ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
-                                      NGX_HTTP_BAD_REQUEST);
-                return;
-            }
-#endif
-
-#if 0
-            /*
-             * if the large client headers are enabled then
-             * we need to compact r->header_in buf
-             */
-
-            if (cscf->large_client_header) {
-                offset = r->header_name_start - r->header_in->start;
-
-                if (offset == 0) {
-                    ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
-                                          NGX_HTTP_BAD_REQUEST);
-                    return;
-                }
-
-                ngx_memcpy(r->header_in->start, r->header_name_start,
-                           r->header_in->last - r->header_name_start);
-
-                r->header_in->last -= offset;
-                r->header_in->pos -= offset;
-                r->header_name_start = r->header_in->start;
-                r->header_name_end -= offset;
-                r->header_start -= offset;
-                r->header_end -= offset;
-
-            } else {
-                ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
-                                      NGX_HTTP_BAD_REQUEST);
-                return;
-            }
-#endif
-        }
     }
 }
 
@@ -1045,10 +933,8 @@ static ssize_t ngx_http_read_request_hea
 }
 
 
-#if 1
-
-static ngx_int_t ngx_http_alloc_header_buf(ngx_http_request_t *r,
-                                           ngx_uint_t request_line)
+static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
+                                                    ngx_uint_t request_line)
 {
     u_char                    *old, *new;
     ngx_int_t                  offset;
@@ -1059,11 +945,24 @@ static ngx_int_t ngx_http_alloc_header_b
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http alloc large header buffer");
 
+    if (request_line && r->state == 0) {
+
+        /* the client fills up the buffer with "\r\n" */
+
+        r->header_in->pos = r->header_in->start;
+        r->header_in->last = r->header_in->start;
+
+        return NGX_OK;
+    }
+
     old = request_line ? r->request_start : r->header_name_start;
 
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
-    if ((size_t) (r->header_in->pos - old) >= cscf->client_large_buffers.size) {
+    if (r->state != 0
+        && (size_t) (r->header_in->pos - old)
+                                     >= cscf->large_client_header_buffers.size)
+    {
         return NGX_DECLINED;
     }
 
@@ -1072,18 +971,18 @@ static ngx_int_t ngx_http_alloc_header_b
     if (hc->nfree) {
         b = hc->free[--hc->nfree];
 
-    } else if (hc->nbusy < cscf->client_large_buffers.num) {
+    } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
 
         if (hc->busy == NULL) {
             hc->busy = ngx_palloc(r->connection->pool,
-                         cscf->client_large_buffers.num * sizeof(ngx_buf_t *));
+                  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
             if (hc->busy == NULL) {
                 return NGX_ERROR;
             }
         }
 
         b = ngx_create_temp_buf(r->connection->pool,
-                                cscf->client_large_buffers.size);
+                                cscf->large_client_header_buffers.size);
         if (b == NULL) {
             return NGX_ERROR;
         }
@@ -1094,6 +993,18 @@ static ngx_int_t ngx_http_alloc_header_b
 
     hc->busy[hc->nbusy++] = b;
 
+    if (r->state == 0) {
+        /*
+         * r->state == 0 means that a header line was parsed successfully
+         * and we do not need to copy incomplete header line and
+         * to relocate the parser header pointers
+         */
+
+        r->header_in = b;
+
+        return NGX_OK;
+    }
+
     new = b->start;
 
     ngx_memcpy(new, old, r->header_in->last - old);
@@ -1103,11 +1014,31 @@ static ngx_int_t ngx_http_alloc_header_b
 
     if (request_line) {
         r->request_start = new;
-        r->request_end = new + (r->request_end - old);
+
+        if (r->request_end) {
+            r->request_end = new + (r->request_end - old);
+        }
+
+        r->method_end = new + (r->method_end - old);
 
         r->uri_start = new + (r->uri_start - old);
         r->uri_end = new + (r->uri_end - old);
 
+        if (r->schema_start) {
+            r->schema_start = new + (r->schema_start - old);
+            r->schema_end = new + (r->schema_end - old);
+        }
+
+        if (r->host_start) {
+            r->host_start = new + (r->host_start - old);
+            r->host_end = new + (r->host_end - old);
+        }
+
+        if (r->port_start) {
+            r->port_start = new + (r->port_start - old);
+            r->port_end = new + (r->port_end - old);
+        }
+
         if (r->uri_ext) {
             r->uri_ext = new + (r->uri_ext - old);
         }
@@ -1128,8 +1059,6 @@ static ngx_int_t ngx_http_alloc_header_b
     return NGX_OK;
 }
 
-#endif
-
 
 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
 {
@@ -1559,8 +1488,8 @@ static void ngx_http_read_discarded_body
 
 static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r)
 {
-    ssize_t                    size, n;
-    ngx_http_core_loc_conf_t  *clcf;
+    ssize_t  size, n;
+    u_char   buffer[NGX_HTTP_DISCARD_BUFFER_SIZE];
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http read discarded body");
@@ -1569,29 +1498,21 @@ static ngx_int_t ngx_http_read_discarded
         return NGX_OK;
     }
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-    if (r->discarded_buffer == NULL) {
-        r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size);
-        if (r->discarded_buffer == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-    }
 
     size = r->headers_in.content_length_n;
 
-    if (size > (ssize_t) clcf->discarded_buffer_size) {
-        size = (ssize_t) clcf->discarded_buffer_size;
+    if (size > NGX_HTTP_DISCARD_BUFFER_SIZE) {
+        size = NGX_HTTP_DISCARD_BUFFER_SIZE;
     }
 
-    n = r->connection->recv(r->connection, r->discarded_buffer, size);
+    n = r->connection->recv(r->connection, buffer, size);
 
     if (n == NGX_ERROR) {
 
         r->closed = 1;
 
         /*
-         * when a client request body is discarded then we already set
+         * if a client request body is discarded then we already set
          * some HTTP response code for client and we can ignore the error
          */
 
@@ -1610,8 +1531,9 @@ static ngx_int_t ngx_http_read_discarded
 
 static void ngx_http_set_keepalive(ngx_http_request_t *r)
 {
+    ngx_int_t                  i;
     size_t                     len;
-    ngx_buf_t                 *b;
+    ngx_buf_t                 *b, *f;
     ngx_event_t               *rev, *wev;
     ngx_connection_t          *c;
     ngx_http_connection_t     *hc;
@@ -1628,10 +1550,47 @@ static void ngx_http_set_keepalive(ngx_h
     ctx->action = "closing request";
 
     hc = r->http_connection;
+    b = r->header_in;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (b->pos < b->last || clcf->keepalive_buffers) {
+
+        /*
+         * the pipelined request or we like to keep the allocated
+         * ngx_http_request_t and the client header buffers while keepalive
+         */
+
+        if (b != c->buffer) {
+
+            /* move the large header buffers to the free list */
+
+            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+            if (hc->free == NULL) {
+                hc->free = ngx_palloc(c->pool,
+                  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
+                if (hc->free == NULL) {
+                    ngx_http_close_connection(c);
+                    return;
+                }
+            }
+
+            for (i = 0; i < hc->nbusy - 1; i++) {
+                f = hc->busy[i];
+                hc->free[hc->nfree++] = f;
+                f->pos = f->start;
+                f->last = f->start;
+            }
+
+            hc->busy[0] = b;
+            hc->nbusy = 1;
+        }
+    }
+
     ngx_http_close_request(r, 0);
     c->data = hc;
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
     ngx_add_timer(rev, clcf->keepalive_timeout);
 
     if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
@@ -1639,31 +1598,12 @@ static void ngx_http_set_keepalive(ngx_h
         return;
     }
 
-    b = c->buffer;
     wev = c->write;
     wev->event_handler = ngx_http_empty_handler;
 
-
     if (b->pos < b->last) {
 
-        /*
-         * The pipelined request.
-         *
-         * We do not know here whether the pipelined request is complete
-         * so if the large client headers are not enabled
-         * we need to copy the data to the start of c->buffer.
-         * This copy should be rare because clients that support
-         * pipelined requests (Mozilla 1.x, Opera 6.x+) are still rare.
-         */
-
-        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
-        if (!cscf->large_client_header) {
-            len = b->last - b->pos;
-            ngx_memcpy(b->start, b->pos, len);
-            b->pos = b->start;
-            b->last = b->start + len;
-        }
+        /* the pipelined request */
 
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
 
@@ -1676,6 +1616,36 @@ static void ngx_http_set_keepalive(ngx_h
     hc->pipeline = 0;
 
     b->pos = b->last = b->start;
+
+    if (!clcf->keepalive_buffers) {
+
+        if (ngx_pfree(c->pool, r) == NGX_OK) {
+            hc->request = NULL;
+        }
+
+        if (ngx_pfree(c->pool, c->buffer->start) == NGX_OK) {
+            c->buffer = NULL;
+        }
+
+        if (hc->free) {
+            for (i = 0; i < hc->nfree; i++) {
+                ngx_pfree(c->pool, hc->free[i]);
+                hc->free[i] = NULL;
+            }
+
+            hc->nfree = 0;
+        }
+
+        if (hc->busy) {
+            for (i = 0; i < hc->nbusy; i++) {
+                ngx_pfree(c->pool, hc->busy[i]);
+                hc->busy[i] = NULL;
+            }
+
+            hc->nbusy = 0;
+        }
+    }
+
     rev->event_handler = ngx_http_keepalive_handler;
 
     if (wev->active) {
@@ -1706,7 +1676,10 @@ static void ngx_http_set_keepalive(ngx_h
         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
     }
 
+#if 0
+    /* if "keepalive_buffers off" then we need some other place */
     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
+#endif
 
     if (rev->ready) {
         ngx_http_keepalive_handler(rev);
@@ -1716,9 +1689,11 @@ static void ngx_http_set_keepalive(ngx_h
 
 static void ngx_http_keepalive_handler(ngx_event_t *rev)
 {
-    ssize_t              n;
-    ngx_connection_t    *c;
-    ngx_http_log_ctx_t  *ctx;
+    ssize_t                 n;
+    ngx_buf_t              *b;
+    ngx_connection_t       *c;
+    ngx_http_log_ctx_t     *ctx;
+    ngx_http_connection_t  *hc;
 
     c = rev->data;
 
@@ -1729,6 +1704,9 @@ static void ngx_http_keepalive_handler(n
         return;
     }
 
+    hc = c->data;
+    b = hc->nbusy ? hc->busy[0] : c->buffer;
+
     /*
      * MSIE closes a keepalive connection with RST flag
      * so we ignore ECONNRESET here.
@@ -1737,7 +1715,7 @@ static void ngx_http_keepalive_handler(n
     c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
     ngx_set_socket_errno(0);
 
-    n = c->recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
+    n = c->recv(c, b->last, b->end - b->last);
     c->log_error = NGX_ERROR_INFO;
 
     if (n == NGX_AGAIN) {
@@ -1759,20 +1737,10 @@ static void ngx_http_keepalive_handler(n
         return;
     }
 
-    c->buffer->last += n;
+    b->last += n;
     rev->log->handler = ngx_http_log_error;
     ctx->action = "reading client request line";
 
-#if 0
-    if (!(hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)) {
-        ngx_http_close_connection(c);
-        return;
-    }
-
-    hc->request = r;
-    c->data = r;
-#endif
-
     ngx_http_init_request(rev);
 }
 
@@ -1840,6 +1808,7 @@ static void ngx_http_lingering_close_han
     ngx_connection_t          *c;
     ngx_http_request_t        *r;
     ngx_http_core_loc_conf_t  *clcf;
+    u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
 
     c = rev->data;
     r = c->data;
@@ -1860,32 +1829,8 @@ static void ngx_http_lingering_close_han
         return;
     }
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-    if (r->discarded_buffer == NULL) {
-
-        /* TODO: r->header_in->start (if large headers are enabled)
-                 or the end of parsed header (otherwise)
-                 instead of r->header_in->last */
-
-        if (r->header_in->end - r->header_in->last
-                                      >= (ssize_t) clcf->discarded_buffer_size)
-        {
-            r->discarded_buffer = r->header_in->last;
-
-        } else {
-            r->discarded_buffer = ngx_palloc(c->pool,
-                                             clcf->discarded_buffer_size);
-            if (r->discarded_buffer) {
-                ngx_http_close_request(r, 0);
-                ngx_http_close_connection(c);
-                return;
-            }
-        }
-    }
-
     do {
-        n = c->recv(c, r->discarded_buffer, clcf->discarded_buffer_size);
+        n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
 
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
 
@@ -1897,7 +1842,10 @@ static void ngx_http_lingering_close_han
 
     } while (rev->ready);
 
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
     timer *= 1000;
+
     if (timer > clcf->lingering_timeout) {
         timer = clcf->lingering_timeout;
     }
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -2,6 +2,10 @@
 #define _NGX_HTTP_REQUEST_H_INCLUDED_
 
 
+#define NGX_HTTP_DISCARD_BUFFER_SIZE       4096
+#define NGX_HTTP_LINGERING_BUFFER_SIZE     4096
+
+
 #define NGX_HTTP_VERSION_9                 9
 #define NGX_HTTP_VERSION_10                1000
 #define NGX_HTTP_VERSION_11                1001
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -66,9 +66,9 @@ void ngx_debug_init()
 #if (NGX_DEBUG && !NGX_NO_DEBUG_MALLOC)
 
 #if __FreeBSD_version >= 500014
-    _malloc_options = "J";
+    _malloc_options = "JAV";
 #else
-    malloc_options = "J";
+    malloc_options = "JAV";
 #endif
 
 #endif