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);
         }