Mercurial > hg > nginx-mail
diff 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 |
line wrap: on
line diff
--- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -211,6 +211,112 @@ ngx_http_compile_complex_value(ngx_http_ } +char * +ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *p = conf; + + ngx_str_t *value; + ngx_http_complex_value_t **cv; + ngx_http_compile_complex_value_t ccv; + + cv = (ngx_http_complex_value_t **) (p + cmd->offset); + + if (*cv != NULL) { + return "duplicate"; + } + + *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); + if (*cv == NULL) { + return NGX_CONF_ERROR; + } + + value = cf->args->elts; + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = *cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + + +ngx_int_t +ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates) +{ + ngx_str_t val; + ngx_uint_t i; + ngx_http_complex_value_t *cv; + + if (predicates == NULL) { + return NGX_OK; + } + + cv = predicates->elts; + + for (i = 0; i < predicates->nelts; i++) { + if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) { + return NGX_ERROR; + } + + if (val.len && val.data[0] != '0') { + return NGX_DECLINED; + } + } + + return NGX_OK; +} + + +char * +ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *p = conf; + + ngx_str_t *value; + ngx_uint_t i; + ngx_array_t **a; + ngx_http_complex_value_t *cv; + ngx_http_compile_complex_value_t ccv; + + a = (ngx_array_t **) (p + cmd->offset); + + if (*a == NGX_CONF_UNSET_PTR) { + *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t)); + if (*a == NULL) { + return NGX_CONF_ERROR; + } + } + + value = cf->args->elts; + + for (i = 1; i < cf->args->nelts; i++) { + cv = ngx_array_push(*a); + if (cv == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[i]; + ccv.complex_value = cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + + return NGX_CONF_OK; +} + + ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value) { @@ -251,8 +357,6 @@ ngx_http_script_compile(ngx_http_script_ { ngx_uint_t n; - /* NGX_HTTP_MAX_CAPTURES is 9 */ - if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { n = sc->source->data[i] - '0'; @@ -828,20 +932,9 @@ ngx_http_script_regex_start_code(ngx_htt e->line.data = e->sp->data; } - if (code->ncaptures && r->captures == NULL) { + rc = ngx_http_regex_exec(r, code->regex, &e->line); - r->captures = ngx_palloc(r->pool, - (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int)); - if (r->captures == NULL) { - e->ip = ngx_http_script_exit; - e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; - return; - } - } - - rc = ngx_regex_exec(code->regex, &e->line, r->captures, code->ncaptures); - - if (rc == NGX_REGEX_NO_MATCHED) { + if (rc == NGX_DECLINED) { if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "\"%V\" does not match \"%V\"", @@ -870,11 +963,7 @@ ngx_http_script_regex_start_code(ngx_htt return; } - if (rc < 0) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", - rc, &e->line, &code->name); - + if (rc == NGX_ERROR) { e->ip = ngx_http_script_exit; e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return; @@ -885,9 +974,6 @@ ngx_http_script_regex_start_code(ngx_htt "\"%V\" matches \"%V\"", &code->name, &e->line); } - r->ncaptures = code->ncaptures; - r->captures_data = e->line.data; - if (code->test) { if (code->negative_test) { e->sp->len = 0; @@ -930,14 +1016,14 @@ ngx_http_script_regex_start_code(ngx_htt e->buf.len = code->size; if (code->uri) { - if (rc && (r->quoted_uri || r->plus_in_uri)) { + if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) { e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_ARGS); } } - for (n = 1; n < (ngx_uint_t) rc; n++) { - e->buf.len += r->captures[2 * n + 1] - r->captures[2 * n]; + for (n = 2; n < r->ncaptures; n += 2) { + e->buf.len += r->captures[n + 1] - r->captures[n]; } } else { @@ -1003,7 +1089,7 @@ ngx_http_script_regex_end_code(ngx_http_ NGX_UNESCAPE_REDIRECT); if (src < e->pos) { - dst = ngx_copy(dst, src, e->pos - src); + dst = ngx_movemem(dst, src, e->pos - src); } e->pos = dst; @@ -1028,8 +1114,7 @@ ngx_http_script_regex_end_code(ngx_http_ } r->headers_out.location->hash = 1; - r->headers_out.location->key.len = sizeof("Location") - 1; - r->headers_out.location->key.data = (u_char *) "Location"; + ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.location->value = e->buf; e->ip += sizeof(ngx_http_script_regex_end_code_t); @@ -1275,14 +1360,17 @@ ngx_http_script_return_code(ngx_http_scr code = (ngx_http_script_return_code_t *) e->ip; - e->status = code->status; - - if (code->status == NGX_HTTP_NO_CONTENT) { - e->request->header_only = 1; - e->request->zero_body = 1; + if (code->status < NGX_HTTP_BAD_REQUEST + || code->text.value.len + || code->text.lengths) + { + e->status = ngx_http_send_response(e->request, code->status, NULL, + &code->text); + } else { + e->status = code->status; } - e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t); + e->ip = ngx_http_script_exit; } @@ -1407,6 +1495,7 @@ ngx_http_script_file_code(ngx_http_scrip ngx_memzero(&of, sizeof(ngx_open_file_info_t)); + of.read_ahead = clcf->read_ahead; of.directio = clcf->directio; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; @@ -1417,7 +1506,10 @@ ngx_http_script_file_code(ngx_http_scrip if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { - if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) { + if (of.err != NGX_ENOENT + && of.err != NGX_ENOTDIR + && of.err != NGX_ENAMETOOLONG) + { ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, "%s \"%s\" failed", of.failed, value->data); }