Klaus Demo nginx / 1b8267c
fastcgi_split_path_info Igor Sysoev 13 years ago
1 changed file(s) with 207 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
2121
2222 ngx_array_t *fastcgi_lengths;
2323 ngx_array_t *fastcgi_values;
24
25 #if (NGX_PCRE)
26 ngx_regex_t *split_regex;
27 ngx_str_t split_name;
28 #endif
2429 } ngx_http_fastcgi_loc_conf_t;
2530
2631
5560 ngx_uint_t fastcgi_stdout; /* unsigned :1 */
5661
5762 ngx_array_t *split_parts;
63
64 ngx_str_t script_name;
65 ngx_str_t path_info;
5866 } ngx_http_fastcgi_ctx_t;
5967
6068
124132 void *parent, void *child);
125133 static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
126134 ngx_http_variable_value_t *v, uintptr_t data);
135 static ngx_int_t ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
136 ngx_http_variable_value_t *v, uintptr_t data);
137 static ngx_int_t ngx_http_fastcgi_split(ngx_http_request_t *r,
138 ngx_http_fastcgi_ctx_t *f, ngx_http_fastcgi_loc_conf_t *flcf);
127139
128140 static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
129141 void *conf);
142 static char *ngx_http_fastcgi_split_path_info(ngx_conf_t *cf,
143 ngx_command_t *cmd, void *conf);
130144 static char *ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
131145 void *conf);
132146 static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
168182 ngx_conf_set_str_slot,
169183 NGX_HTTP_LOC_CONF_OFFSET,
170184 offsetof(ngx_http_fastcgi_loc_conf_t, index),
185 NULL },
186
187 { ngx_string("fastcgi_split_path_info"),
188 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
189 ngx_http_fastcgi_split_path_info,
190 NGX_HTTP_LOC_CONF_OFFSET,
191 0,
171192 NULL },
172193
173194 { ngx_string("fastcgi_store"),
389410 };
390411
391412
392 static ngx_str_t ngx_http_fastcgi_script_name =
393 ngx_string("fastcgi_script_name");
413 static ngx_http_variable_t ngx_http_fastcgi_vars[] = {
414
415 { ngx_string("fastcgi_script_name"), NULL,
416 ngx_http_fastcgi_script_name_variable, 0,
417 NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
418
419 { ngx_string("fastcgi_path_info"), NULL,
420 ngx_http_fastcgi_path_info_variable, 0,
421 NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
422
423 { ngx_null_string, NULL, NULL, 0, 0, 0 }
424 };
394425
395426
396427 static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
409440 {
410441 ngx_int_t rc;
411442 ngx_http_upstream_t *u;
443 ngx_http_fastcgi_ctx_t *f;
412444 ngx_http_fastcgi_loc_conf_t *flcf;
413445
414446 if (r->subrequest_in_memory) {
418450 return NGX_HTTP_INTERNAL_SERVER_ERROR;
419451 }
420452
421 ngx_http_set_ctx(r, NULL, ngx_http_fastcgi_module);
453 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
454 if (f == NULL) {
455 return NGX_ERROR;
456 }
457
458 ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
422459
423460 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
424461 if (u == NULL) {
932969
933970 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
934971
935 if (f == NULL) {
936 f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
937 if (f == NULL) {
938 return NGX_ERROR;
939 }
940
941 ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
942 }
943
944972 u = r->upstream;
945973
946974 for ( ;; ) {
16651693 static ngx_int_t
16661694 ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
16671695 {
1668 ngx_http_variable_t *var;
1669
1670 var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
1671 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE);
1672 if (var == NULL) {
1673 return NGX_ERROR;
1674 }
1675
1676 var->get_handler = ngx_http_fastcgi_script_name_variable;
1696 ngx_http_variable_t *var, *v;
1697
1698 for (v = ngx_http_fastcgi_vars; v->name.len; v++) {
1699 var = ngx_http_add_variable(cf, &v->name, v->flags);
1700 if (var == NULL) {
1701 return NGX_ERROR;
1702 }
1703
1704 var->get_handler = v->get_handler;
1705 var->data = v->data;
1706 }
16771707
16781708 return NGX_OK;
16791709 }
19321962 conf->fastcgi_values = prev->fastcgi_values;
19331963 }
19341964
1965 #if (NGX_PCRE)
1966 if (conf->split_regex == NULL) {
1967 conf->split_regex = prev->split_regex;
1968 conf->split_name = prev->split_name;
1969 }
1970 #endif
1971
19351972 if (conf->params_source == NULL) {
19361973 conf->flushes = prev->flushes;
19371974 conf->params_len = prev->params_len;
20702107 ngx_http_variable_value_t *v, uintptr_t data)
20712108 {
20722109 u_char *p;
2110 ngx_http_fastcgi_ctx_t *f;
20732111 ngx_http_fastcgi_loc_conf_t *flcf;
20742112
2075 if (r->uri.len) {
2113 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
2114 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
2115
2116 if (ngx_http_fastcgi_split(r, f, flcf) != NGX_OK) {
2117 return NGX_ERROR;
2118 }
2119
2120 if (f->script_name.len == 0
2121 || f->script_name.data[f->script_name.len - 1] != '/')
2122 {
2123 v->len = f->script_name.len;
20762124 v->valid = 1;
20772125 v->no_cacheable = 0;
20782126 v->not_found = 0;
2079
2080 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
2081
2082 if (r->uri.data[r->uri.len - 1] != '/') {
2083 v->len = r->uri.len;
2084 v->data = r->uri.data;
2085 return NGX_OK;
2086 }
2087
2088 v->len = r->uri.len + flcf->index.len;
2089
2090 v->data = ngx_pnalloc(r->pool, v->len);
2091 if (v->data == NULL) {
2092 return NGX_ERROR;
2093 }
2094
2095 p = ngx_copy(v->data, r->uri.data, r->uri.len);
2096 ngx_memcpy(p, flcf->index.data, flcf->index.len);
2097
2098 } else {
2099 v->len = 0;
2100 v->valid = 1;
2101 v->no_cacheable = 0;
2102 v->not_found = 0;
2103 v->data = NULL;
2127 v->data = f->script_name.data;
21042128
21052129 return NGX_OK;
21062130 }
21072131
2132 v->len = f->script_name.len + flcf->index.len;
2133
2134 v->data = ngx_pnalloc(r->pool, v->len);
2135 if (v->data == NULL) {
2136 return NGX_ERROR;
2137 }
2138
2139 p = ngx_copy(v->data, f->script_name.data, f->script_name.len);
2140 ngx_memcpy(p, flcf->index.data, flcf->index.len);
2141
21082142 return NGX_OK;
2143 }
2144
2145
2146 static ngx_int_t
2147 ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
2148 ngx_http_variable_value_t *v, uintptr_t data)
2149 {
2150 ngx_http_fastcgi_ctx_t *f;
2151 ngx_http_fastcgi_loc_conf_t *flcf;
2152
2153 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
2154 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
2155
2156 if (ngx_http_fastcgi_split(r, f, flcf) != NGX_OK) {
2157 return NGX_ERROR;
2158 }
2159
2160 v->len = f->path_info.len;
2161 v->valid = 1;
2162 v->no_cacheable = 0;
2163 v->not_found = 0;
2164 v->data = f->path_info.data;
2165
2166 return NGX_OK;
2167 }
2168
2169
2170 static ngx_int_t
2171 ngx_http_fastcgi_split(ngx_http_request_t *r, ngx_http_fastcgi_ctx_t *f,
2172 ngx_http_fastcgi_loc_conf_t *flcf)
2173 {
2174 #if (NGX_PCRE)
2175 ngx_int_t n;
2176 int captures[(1 + 2) * 3];
2177
2178 if (f->script_name.len) {
2179 return NGX_OK;
2180 }
2181
2182 if (flcf->split_regex == NULL) {
2183 f->script_name = r->uri;
2184 return NGX_OK;
2185 }
2186
2187 n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3);
2188
2189 if (n == NGX_REGEX_NO_MATCHED) {
2190 f->script_name = r->uri;
2191 return NGX_OK;
2192 }
2193
2194 if (n < 0) {
2195 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
2196 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
2197 n, &r->uri, &flcf->split_name);
2198 return NGX_ERROR;
2199 }
2200
2201 /* match */
2202
2203 f->script_name.len = captures[3] - captures[2];
2204 f->script_name.data = r->uri.data;
2205
2206 f->path_info.len = captures[5] - captures[4];
2207 f->path_info.data = r->uri.data + f->script_name.len;
2208
2209 return NGX_OK;
2210
2211 #else
2212
2213 f->script_name = r->uri;
2214
2215 return NGX_OK;
2216
2217 #endif
21092218 }
21102219
21112220
21672276 }
21682277
21692278 return NGX_CONF_OK;
2279 }
2280
2281
2282 static char *
2283 ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2284 {
2285 #if (NGX_PCRE)
2286 ngx_http_fastcgi_loc_conf_t *flcf = conf;
2287
2288 ngx_int_t n;
2289 ngx_str_t *value, err;
2290 u_char errstr[NGX_MAX_CONF_ERRSTR];
2291
2292 value = cf->args->elts;
2293
2294 flcf->split_name = value[1];
2295
2296 err.len = NGX_MAX_CONF_ERRSTR;
2297 err.data = errstr;
2298
2299 flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
2300
2301 if (flcf->split_regex == NULL) {
2302 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
2303 return NGX_CONF_ERROR;
2304 }
2305
2306 n = ngx_regex_capture_count(flcf->split_regex);
2307
2308 if (n < 0) {
2309 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2310 ngx_regex_capture_count_n " failed for "
2311 "pattern \"%V\"", &value[1]);
2312 return NGX_CONF_ERROR;
2313 }
2314
2315 if (n != 2) {
2316 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2317 "pattern \"%V\" must have 2 captures", &value[1]);
2318 return NGX_CONF_ERROR;
2319 }
2320
2321 return NGX_CONF_OK;
2322
2323 #else
2324
2325 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2326 "\"%V\" requires PCRE library", &cmd->name);
2327 return NGX_CONF_ERROR;
2328
2329 #endif
21702330 }
21712331
21722332