I was testing the new rewrite support in httpd in conjunction with the "fastcgi"
option and noticed that the REQUEST_URI CGI variable is set to the rewritten
path and query string instead of the requested URI and query string. The patch
below mimics what happens with http_descriptor->http_path_alias to change this.

I also noticed that $QUERY_STRING macro isn't being encoded when it gets
expanded during a rewrite. I saw the recent commits making changes to this
macro, so I thought I'd mention it but leave it alone.

Tim


Index: http.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/http.h,v
retrieving revision 1.14
diff -u -p -r1.14 http.h
--- http.h    1 Aug 2016 21:15:30 -0000    1.14
+++ http.h    30 Jul 2018 16:08:44 -0000
@@ -243,8 +243,9 @@ struct http_descriptor {
     char            *http_version;
     unsigned int         http_status;

-    /* Rewritten path remains NULL if not used */
+    /* Rewritten path and query remain NULL if not used */
     char            *http_path_alias;
+    char            *http_query_alias;

     /* A tree of headers and attached lists for repeated headers. */
     struct kv        *http_lastheader;
Index: server_fcgi.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v
retrieving revision 1.76
diff -u -p -r1.76 server_fcgi.c
--- server_fcgi.c    19 May 2018 13:56:56 -0000    1.76
+++ server_fcgi.c    30 Jul 2018 16:08:44 -0000
@@ -97,7 +97,7 @@ server_fcgi(struct httpd *env, struct cl
     int                 pathlen;
     int                 fd = -1, ret;
     const char            *stripped, *p, *alias, *errstr = NULL;
-    char                *str, *script = NULL;
+    char                *queryalias, *str, *script = NULL;

     if (srv_conf->socket[0] == ':') {
         struct sockaddr_storage     ss;
@@ -193,6 +193,10 @@ server_fcgi(struct httpd *env, struct cl
         ? desc->http_path_alias
         : desc->http_path;

+    queryalias = desc->http_query_alias != NULL
+        ? desc->http_query_alias
+        : desc->http_query;
+
     stripped = server_root_strip(alias, srv_conf->strip);
     if ((pathlen = asprintf(&script, "%s%s", srv_conf->root, stripped))
         == -1) {
@@ -241,8 +245,8 @@ server_fcgi(struct httpd *env, struct cl
         goto fail;
     }

-    if (desc->http_query) {
-        if (fcgi_add_param(&param, "QUERY_STRING", desc->http_query,
+    if (queryalias) {
+        if (fcgi_add_param(&param, "QUERY_STRING", queryalias,
             clt) == -1) {
             errstr = "failed to encode param";
             goto fail;
Index: server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.122
diff -u -p -r1.122 server_http.c
--- server_http.c    20 Jun 2018 16:43:05 -0000    1.122
+++ server_http.c    30 Jul 2018 16:08:44 -0000
@@ -102,6 +102,8 @@ server_httpdesc_free(struct http_descrip
     desc->http_path = NULL;
     free(desc->http_path_alias);
     desc->http_path_alias = NULL;
+    free(desc->http_query_alias);
+    desc->http_query_alias = NULL;
     free(desc->http_query);
     desc->http_query = NULL;
     free(desc->http_version);
@@ -1295,11 +1297,11 @@ server_response(struct httpd *httpd, str
          * be URL encoded - either specified by the user or by using the
          * original $QUERY_STRING.
          */
-        free(desc->http_query);
-        desc->http_query = NULL;
+        free(desc->http_query_alias);
+        desc->http_query_alias = NULL;
         if ((query = strchr(path, '?')) != NULL) {
             *query++ = '\0';
-            if ((desc->http_query = strdup(query)) == NULL)
+            if ((desc->http_query_alias = strdup(query)) == NULL)
                 goto fail;
         }

@@ -1308,15 +1310,15 @@ server_response(struct httpd *httpd, str
             path, sizeof(path)) == NULL)
             goto fail;

-        log_debug("%s: rewrote %s -> %s?%s", __func__,
-            desc->http_path, path, desc->http_query);
+        log_debug("%s: rewrote %s?%s -> %s?%s", __func__,
+            desc->http_path, desc->http_query, path, query);

-        free(desc->http_path);
-        if ((desc->http_path = strdup(path)) == NULL)
+        free(desc->http_path_alias);
+        if ((desc->http_path_alias = strdup(path)) == NULL)
             goto fail;

         /* Now search for the updated location */
-        srv_conf = server_getlocation(clt, desc->http_path);
+        srv_conf = server_getlocation(clt, desc->http_path_alias);
     }

     if (srv_conf->flags & SRVFLAG_BLOCK) {

Reply via email to