diff src/http/modules/ngx_http_rewrite_handler.c @ 32:da8c190bdaba NGINX_0_1_16

nginx 0.1.16 *) Bugfix: if the response were transferred by chunks, then on the HEAD request the final chunk was issued. *) Bugfix: the "Connection: keep-alive" header were issued, even if the keepalive_timeout directive forbade the keep-alive use. *) Bugfix: the errors in the ngx_http_fastcgi_module caused the segmentation faults. *) Bugfix: the compressed response encrypted by SSL may not transferred complete. *) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK options, are not used for the unix domain sockets. *) Feature: the rewrite directive supports the arguments rewriting. *) Bugfix: the response code 400 was returned for the POST request with the "Content-Length: 0" header; bug appeared in 0.1.14.
author Igor Sysoev <http://sysoev.ru>
date Tue, 25 Jan 2005 00:00:00 +0300
parents e1ada20fc595
children aab2ea7c0458
line wrap: on
line diff
--- a/src/http/modules/ngx_http_rewrite_handler.c
+++ b/src/http/modules/ngx_http_rewrite_handler.c
@@ -9,9 +9,10 @@
 #include <ngx_http.h>
 
 
-#define NGX_HTTP_REWRITE_COPY_MATCH  0
-#define NGX_HTTP_REWRITE_COPY_SHORT  1
-#define NGX_HTTP_REWRITE_COPY_LONG   2
+#define NGX_HTTP_REWRITE_COPY_CAPTURE  0
+#define NGX_HTTP_REWRITE_COPY_SHORT    1
+#define NGX_HTTP_REWRITE_COPY_LONG     2
+#define NGX_HTTP_REWRITE_START_ARGS    3
 
 
 typedef struct {
@@ -119,7 +120,7 @@ static ngx_int_t ngx_http_rewrite_handle
     uintptr_t                     data;
     ngx_int_t                     rc;
     ngx_uint_t                    i, m, n;
-    ngx_str_t                     uri;
+    ngx_str_t                     uri, args;
     ngx_http_rewrite_op_t        *op;
     ngx_http_rewrite_rule_t      *rule;
     ngx_http_rewrite_srv_conf_t  *scf;
@@ -176,13 +177,14 @@ static ngx_int_t ngx_http_rewrite_handle
         uri.len = rule[i].size;
 
         for (n = 1; n < (ngx_uint_t) rc; n++) {
-           uri.len += captures[2 * n + 1] - captures[2 * n];
+            uri.len += captures[2 * n + 1] - captures[2 * n];
         }
 
         if (!(uri.data = ngx_palloc(r->pool, uri.len))) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
+        args.data = NULL;
         p = uri.data;
 
         op = rule[i].ops.elts;
@@ -198,22 +200,34 @@ static ngx_int_t ngx_http_rewrite_handle
             } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) {
                 p = ngx_cpymem(p, (void *) op[n].data, op[n].len);
 
-            } else { /* NGX_HTTP_REWRITE_COPY_MATCH */
+            } else if (op[n].op == NGX_HTTP_REWRITE_START_ARGS) {
+                args.data = p;
+
+            } else { /* NGX_HTTP_REWRITE_COPY_CAPTURE */
                 m = 2 * op[n].data;
                 p = ngx_cpymem(p, &r->uri.data[captures[m]],
                                captures[m + 1] - captures[m]);
             }
         }
 
-        uri.len = p - uri.data;
+        if (args.data) {
+            uri.len = args.data - uri.data;
+            args.len = p - args.data;
+
+            r->args = args;
+
+        } else {
+            uri.len = p - uri.data;
+            args.len = 0;
+        }
+
+        r->uri = uri;
 
         if (scf->log) {
             ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
-                          "rewritten uri: \"%V\"", &uri);
+                          "rewritten uri: \"%V\", args: \"%V\"", &uri, &args);
         }
 
-        r->uri = uri;
-
         if (ngx_http_set_exten(r) != NGX_OK) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
@@ -359,7 +373,9 @@ static char *ngx_http_rewrite_rule(ngx_c
             return NGX_CONF_ERROR;
         }
 
-        for (i = 0; i < value[2].len; /* void */) {
+        i = 0;
+
+        while (i < value[2].len) {
 
             if (!(op = ngx_push_array(&rule->ops))) {
                 return NGX_CONF_ERROR;
@@ -372,7 +388,8 @@ static char *ngx_http_rewrite_rule(ngx_c
                 && value[2].data[i + 1] >= '1'
                 && value[2].data[i + 1] <= '9')
             {
-                op->op = NGX_HTTP_REWRITE_COPY_MATCH; 
+                op->op = NGX_HTTP_REWRITE_COPY_CAPTURE; 
+                op->len = 0;
                 op->data = value[2].data[++i] - '0';
 
                 if (rule->ncaptures < op->data) {
@@ -381,39 +398,53 @@ static char *ngx_http_rewrite_rule(ngx_c
 
                 i++;
 
-            } else {
+                continue;
+            }
+
+            if (value[2].data[i] == '?') {
+                op->op = NGX_HTTP_REWRITE_START_ARGS; 
+                op->len = 0;
+                op->data = 0;
+
                 i++;
 
-                while (i < value[2].len && value[2].data[i] != '$') {
-                    i++;
-                }
+                continue;
+            }
 
-                len = &value[2].data[i] - data;
-                rule->size += len;
+            i++;
 
-                if (len) {
-
-                    op->len = len;
+            while (i < value[2].len
+                   && value[2].data[i] != '$'
+                   && value[2].data[i] != '?')
+            {
+                i++;
+            }
 
-                    if (len <= sizeof(uintptr_t)) {
-                        op->op = NGX_HTTP_REWRITE_COPY_SHORT; 
-                        op->data = 0;
+            len = &value[2].data[i] - data;
+            rule->size += len;
+
+            if (len) {
+
+                op->len = len;
 
-                        while (len--) {
-                            op->data <<= 8;
-                            op->data |= data[len];
-                        }
+                if (len <= sizeof(uintptr_t)) {
+                    op->op = NGX_HTTP_REWRITE_COPY_SHORT; 
+                    op->data = 0;
 
-                    } else {
-                        op->op = NGX_HTTP_REWRITE_COPY_LONG;
+                    while (len--) {
+                        op->data <<= 8;
+                        op->data |= data[len];
+                    }
 
-                        if (!(p = ngx_palloc(cf->pool, len))) {
-                            return NGX_CONF_ERROR;
-                        }
+                } else {
+                    op->op = NGX_HTTP_REWRITE_COPY_LONG;
 
-                        ngx_memcpy(p, data, len);
-                        op->data = (uintptr_t) p;
+                    if (!(p = ngx_palloc(cf->pool, len))) {
+                        return NGX_CONF_ERROR;
                     }
+
+                    ngx_memcpy(p, data, len);
+                    op->data = (uintptr_t) p;
                 }
             }
         }