nginx-0.3.58-RELEASE import

    *) Feature: the "error_page" directive supports the variables.

    *) Change: now the procfs interface instead of sysctl is used on Linux.

    *) Change: now the "Content-Type" header line is inherited from first
       response when the "X-Accel-Redirect" was used.

    *) Bugfix: the "error_page" directive did not redirect the 413 error.

    *) Bugfix: the trailing "?" did not remove old arguments if no new
       arguments were added to a rewritten URI.

    *) Bugfix: nginx could not run on 64-bit FreeBSD 7.0-CURRENT.
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 8d5ef95..98e098b 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2056,7 +2056,7 @@
 #if (NGX_FREEBSD)
     ssize_t *np = data;
 
-    if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
+    if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "\"fastcgi_send_lowat\" must be less than %d "
                            "(sysctl net.inet.tcp.sendspace)",
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index a6adc3c..0d80b31 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2343,7 +2343,7 @@
 #if (NGX_FREEBSD)
     ssize_t *np = data;
 
-    if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
+    if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "\"proxy_send_lowat\" must be less than %d "
                            "(sysctl net.inet.tcp.sendspace)",
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 8e287a6..53b6a92 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -116,10 +116,8 @@
         }
 
     } else {
-        if (r->headers_out.content_type.len == 0) {
-            if (ngx_http_set_content_type(r) != NGX_OK) {
-                XSRETURN_EMPTY;
-            }
+        if (ngx_http_set_content_type(r) != NGX_OK) {
+            XSRETURN_EMPTY;
         }
     }
 
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index b3e1175..6f979c6 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -226,13 +226,6 @@
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl handler");
 
-    /* mod_perl's content handler assumes that content type was already set */
-
-    if (ngx_http_set_content_type(r) != NGX_OK) {
-        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-        return;
-    }
-
     ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
 
     if (ctx == NULL) {
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 9d33d3a..764f35c 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -700,6 +700,7 @@
                    r->headers_in.content_length_n, clcf->client_max_body_size);
 
     if (r->headers_in.content_length_n != -1
+        && !r->discard_body
         && clcf->client_max_body_size
         && clcf->client_max_body_size < r->headers_in.content_length_n)
     {
@@ -929,6 +930,10 @@
     ngx_uint_t                 i, hash;
     ngx_http_core_loc_conf_t  *clcf;
 
+    if (r->headers_out.content_type.len) {
+        return NGX_OK;
+    }
+
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     if (r->exten.len) {
@@ -2688,10 +2693,12 @@
 {
     ngx_http_core_loc_conf_t *lcf = conf;
 
-    ngx_int_t             overwrite;
-    ngx_uint_t            i, n;
-    ngx_str_t            *value;
-    ngx_http_err_page_t  *err;
+    ngx_int_t                   overwrite;
+    ngx_str_t                  *value, uri;
+    ngx_uint_t                  i, n, nvar;
+    ngx_array_t                *uri_lengths, *uri_values;
+    ngx_http_err_page_t        *err;
+    ngx_http_script_compile_t   sc;
 
     if (lcf->error_pages == NULL) {
         lcf->error_pages = ngx_array_create(cf->pool, 4,
@@ -2732,6 +2739,28 @@
         n = 1;
     }
 
+    uri = value[cf->args->nelts - 1];
+    uri_lengths = NULL;
+    uri_values = NULL;
+
+    nvar = ngx_http_script_variables_count(&uri);
+
+    if (nvar) {
+        ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+        sc.cf = cf;
+        sc.source = &uri;
+        sc.lengths = &uri_lengths;
+        sc.values = &uri_values;
+        sc.variables = nvar;
+        sc.complete_lengths = 1;
+        sc.complete_values = 1;
+
+        if (ngx_http_script_compile(&sc) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
     for (i = 1; i < cf->args->nelts - n; i++) {
         err = ngx_array_push(lcf->error_pages);
         if (err == NULL) {
@@ -2755,7 +2784,9 @@
 
         err->overwrite = (overwrite >= 0) ? overwrite : err->status;
 
-        err->uri = value[cf->args->nelts - 1];
+        err->uri = uri;
+        err->uri_lengths = uri_lengths;
+        err->uri_values = uri_values;
     }
 
     return NGX_CONF_OK;
@@ -2838,7 +2869,7 @@
 #if (NGX_FREEBSD)
     ssize_t *np = data;
 
-    if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
+    if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                            "\"send_lowat\" must be less than %d "
                            "(sysctl net.inet.tcp.sendspace)",
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 5ea8103..35f8658 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -171,9 +171,11 @@
 
 
 typedef struct {
-    ngx_int_t     status;
-    ngx_int_t     overwrite;
-    ngx_str_t     uri;
+    ngx_int_t                  status;
+    ngx_int_t                  overwrite;
+    ngx_str_t                  uri;
+    ngx_array_t               *uri_lengths;
+    ngx_array_t               *uri_values;
 } ngx_http_err_page_t;
 
 
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 460cf39..fb183c6 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -405,7 +405,7 @@
     ssize_t       size;
     ngx_event_t  *rev;
 
-    if (r != r->main) {
+    if (r != r->main || r->discard_body) {
         return NGX_OK;
     }
 
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 1918397..2169c87 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -792,6 +792,10 @@
 
     } else {
         e->buf.len = e->pos - e->buf.data;
+
+        if (!code->add_args) {
+            r->args.len = 0;
+        }
     }
 
     if (e->log) {
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 734ad69..dfff641 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -295,8 +295,9 @@
 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
 {
     ngx_int_t                  rc;
-    ngx_uint_t                 i, err, msie_padding;
     ngx_buf_t                 *b;
+    ngx_str_t                 *uri;
+    ngx_uint_t                 i, err, msie_padding;
     ngx_chain_t               *out, *cl;
     ngx_http_err_page_t       *err_page;
     ngx_http_core_loc_conf_t  *clcf;
@@ -349,9 +350,20 @@
 
                 r->method = NGX_HTTP_GET;
 
-                if (err_page[i].uri.data[0] == '/') {
-                    return ngx_http_internal_redirect(r, &err_page[i].uri,
-                                                      NULL);
+                uri = &err_page[i].uri;
+
+                if (err_page[i].uri_lengths) {
+                    if (ngx_http_script_run(r, uri,
+                                            err_page[i].uri_lengths->elts, 0,
+                                            err_page[i].uri_values->elts)
+                        == NULL)
+                    {
+                        return NGX_ERROR;
+                    }
+                }
+
+                if (uri->data[0] == '/') {
+                    return ngx_http_internal_redirect(r, uri, NULL);
                 }
 
                 r->headers_out.location =
@@ -364,10 +376,10 @@
                     r->headers_out.location->hash = 1;
                     r->headers_out.location->key.len = sizeof("Location") - 1;
                     r->headers_out.location->key.data = (u_char *) "Location";
-                    r->headers_out.location->value = err_page[i].uri;
+                    r->headers_out.location->value = *uri;
 
                 } else {
-                    error = NGX_HTTP_INTERNAL_SERVER_ERROR;
+                    return NGX_ERROR;
                 }
             }
         }
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 5e22f2d..d5b7aee 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -110,7 +110,7 @@
     { ngx_string("Content-Type"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, content_type),
-                 ngx_http_upstream_copy_content_type, 0, 0 },
+                 ngx_http_upstream_copy_content_type, 0, 1 },
 
     { ngx_string("Content-Length"),
                  ngx_http_upstream_process_header_line,