Mercurial > hg > nginx-mail
comparison src/http/ngx_http_script.c @ 665:0b460e61bdcd default tip
Merge with nginx 1.0.0.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:22:17 +0400 |
parents | b4dcae568a2a |
children |
comparison
equal
deleted
inserted
replaced
572:06419a2298a9 | 665:0b460e61bdcd |
---|---|
209 | 209 |
210 return NGX_OK; | 210 return NGX_OK; |
211 } | 211 } |
212 | 212 |
213 | 213 |
214 char * | |
215 ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
216 { | |
217 char *p = conf; | |
218 | |
219 ngx_str_t *value; | |
220 ngx_http_complex_value_t **cv; | |
221 ngx_http_compile_complex_value_t ccv; | |
222 | |
223 cv = (ngx_http_complex_value_t **) (p + cmd->offset); | |
224 | |
225 if (*cv != NULL) { | |
226 return "duplicate"; | |
227 } | |
228 | |
229 *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); | |
230 if (*cv == NULL) { | |
231 return NGX_CONF_ERROR; | |
232 } | |
233 | |
234 value = cf->args->elts; | |
235 | |
236 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
237 | |
238 ccv.cf = cf; | |
239 ccv.value = &value[1]; | |
240 ccv.complex_value = *cv; | |
241 | |
242 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
243 return NGX_CONF_ERROR; | |
244 } | |
245 | |
246 return NGX_CONF_OK; | |
247 } | |
248 | |
249 | |
250 ngx_int_t | |
251 ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates) | |
252 { | |
253 ngx_str_t val; | |
254 ngx_uint_t i; | |
255 ngx_http_complex_value_t *cv; | |
256 | |
257 if (predicates == NULL) { | |
258 return NGX_OK; | |
259 } | |
260 | |
261 cv = predicates->elts; | |
262 | |
263 for (i = 0; i < predicates->nelts; i++) { | |
264 if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) { | |
265 return NGX_ERROR; | |
266 } | |
267 | |
268 if (val.len && val.data[0] != '0') { | |
269 return NGX_DECLINED; | |
270 } | |
271 } | |
272 | |
273 return NGX_OK; | |
274 } | |
275 | |
276 | |
277 char * | |
278 ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
279 { | |
280 char *p = conf; | |
281 | |
282 ngx_str_t *value; | |
283 ngx_uint_t i; | |
284 ngx_array_t **a; | |
285 ngx_http_complex_value_t *cv; | |
286 ngx_http_compile_complex_value_t ccv; | |
287 | |
288 a = (ngx_array_t **) (p + cmd->offset); | |
289 | |
290 if (*a == NGX_CONF_UNSET_PTR) { | |
291 *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t)); | |
292 if (*a == NULL) { | |
293 return NGX_CONF_ERROR; | |
294 } | |
295 } | |
296 | |
297 value = cf->args->elts; | |
298 | |
299 for (i = 1; i < cf->args->nelts; i++) { | |
300 cv = ngx_array_push(*a); | |
301 if (cv == NULL) { | |
302 return NGX_CONF_ERROR; | |
303 } | |
304 | |
305 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
306 | |
307 ccv.cf = cf; | |
308 ccv.value = &value[i]; | |
309 ccv.complex_value = cv; | |
310 | |
311 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
312 return NGX_CONF_ERROR; | |
313 } | |
314 } | |
315 | |
316 return NGX_CONF_OK; | |
317 } | |
318 | |
319 | |
214 ngx_uint_t | 320 ngx_uint_t |
215 ngx_http_script_variables_count(ngx_str_t *value) | 321 ngx_http_script_variables_count(ngx_str_t *value) |
216 { | 322 { |
217 ngx_uint_t i, n; | 323 ngx_uint_t i, n; |
218 | 324 |
248 } | 354 } |
249 | 355 |
250 #if (NGX_PCRE) | 356 #if (NGX_PCRE) |
251 { | 357 { |
252 ngx_uint_t n; | 358 ngx_uint_t n; |
253 | |
254 /* NGX_HTTP_MAX_CAPTURES is 9 */ | |
255 | 359 |
256 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { | 360 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { |
257 | 361 |
258 n = sc->source->data[i] - '0'; | 362 n = sc->source->data[i] - '0'; |
259 | 363 |
826 e->sp--; | 930 e->sp--; |
827 e->line.len = e->sp->len; | 931 e->line.len = e->sp->len; |
828 e->line.data = e->sp->data; | 932 e->line.data = e->sp->data; |
829 } | 933 } |
830 | 934 |
831 if (code->ncaptures && r->captures == NULL) { | 935 rc = ngx_http_regex_exec(r, code->regex, &e->line); |
832 | 936 |
833 r->captures = ngx_palloc(r->pool, | 937 if (rc == NGX_DECLINED) { |
834 (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int)); | |
835 if (r->captures == NULL) { | |
836 e->ip = ngx_http_script_exit; | |
837 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
838 return; | |
839 } | |
840 } | |
841 | |
842 rc = ngx_regex_exec(code->regex, &e->line, r->captures, code->ncaptures); | |
843 | |
844 if (rc == NGX_REGEX_NO_MATCHED) { | |
845 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { | 938 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { |
846 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 939 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
847 "\"%V\" does not match \"%V\"", | 940 "\"%V\" does not match \"%V\"", |
848 &code->name, &e->line); | 941 &code->name, &e->line); |
849 } | 942 } |
868 | 961 |
869 e->ip += code->next; | 962 e->ip += code->next; |
870 return; | 963 return; |
871 } | 964 } |
872 | 965 |
873 if (rc < 0) { | 966 if (rc == NGX_ERROR) { |
874 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
875 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", | |
876 rc, &e->line, &code->name); | |
877 | |
878 e->ip = ngx_http_script_exit; | 967 e->ip = ngx_http_script_exit; |
879 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | 968 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; |
880 return; | 969 return; |
881 } | 970 } |
882 | 971 |
883 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { | 972 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { |
884 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 973 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
885 "\"%V\" matches \"%V\"", &code->name, &e->line); | 974 "\"%V\" matches \"%V\"", &code->name, &e->line); |
886 } | 975 } |
887 | |
888 r->ncaptures = code->ncaptures; | |
889 r->captures_data = e->line.data; | |
890 | 976 |
891 if (code->test) { | 977 if (code->test) { |
892 if (code->negative_test) { | 978 if (code->negative_test) { |
893 e->sp->len = 0; | 979 e->sp->len = 0; |
894 e->sp->data = (u_char *) ""; | 980 e->sp->data = (u_char *) ""; |
928 | 1014 |
929 if (code->lengths == NULL) { | 1015 if (code->lengths == NULL) { |
930 e->buf.len = code->size; | 1016 e->buf.len = code->size; |
931 | 1017 |
932 if (code->uri) { | 1018 if (code->uri) { |
933 if (rc && (r->quoted_uri || r->plus_in_uri)) { | 1019 if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) { |
934 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, | 1020 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, |
935 NGX_ESCAPE_ARGS); | 1021 NGX_ESCAPE_ARGS); |
936 } | 1022 } |
937 } | 1023 } |
938 | 1024 |
939 for (n = 1; n < (ngx_uint_t) rc; n++) { | 1025 for (n = 2; n < r->ncaptures; n += 2) { |
940 e->buf.len += r->captures[2 * n + 1] - r->captures[2 * n]; | 1026 e->buf.len += r->captures[n + 1] - r->captures[n]; |
941 } | 1027 } |
942 | 1028 |
943 } else { | 1029 } else { |
944 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); | 1030 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); |
945 | 1031 |
1001 | 1087 |
1002 ngx_unescape_uri(&dst, &src, e->pos - e->buf.data, | 1088 ngx_unescape_uri(&dst, &src, e->pos - e->buf.data, |
1003 NGX_UNESCAPE_REDIRECT); | 1089 NGX_UNESCAPE_REDIRECT); |
1004 | 1090 |
1005 if (src < e->pos) { | 1091 if (src < e->pos) { |
1006 dst = ngx_copy(dst, src, e->pos - src); | 1092 dst = ngx_movemem(dst, src, e->pos - src); |
1007 } | 1093 } |
1008 | 1094 |
1009 e->pos = dst; | 1095 e->pos = dst; |
1010 | 1096 |
1011 if (code->add_args && r->args.len) { | 1097 if (code->add_args && r->args.len) { |
1026 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | 1112 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; |
1027 return; | 1113 return; |
1028 } | 1114 } |
1029 | 1115 |
1030 r->headers_out.location->hash = 1; | 1116 r->headers_out.location->hash = 1; |
1031 r->headers_out.location->key.len = sizeof("Location") - 1; | 1117 ngx_str_set(&r->headers_out.location->key, "Location"); |
1032 r->headers_out.location->key.data = (u_char *) "Location"; | |
1033 r->headers_out.location->value = e->buf; | 1118 r->headers_out.location->value = e->buf; |
1034 | 1119 |
1035 e->ip += sizeof(ngx_http_script_regex_end_code_t); | 1120 e->ip += sizeof(ngx_http_script_regex_end_code_t); |
1036 return; | 1121 return; |
1037 } | 1122 } |
1273 { | 1358 { |
1274 ngx_http_script_return_code_t *code; | 1359 ngx_http_script_return_code_t *code; |
1275 | 1360 |
1276 code = (ngx_http_script_return_code_t *) e->ip; | 1361 code = (ngx_http_script_return_code_t *) e->ip; |
1277 | 1362 |
1278 e->status = code->status; | 1363 if (code->status < NGX_HTTP_BAD_REQUEST |
1279 | 1364 || code->text.value.len |
1280 if (code->status == NGX_HTTP_NO_CONTENT) { | 1365 || code->text.lengths) |
1281 e->request->header_only = 1; | 1366 { |
1282 e->request->zero_body = 1; | 1367 e->status = ngx_http_send_response(e->request, code->status, NULL, |
1283 } | 1368 &code->text); |
1284 | 1369 } else { |
1285 e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t); | 1370 e->status = code->status; |
1371 } | |
1372 | |
1373 e->ip = ngx_http_script_exit; | |
1286 } | 1374 } |
1287 | 1375 |
1288 | 1376 |
1289 void | 1377 void |
1290 ngx_http_script_break_code(ngx_http_script_engine_t *e) | 1378 ngx_http_script_break_code(ngx_http_script_engine_t *e) |
1405 | 1493 |
1406 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1494 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1407 | 1495 |
1408 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); | 1496 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); |
1409 | 1497 |
1498 of.read_ahead = clcf->read_ahead; | |
1410 of.directio = clcf->directio; | 1499 of.directio = clcf->directio; |
1411 of.valid = clcf->open_file_cache_valid; | 1500 of.valid = clcf->open_file_cache_valid; |
1412 of.min_uses = clcf->open_file_cache_min_uses; | 1501 of.min_uses = clcf->open_file_cache_min_uses; |
1413 of.test_only = 1; | 1502 of.test_only = 1; |
1414 of.errors = clcf->open_file_cache_errors; | 1503 of.errors = clcf->open_file_cache_errors; |
1415 of.events = clcf->open_file_cache_events; | 1504 of.events = clcf->open_file_cache_events; |
1416 | 1505 |
1417 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) | 1506 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) |
1418 != NGX_OK) | 1507 != NGX_OK) |
1419 { | 1508 { |
1420 if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) { | 1509 if (of.err != NGX_ENOENT |
1510 && of.err != NGX_ENOTDIR | |
1511 && of.err != NGX_ENAMETOOLONG) | |
1512 { | |
1421 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, | 1513 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, |
1422 "%s \"%s\" failed", of.failed, value->data); | 1514 "%s \"%s\" failed", of.failed, value->data); |
1423 } | 1515 } |
1424 | 1516 |
1425 switch (code->op) { | 1517 switch (code->op) { |