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) {