Mercurial > hg > nginx
comparison src/http/ngx_http_core_module.c @ 2400:2c2b79633ded
allow "~", "~*", "^~", and "=" before location name without space
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 11 Dec 2008 10:21:08 +0000 |
parents | 87b8c44906b5 |
children | dca164c4a868 |
comparison
equal
deleted
inserted
replaced
2399:aecf0755cee3 | 2400:2c2b79633ded |
---|---|
37 | 37 |
38 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, | 38 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, |
39 void *dummy); | 39 void *dummy); |
40 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, | 40 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, |
41 void *dummy); | 41 void *dummy); |
42 static ngx_int_t ngx_http_core_regex_location(ngx_conf_t *cf, | |
43 ngx_http_core_loc_conf_t *clcf, ngx_str_t *regex, ngx_uint_t caseless); | |
42 | 44 |
43 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, | 45 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, |
44 void *conf); | 46 void *conf); |
45 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, | 47 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, |
46 void *conf); | 48 void *conf); |
2180 | 2182 |
2181 static char * | 2183 static char * |
2182 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | 2184 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) |
2183 { | 2185 { |
2184 char *rv; | 2186 char *rv; |
2187 u_char *mod; | |
2188 size_t len; | |
2189 ngx_str_t *value, *name; | |
2185 ngx_uint_t i; | 2190 ngx_uint_t i; |
2186 ngx_str_t *value; | |
2187 ngx_conf_t save; | 2191 ngx_conf_t save; |
2188 ngx_http_module_t *module; | 2192 ngx_http_module_t *module; |
2189 ngx_http_conf_ctx_t *ctx, *pctx; | 2193 ngx_http_conf_ctx_t *ctx, *pctx; |
2190 ngx_http_core_loc_conf_t *clcf, *pclcf; | 2194 ngx_http_core_loc_conf_t *clcf, *pclcf; |
2191 | 2195 |
2223 clcf->loc_conf = ctx->loc_conf; | 2227 clcf->loc_conf = ctx->loc_conf; |
2224 | 2228 |
2225 value = cf->args->elts; | 2229 value = cf->args->elts; |
2226 | 2230 |
2227 if (cf->args->nelts == 3) { | 2231 if (cf->args->nelts == 3) { |
2228 if (value[1].len == 1 && value[1].data[0] == '=') { | 2232 |
2229 clcf->name = value[2]; | 2233 len = value[1].len; |
2234 mod = value[1].data; | |
2235 name = &value[2]; | |
2236 | |
2237 if (len == 1 && mod[0] == '=') { | |
2238 | |
2239 clcf->name = *name; | |
2230 clcf->exact_match = 1; | 2240 clcf->exact_match = 1; |
2231 | 2241 |
2232 } else if (value[1].len == 2 | 2242 } else if (len == 2 && mod[0] == '^' && mod[1] == '~') { |
2233 && value[1].data[0] == '^' | 2243 |
2234 && value[1].data[1] == '~') | 2244 clcf->name = *name; |
2235 { | |
2236 clcf->name = value[2]; | |
2237 clcf->noregex = 1; | 2245 clcf->noregex = 1; |
2238 | 2246 |
2239 } else if ((value[1].len == 1 && value[1].data[0] == '~') | 2247 } else if (len == 1 && mod[0] == '~') { |
2240 || (value[1].len == 2 | 2248 |
2241 && value[1].data[0] == '~' | 2249 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) { |
2242 && value[1].data[1] == '*')) | |
2243 { | |
2244 #if (NGX_PCRE) | |
2245 ngx_str_t err; | |
2246 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
2247 | |
2248 err.len = NGX_MAX_CONF_ERRSTR; | |
2249 err.data = errstr; | |
2250 | |
2251 clcf->regex = ngx_regex_compile(&value[2], | |
2252 value[1].len == 2 ? NGX_REGEX_CASELESS: 0, | |
2253 cf->pool, &err); | |
2254 | |
2255 if (clcf->regex == NULL) { | |
2256 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
2257 return NGX_CONF_ERROR; | 2250 return NGX_CONF_ERROR; |
2258 } | 2251 } |
2259 | 2252 |
2260 clcf->name = value[2]; | 2253 } else if (len == 2 && mod[0] == '~' && mod[1] == '*') { |
2261 #else | 2254 |
2262 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 2255 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) { |
2263 "the using of the regex \"%V\" " | 2256 return NGX_CONF_ERROR; |
2264 "requires PCRE library", &value[2]); | 2257 } |
2265 return NGX_CONF_ERROR; | |
2266 #endif | |
2267 | 2258 |
2268 } else { | 2259 } else { |
2269 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 2260 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2270 "invalid location modifier \"%V\"", &value[1]); | 2261 "invalid location modifier \"%V\"", &value[1]); |
2271 return NGX_CONF_ERROR; | 2262 return NGX_CONF_ERROR; |
2272 } | 2263 } |
2273 | 2264 |
2274 } else { | 2265 } else { |
2275 | 2266 |
2276 clcf->name = value[1]; | 2267 name = &value[1]; |
2277 | 2268 |
2278 if (value[1].data[0] == '@') { | 2269 if (name->data[0] == '=') { |
2279 clcf->named = 1; | 2270 |
2271 clcf->name.len = name->len - 1; | |
2272 clcf->name.data = name->data + 1; | |
2273 clcf->exact_match = 1; | |
2274 | |
2275 } else if (name->data[0] == '^' && name->data[1] == '~') { | |
2276 | |
2277 clcf->name.len = name->len - 2; | |
2278 clcf->name.data = name->data + 2; | |
2279 clcf->noregex = 1; | |
2280 | |
2281 } else if (name->data[0] == '~') { | |
2282 | |
2283 name->len--; | |
2284 name->data++; | |
2285 | |
2286 if (name->data[0] == '*') { | |
2287 | |
2288 name->len--; | |
2289 name->data++; | |
2290 | |
2291 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) { | |
2292 return NGX_CONF_ERROR; | |
2293 } | |
2294 | |
2295 } else { | |
2296 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) { | |
2297 return NGX_CONF_ERROR; | |
2298 } | |
2299 } | |
2300 | |
2301 } else { | |
2302 | |
2303 clcf->name = *name; | |
2304 | |
2305 if (name->data[0] == '@') { | |
2306 clcf->named = 1; | |
2307 } | |
2280 } | 2308 } |
2281 } | 2309 } |
2282 | 2310 |
2283 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | 2311 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; |
2284 | 2312 |
2312 "on server level only", | 2340 "on server level only", |
2313 &clcf->name); | 2341 &clcf->name); |
2314 return NGX_CONF_ERROR; | 2342 return NGX_CONF_ERROR; |
2315 } | 2343 } |
2316 | 2344 |
2345 len = pclcf->name.len; | |
2346 | |
2317 #if (NGX_PCRE) | 2347 #if (NGX_PCRE) |
2318 if (clcf->regex == NULL | 2348 if (clcf->regex == NULL |
2319 && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) | 2349 && ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0) |
2320 != 0) | |
2321 #else | 2350 #else |
2322 if (ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) | 2351 if (ngx_strncmp(clcf->name.data, pclcf->name.data, len) != 0) |
2323 != 0) | |
2324 #endif | 2352 #endif |
2325 { | 2353 { |
2326 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 2354 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2327 "location \"%V\" is outside location \"%V\"", | 2355 "location \"%V\" is outside location \"%V\"", |
2328 &clcf->name, &pclcf->name); | 2356 &clcf->name, &pclcf->name); |
2341 rv = ngx_conf_parse(cf, NULL); | 2369 rv = ngx_conf_parse(cf, NULL); |
2342 | 2370 |
2343 *cf = save; | 2371 *cf = save; |
2344 | 2372 |
2345 return rv; | 2373 return rv; |
2374 } | |
2375 | |
2376 | |
2377 static ngx_int_t | |
2378 ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf, | |
2379 ngx_str_t *regex, ngx_uint_t caseless) | |
2380 { | |
2381 #if (NGX_PCRE) | |
2382 ngx_str_t err; | |
2383 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
2384 | |
2385 err.len = NGX_MAX_CONF_ERRSTR; | |
2386 err.data = errstr; | |
2387 | |
2388 clcf->regex = ngx_regex_compile(regex, caseless ? NGX_REGEX_CASELESS: 0, | |
2389 cf->pool, &err); | |
2390 | |
2391 if (clcf->regex == NULL) { | |
2392 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
2393 return NGX_ERROR; | |
2394 } | |
2395 | |
2396 clcf->name = *regex; | |
2397 | |
2398 return NGX_OK; | |
2399 | |
2400 #else | |
2401 | |
2402 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2403 "the using of the regex \"%V\" requires PCRE library", | |
2404 regex); | |
2405 return NGX_ERROR; | |
2406 | |
2407 #endif | |
2346 } | 2408 } |
2347 | 2409 |
2348 | 2410 |
2349 static char * | 2411 static char * |
2350 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 2412 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |