diff src/http/modules/ngx_http_fastcgi_module.c @ 430:dac47e9ef0d5 NGINX_0_7_27

nginx 0.7.27 *) Feature: the "try_files" directive. *) Feature: variables support in the "fastcgi_pass" directive. *) Feature: now the $geo variable may get an address from a variable. Thanks to Andrei Nigmatulin. *) Feature: now a location's modifier may be used without space before name. *) Feature: the $upstream_response_length variable. *) Bugfix: now a "add_header" directive does not add an empty value. *) Bugfix: if zero length static file was requested, then nginx just closed connection; the bug had appeared in 0.7.25. *) Bugfix: a MOVE method could not move file in non-existent directory. *) Bugfix: a segmentation fault occurred in worker process, if no one named location was defined in server, but some one was used in an error_page directive. Thanks to Sergey Bochenkov.
author Igor Sysoev <http://sysoev.ru>
date Mon, 15 Dec 2008 00:00:00 +0300
parents b246022ef454
children 49a0eb7ce20c
line wrap: on
line diff
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -19,6 +19,9 @@ typedef struct {
     ngx_array_t                   *params;
     ngx_array_t                   *params_source;
     ngx_array_t                   *catch_stderr;
+
+    ngx_array_t                   *fastcgi_lengths;
+    ngx_array_t                   *fastcgi_values;
 } ngx_http_fastcgi_loc_conf_t;
 
 
@@ -103,6 +106,8 @@ typedef struct {
 } ngx_http_fastcgi_request_start_t;
 
 
+static ngx_int_t ngx_http_fastcgi_eval(ngx_http_request_t *r,
+    ngx_http_fastcgi_loc_conf_t *flcf);
 static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r);
 static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r);
 static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r);
@@ -414,14 +419,25 @@ ngx_http_fastcgi_handler(ngx_http_reques
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
+    ngx_http_set_ctx(r, NULL, ngx_http_fastcgi_module);
 
     u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
     if (u == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    u->schema = flcf->upstream.schema;
+    r->upstream = u;
+
+    flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
+
+    if (flcf->fastcgi_lengths) {
+        if (ngx_http_fastcgi_eval(r, flcf) != NGX_OK) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+    }
+
+    u->schema.len = sizeof("fastcgi://") - 1;
+    u->schema.data = (u_char *) "fastcgi://";
 
     u->peer.log = r->connection->log;
     u->peer.log_error = NGX_ERROR_ERR;
@@ -449,8 +465,6 @@ ngx_http_fastcgi_handler(ngx_http_reques
     u->pipe->input_filter = ngx_http_fastcgi_input_filter;
     u->pipe->input_ctx = r;
 
-    r->upstream = u;
-
     rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
@@ -462,6 +476,50 @@ ngx_http_fastcgi_handler(ngx_http_reques
 
 
 static ngx_int_t
+ngx_http_fastcgi_eval(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf)
+{
+    ngx_url_t  u;
+
+    ngx_memzero(&u, sizeof(ngx_url_t));
+
+    if (ngx_http_script_run(r, &u.url, flcf->fastcgi_lengths->elts, 0,
+                            flcf->fastcgi_values->elts)
+        == NULL)
+    {
+        return NGX_ERROR;
+    }
+
+    u.no_resolve = 1;
+
+    if (ngx_parse_url(r->pool, &u) != NGX_OK) {
+         if (u.err) {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "%s in upstream \"%V\"", u.err, &u.url);
+        }
+
+        return NGX_ERROR;
+    }
+
+    if (u.no_port) {
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "no port in upstream \"%V\"", &u.url);
+        return NGX_ERROR;
+    }
+
+    r->upstream->resolved = ngx_pcalloc(r->pool,
+                                        sizeof(ngx_http_upstream_resolved_t));
+    if (r->upstream->resolved == NULL) {
+        return NGX_ERROR;
+    }
+
+    r->upstream->resolved->host = u.host;
+    r->upstream->resolved->port = u.port;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_fastcgi_create_request(ngx_http_request_t *r)
 {
     off_t                         file_pos;
@@ -1631,7 +1689,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_con
      *     conf->upstream.next_upstream = 0;
      *     conf->upstream.temp_path = NULL;
      *     conf->upstream.hide_headers_hash = { NULL, 0 };
-     *     conf->upstream.schema = { 0, NULL };
      *     conf->upstream.uri = { 0, NULL };
      *     conf->upstream.location = NULL;
      *     conf->upstream.store_lengths = NULL;
@@ -1861,7 +1918,11 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf
 
     if (conf->upstream.upstream == NULL) {
         conf->upstream.upstream = prev->upstream.upstream;
-        conf->upstream.schema = prev->upstream.schema;
+    }
+
+    if (conf->fastcgi_lengths == NULL) {
+        conf->fastcgi_lengths = prev->fastcgi_lengths;
+        conf->fastcgi_values = prev->fastcgi_values;
     }
 
     if (conf->params_source == NULL) {
@@ -2044,35 +2105,56 @@ ngx_http_fastcgi_script_name_variable(ng
 static char *
 ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
-    ngx_http_fastcgi_loc_conf_t *lcf = conf;
-
-    ngx_url_t                    u;
-    ngx_str_t                   *value;
-    ngx_http_core_loc_conf_t    *clcf;
-
-    if (lcf->upstream.schema.len) {
+    ngx_http_fastcgi_loc_conf_t *flcf = conf;
+
+    ngx_url_t                   u;
+    ngx_str_t                  *value, *url;
+    ngx_uint_t                  n;
+    ngx_http_core_loc_conf_t   *clcf;
+    ngx_http_script_compile_t   sc;
+
+    if (flcf->upstream.upstream || flcf->fastcgi_lengths) {
         return "is duplicate";
     }
 
+    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+    clcf->handler = ngx_http_fastcgi_handler;
+
     value = cf->args->elts;
 
+    url = &value[1];
+
+    n = ngx_http_script_variables_count(url);
+
+    if (n) {
+
+        ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+        sc.cf = cf;
+        sc.source = url;
+        sc.lengths = &flcf->fastcgi_lengths;
+        sc.values = &flcf->fastcgi_values;
+        sc.variables = n;
+        sc.complete_lengths = 1;
+        sc.complete_values = 1;
+
+        if (ngx_http_script_compile(&sc) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+
+        return NGX_CONF_OK;
+    }
+
     ngx_memzero(&u, sizeof(ngx_url_t));
 
     u.url = value[1];
     u.no_resolve = 1;
 
-    lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
-    if (lcf->upstream.upstream == NULL) {
+    flcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
+    if (flcf->upstream.upstream == NULL) {
         return NGX_CONF_ERROR;
     }
 
-    lcf->upstream.schema.len = sizeof("fastcgi://") - 1;
-    lcf->upstream.schema.data = (u_char *) "fastcgi://";
-
-    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
-
-    clcf->handler = ngx_http_fastcgi_handler;
-
     if (clcf->name.data[clcf->name.len - 1] == '/') {
         clcf->auto_redirect = 1;
     }