nginx-0.3.48-RELEASE import

    *) Change: now the ngx_http_charset_module works for subrequests, if
       the response has no "Content-Type" header line.

    *) Bugfix: if the "proxy_pass" directive has no URI part, then the
       "proxy_redirect default" directive add the unnecessary slash in
       start of the rewritten redirect.

    *) Bugfix: the internal redirect always transform client's HTTP method
       to GET, now the transformation is made for the "X-Accel-Redirect"
       redirects only and if the method is not HEAD; the bug had appeared
       in 0.3.42.

    *) Bugfix: the ngx_http_perl_module could not be built, if the perl was
       built with the threads support; the bug had appeared in 0.3.46.
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 3c9e01b..c7aa14c 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -154,7 +154,7 @@
     ngx_uint_t                     i;
     ngx_http_charset_t            *charsets;
     ngx_http_charset_ctx_t        *ctx;
-    ngx_http_charset_loc_conf_t   *lcf;
+    ngx_http_charset_loc_conf_t   *lcf, *mlcf;
     ngx_http_charset_main_conf_t  *mcf;
 
     mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
@@ -162,9 +162,9 @@
     ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
 
     if (ctx == NULL) {
-        lcf = ngx_http_get_module_loc_conf(r->main,
-                                           ngx_http_charset_filter_module);
-        charset = lcf->charset;
+        mlcf = ngx_http_get_module_loc_conf(r->main,
+                                            ngx_http_charset_filter_module);
+        charset = mlcf->charset;
 
         if (charset == NGX_HTTP_NO_CHARSET) {
             return ngx_http_next_header_filter(r);
@@ -174,19 +174,30 @@
         charset = ctx->charset;
     }
 
-    if (r->headers_out.content_type.len == 0) {
-        return ngx_http_next_header_filter(r);
-    }
-
-    if (ngx_strncasecmp(r->headers_out.content_type.data, "text/", 5) != 0
-        && ngx_strncasecmp(r->headers_out.content_type.data,
-                           "application/x-javascript", 24) != 0)
-    {
-        return ngx_http_next_header_filter(r);
-    }
-
     charsets = mcf->charsets.elts;
 
+    if (r == r->main) {
+        if (r->headers_out.content_type.len == 0) {
+            return ngx_http_next_header_filter(r);
+        }
+
+        if (ngx_strncasecmp(r->headers_out.content_type.data, "text/", 5) != 0
+            && ngx_strncasecmp(r->headers_out.content_type.data,
+                               "application/x-javascript", 24) != 0)
+        {
+            return ngx_http_next_header_filter(r);
+        }
+
+    } else {
+        if (r->headers_out.content_type.len == 0) {
+            mlcf = ngx_http_get_module_loc_conf(r->main,
+                                                ngx_http_charset_filter_module);
+            source_charset = mlcf->source_charset;
+
+            goto found;
+        }
+    }
+
     lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
 
     len = 0;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index f5fb918..31a4355 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1349,7 +1349,9 @@
 
     p = ngx_copy(p, h->value.data, prefix);
 
-    p = ngx_copy(p, pr->replacement.text.data, pr->replacement.text.len);
+    if (pr->replacement.text.len) {
+        p = ngx_copy(p, pr->replacement.text.data, pr->replacement.text.len);
+    }
 
     ngx_memcpy(p, h->value.data + prefix + pr->redirect.len,
                h->value.len - pr->redirect.len - prefix);
@@ -1694,7 +1696,14 @@
 
             pr->handler = ngx_http_proxy_rewrite_redirect_text;
             pr->redirect = conf->upstream.url;
-            pr->replacement.text = conf->upstream.location;
+
+            if (conf->upstream.uri.len) {
+                pr->replacement.text = conf->upstream.location;
+
+            } else {
+                pr->replacement.text.len = 0;
+                pr->replacement.text.data = NULL;
+            }
         }
     }
 
@@ -2263,7 +2272,14 @@
 
         pr->handler = ngx_http_proxy_rewrite_redirect_text;
         pr->redirect = plcf->upstream.url;
-        pr->replacement.text = plcf->upstream.location;
+
+        if (plcf->upstream.uri.len) {
+            pr->replacement.text = plcf->upstream.location;
+
+        } else {
+            pr->replacement.text.len = 0;
+            pr->replacement.text.data = NULL;
+        }
 
         return NGX_CONF_OK;
     }
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 975c727..91a9c85 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -34,6 +34,12 @@
 } ngx_http_perl_variable_t;
 
 
+typedef struct {
+    SV                *sv;
+    PerlInterpreter   *perl;
+} ngx_http_perl_cleanup_t;
+
+
 #if (NGX_HTTP_SSI)
 static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
     ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);
@@ -51,7 +57,7 @@
 static PerlInterpreter *
     ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
     ngx_log_t *log);
-static ngx_int_t ngx_http_perl_run_requires(ngx_array_t *requires,
+static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires,
     ngx_log_t *log);
 static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r,
     SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv);
@@ -478,7 +484,7 @@
 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
 {
 #if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
-    ngx_pool_cleanup_t  *cln;
+    ngx_pool_cleanup_t       *cln;
 
     cln = ngx_pool_cleanup_add(cf->pool, 0);
     if (cln == NULL) {
@@ -504,7 +510,9 @@
 #if !(NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
 
     if (perl) {
-        if (ngx_http_perl_run_requires(&pmcf->requires, cf->log) != NGX_OK) {
+        if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log)
+            != NGX_OK)
+        {
             return NGX_CONF_ERROR;
         }
 
@@ -613,7 +621,7 @@
         goto fail;
     }
 
-    if (ngx_http_perl_run_requires(&pmcf->requires, log) != NGX_OK) {
+    if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, log) != NGX_OK) {
         goto fail;
     }
 
@@ -634,7 +642,7 @@
 
 
 static ngx_int_t
-ngx_http_perl_run_requires(ngx_array_t *requires, ngx_log_t *log)
+ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log)
 {
     char       **script;
     STRLEN       len;
@@ -870,9 +878,11 @@
 static void
 ngx_http_perl_cleanup_sv(void *data)
 {
-    SV  *sv = data;
+    ngx_http_perl_cleanup_t  *cln = data;
 
-    SvREFCNT_dec(sv);
+    dTHXa(cln->perl);
+
+    SvREFCNT_dec(cln->sv);
 }
 
 
@@ -967,6 +977,7 @@
 
     ngx_str_t                  *value;
     ngx_pool_cleanup_t         *cln;
+    ngx_http_perl_cleanup_t    *pcln;
     ngx_http_core_loc_conf_t   *clcf;
     ngx_http_perl_main_conf_t  *pmcf;
 
@@ -986,7 +997,7 @@
         }
     }
 
-    cln = ngx_pool_cleanup_add(cf->pool, 0);
+    cln = ngx_pool_cleanup_add(cf->pool, sizeof(ngx_http_perl_cleanup_t));
     if (cln == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -1012,7 +1023,9 @@
     }
 
     cln->handler = ngx_http_perl_cleanup_sv;
-    cln->data = plcf->sub;
+    pcln = cln->data;
+    pcln->sv = plcf->sub;
+    pcln->perl = pmcf->perl;
 
     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
     clcf->handler = ngx_http_perl_handler;
@@ -1028,6 +1041,7 @@
     ngx_str_t                  *value;
     ngx_pool_cleanup_t         *cln;
     ngx_http_variable_t        *v;
+    ngx_http_perl_cleanup_t    *pcln;
     ngx_http_perl_variable_t   *pv;
     ngx_http_perl_main_conf_t  *pmcf;
 
@@ -1065,7 +1079,7 @@
         }
     }
 
-    cln = ngx_pool_cleanup_add(cf->pool, 0);
+    cln = ngx_pool_cleanup_add(cf->pool, sizeof(ngx_http_perl_cleanup_t));
     if (cln == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -1091,7 +1105,9 @@
     }
 
     cln->handler = ngx_http_perl_cleanup_sv;
-    cln->data = pv->sub;
+    pcln = cln->data;
+    pcln->sv = pv->sub;
+    pcln->perl = pmcf->perl;
 
     v->get_handler = ngx_http_perl_variable;
     v->data = (uintptr_t) pv;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 6cbbf09..f08ec45 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1330,7 +1330,6 @@
     ngx_http_update_location_config(r);
 
     r->internal = 1;
-    r->method = NGX_HTTP_GET;
 
     r->uri_changes--;
 
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 4f7d24f..c606ec8 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1470,7 +1470,6 @@
         || rc == NGX_HTTP_CREATED
         || rc == NGX_HTTP_NO_CONTENT)
     {
-
         if (rc == NGX_HTTP_CLOSE) {
             ngx_http_close_request(r, rc);
             return;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 9826ece..94793d7 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -833,6 +833,10 @@
 
     e->status = code->status;
 
+    if (code->status == NGX_HTTP_NO_CONTENT) {
+        e->request->header_only = 1;
+    }
+
     e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t);
 }
 
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 4b914ab..e53d32c 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1160,6 +1160,10 @@
             r->zero_in_uri = 1;
         }
 
+        if (r->method != NGX_HTTP_HEAD) {
+            r->method = NGX_HTTP_GET;
+        }
+
         ngx_http_internal_redirect(r, uri, &args);
         return;
     }