Still confused with try_files

Igor Sysoev is at rambler-co.ru
Thu Mar 19 13:24:22 MSK 2009


On Mon, Mar 16, 2009 at 09:44:30PM -0700, mike wrote:

> for a site with multiple "if file does not exist, use this master
> controller file" like wordpress, drupal, etc, does a config like this
> make sense?
> 
> because right now, it doesn't.
> 
> the /blog one does, but the /second one doesn.t
> 
> server {
>         listen 80;
>         server_name proto.foo.net;
>         index index.php index.html;
>         root /home/proto/web/proto.foo.net;
>         include /etc/nginx/defaults.conf;
>         include /etc/nginx/expires.conf;
>         location /blog {
>                 error_page 404 = /wordpress/index.php?q=$request_uri;
>         }
>         location /second {
>                 try_files $uri $uri/ /second/controller.php?slug=$request_uri;
>         }
>         location ~ \.php$ {
>                 fastcgi_pass 127.0.0.1:11020;
>         }
> }
> 
> 
> 2009/03/16 21:40:29 [error] 29669#0: *638 rewrite or internal
> redirection cycle while internal redirect to
> "/second/controller.php?slug=/second/contro", client: 123.5.226.17,
> server: proto.foo.net, request: "GET /second/contro HTTP/1.1", host:
> "proto.mikehost.net"
> 
> I really want to use try_files as I believe it is better than using
> error_page 404 and if ( !-e $request_filename) type stuff, right? All
> I need is to understand the routing better and I'll be on my way. :)
> 
> I guess it makes sense about the internal redirection cycle but how
> else can I route only requests to the prefix of /second to that
> application's controller?

The attached patch should fix the bug.


-- 
Igor Sysoev
http://sysoev.ru/en/
-------------- next part --------------
Index: src/http/ngx_http.h
===================================================================
--- src/http/ngx_http.h	(revision 1897)
+++ src/http/ngx_http.h	(working copy)
@@ -78,6 +78,8 @@
     ngx_str_t *name, ngx_str_t *value);
 ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,
     ngx_str_t *value);
+void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,
+    ngx_str_t *args);
 
 
 ngx_int_t ngx_http_find_server_conf(ngx_http_request_t *r);
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c	(revision 1897)
+++ src/http/ngx_http_core_module.c	(working copy)
@@ -1037,7 +1037,7 @@
 {
     size_t                        len, root, alias, reserve, allocated;
     u_char                       *p, *name;
-    ngx_str_t                     path;
+    ngx_str_t                     path, args;
     ngx_uint_t                    test_dir;
     ngx_http_try_file_t          *tf;
     ngx_open_file_info_t          of;
@@ -1146,7 +1146,9 @@
                 (void) ngx_http_named_location(r, &path);
 
             } else {
-                (void) ngx_http_internal_redirect(r, &path, NULL);
+                ngx_http_split_args(r, &path, &args);
+
+                (void) ngx_http_internal_redirect(r, &path, &args);
             }
 
             return NGX_OK;
Index: src/http/ngx_http_parse.c
===================================================================
--- src/http/ngx_http_parse.c	(revision 1897)
+++ src/http/ngx_http_parse.c	(working copy)
@@ -1523,3 +1523,37 @@
 
     return NGX_DECLINED;
 }
+
+
+void
+ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)
+{
+    u_char  ch, *p, *last;
+
+    p = uri->data;
+
+    last = p + uri->len;
+
+    while (p < last) {
+
+	ch = *p++;
+
+	if (ch == '?') {
+	    args->len = last - p;
+	    args->data = p;
+
+	    uri->len = p - 1 - uri->data;
+
+	    if (ngx_strlchr(p, last, '\0') != NULL) {
+		r->zero_in_uri = 1;
+	    }
+
+	    return;
+	}
+
+	if (ch == '\0') {
+	    r->zero_in_uri = 1;
+	    continue;
+	}
+    }
+}


More information about the nginx mailing list