diff src/http/ngx_http_variables.c @ 577:4d9ea73a627a release-0.3.10

nginx-0.3.10-RELEASE import *) Change: the "valid_referers" directive and the "$invalid_referer" variable were moved to the new ngx_http_referer_module from the ngx_http_rewrite_module. *) Change: the "$apache_bytes_sent" variable name was changed to "$body_bytes_sent". *) Feature: the "$sent_http_..." variables. *) Feature: the "if" directive supports the "=" and "!=" operations. *) Feature: the "proxy_pass" directive supports the HTTPS protocol. *) Feature: the "proxy_set_body" directive. *) Feature: the "post_action" directive. *) Feature: the ngx_http_empty_gif_module. *) Feature: the "worker_cpu_affinity" directive for Linux. *) Bugfix: the "rewrite" directive did not unescape URI part in redirect, now it is unescaped except the %00-%25 and %7F-%FF characters. *) Bugfix: nginx could not be built by the icc 9.0 compiler. *) Bugfix: if the SSI was enabled for zero size static file, then the chunked response was encoded incorrectly.
author Igor Sysoev <igor@sysoev.ru>
date Tue, 15 Nov 2005 13:30:52 +0000
parents 58475592100c
children 326634fb9d47
line wrap: on
line diff
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -16,8 +16,14 @@ static ngx_int_t ngx_http_variable_heade
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_unknown_header(ngx_http_request_t *r,
+
+static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
+    ngx_str_t *var, ngx_list_part_t *part, size_t prefix);
+
 static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r,
@@ -124,6 +130,12 @@ static ngx_http_variable_t  ngx_http_cor
 };
 
 
+ngx_http_variable_value_t  ngx_http_variable_null_value =
+    ngx_http_variable("");
+ngx_http_variable_value_t  ngx_http_variable_true_value =
+    ngx_http_variable("1");
+
+
 ngx_http_variable_t *
 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
 {
@@ -324,7 +336,19 @@ ngx_http_get_variable(ngx_http_request_t
 
     if (ngx_strncmp(name->data, "http_", 5) == 0) {
 
-        if (ngx_http_variable_unknown_header(r, vv, (uintptr_t) name) == NGX_OK)
+        if (ngx_http_variable_unknown_header_in(r, vv, (uintptr_t) name)
+            == NGX_OK)
+        {
+            return vv;
+        }
+
+        return NULL;
+    }
+
+    if (ngx_strncmp(name->data, "sent_http_", 10) == 0) {
+
+        if (ngx_http_variable_unknown_header_out(r, vv, (uintptr_t) name)
+            == NGX_OK)
         {
             return vv;
         }
@@ -446,17 +470,33 @@ ngx_http_variable_headers(ngx_http_reque
 
 
 static ngx_int_t
-ngx_http_variable_unknown_header(ngx_http_request_t *r,
+ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
+                                            &r->headers_in.headers.part,
+                                            sizeof("http_") - 1);
+}
+
+
+static ngx_int_t
+ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
-    ngx_str_t  *var = (ngx_str_t *) data;
+    return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
+                                            &r->headers_out.headers.part,
+                                            sizeof("sent_http_") - 1);
+}
 
+
+static ngx_int_t
+ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
+    ngx_list_part_t *part, size_t prefix)
+{
     u_char            ch;
     ngx_uint_t        i, n;
-    ngx_list_part_t  *part;
     ngx_table_elt_t  *header;
 
-    part = &r->headers_in.headers.part;
     header = part->elts;
 
     for (i = 0; /* void */ ; i++) {
@@ -471,7 +511,7 @@ ngx_http_variable_unknown_header(ngx_htt
             i = 0;
         }
 
-        for (n = 0; n + 5 < var->len && n < header[i].key.len; n++) {
+        for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
             ch = header[i].key.data[n];
 
             if (ch >= 'A' && ch <= 'Z') {
@@ -481,12 +521,12 @@ ngx_http_variable_unknown_header(ngx_htt
                 ch = '_';
             }
 
-            if (var->data[n + 5] != ch) {
+            if (var->data[n + prefix] != ch) {
                 break;
             }
         }
 
-        if (n + 5 == var->len) {
+        if (n + prefix == var->len) {
             v->len = header[i].value.len;
             v->valid = 1;
             v->no_cachable = 0;
@@ -556,12 +596,12 @@ ngx_http_variable_remote_port(ngx_http_r
     }
 
     /* AF_INET only */
-    
+
     if (r->connection->sockaddr->sa_family == AF_INET) {
         sin = (struct sockaddr_in *) r->connection->sockaddr;
-    
+
         port = ntohs(sin->sin_port);
-                             
+
         if (port > 0 && port < 65536) {
             v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
         }
@@ -777,7 +817,14 @@ ngx_http_variables_init_vars(ngx_conf_t 
         }
 
         if (ngx_strncmp(v[i].name.data, "http_", 5) == 0) {
-            v[i].handler = ngx_http_variable_unknown_header;
+            v[i].handler = ngx_http_variable_unknown_header_in;
+            v[i].data = (uintptr_t) &v[i].name;
+
+            continue;
+        }
+
+        if (ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0) {
+            v[i].handler = ngx_http_variable_unknown_header_out;
             v[i].data = (uintptr_t) &v[i].name;
 
             continue;