proxy: get uri from pb_key_uri/pb_key_query instead of clf-request

Sun, 22 Feb 2026 09:33:48 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 22 Feb 2026 09:33:48 +0100
changeset 696
27e42da5050f
parent 695
ff14b97bdf14
child 697
3ddfd45d4e47

proxy: get uri from pb_key_uri/pb_key_query instead of clf-request

src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/safs/proxy.c file | annotate | diff | comparison | revisions
src/server/safs/proxy.h file | annotate | diff | comparison | revisions
src/server/util/uri.c file | annotate | diff | comparison | revisions
--- a/src/server/daemon/httprequest.c	Sun Feb 22 09:24:41 2026 +0100
+++ b/src/server/daemon/httprequest.c	Sun Feb 22 09:33:48 2026 +0100
@@ -296,6 +296,8 @@
                 absPath.length,
                 rq->rq.reqpb);
     } else {
+        // error
+        
         // util_uri_unescape_strict can modify absPath.ptr, but
         // we want to log the original uri. However we also don't want to
         // create an unnecessary copy. Therefore we restore the original
--- a/src/server/safs/proxy.c	Sun Feb 22 09:24:41 2026 +0100
+++ b/src/server/safs/proxy.c	Sun Feb 22 09:33:48 2026 +0100
@@ -34,47 +34,9 @@
 #include <string.h>
 
 #include "../util/pblock.h"
+#include "../util/util.h"
 #include "../proxy/httpclient.h"
 
-// Gets the uri part from an http request line
-static cxstring get_uri_from_clfreq(const char *clfreq) {
-    cxstring uri = { NULL, 0 };
-    
-    const char *begin = NULL;
-    const char *str = clfreq;
-    for(;*str != '\0';str++) {
-        if(*str < 33) {
-            if(begin) {
-                str++;
-                break;
-            }
-        } else {
-            if(!begin) {
-                begin = str;
-            }
-        }
-    }
-    
-    begin = NULL;
-    for(;*str != '\0';str++) {
-        if(*str > 32) {
-            if(!begin) {
-                begin = str;
-            }
-        } else {
-            if(begin) {
-                break;
-            }
-        }
-    }
-    
-    if(begin && *str != '\0') {
-        return cx_strn(begin, str-begin);
-    }
-    
-    return uri;
-    
-}
 
 typedef struct ProxyRequest {
     Session *sn;
@@ -177,11 +139,19 @@
 int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq) {
     EventHandler *ev = sn->ev;
     const char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
-    const char *clfreq = pblock_findkeyval(pb_key_clf_request, rq->reqpb);
+    const char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+    const char *query = pblock_findkeyval(pb_key_query, rq->reqpb);
     
-    cxstring uri = get_uri_from_clfreq(clfreq);
-    if(uri.length == 0) {
-        return REQ_ABORTED;
+    cxmutstr new_uri = CX_NULLSTR;
+    size_t uri_len = strlen(uri);
+    size_t query_len = query ? strlen(query) : 0;
+    size_t new_uri_alloc = ((uri_len + query_len) * 3) + 2;
+    new_uri.ptr = pool_malloc(sn->pool, new_uri_alloc);
+    new_uri.length = util_uri_escape_s(new_uri.ptr, new_uri_alloc, uri);
+    if(new_uri.length > 0 && query_len > 0) {
+        new_uri.ptr[new_uri.length] = '?';
+        memcpy(new_uri.ptr + new_uri.length + 1, query, query_len + 1);
+        new_uri.length = new_uri.length + 1 + query_len;
     }
     
     // remove some response headers, that were previously set by ObjectType
@@ -215,7 +185,7 @@
         return REQ_ABORTED;
     }
     
-    if(http_client_set_uri_len(client, uri.ptr, uri.length)) {
+    if(http_client_set_uri_len(client, new_uri.ptr, new_uri.length)) {
         http_client_free(client);
         return REQ_ABORTED;
     }
@@ -293,43 +263,3 @@
     return REQ_PROCESSING;
 }
 
-
-
-/* --------------------------------- Tests --------------------------------- */
-
-static CX_TEST(test_safs_proxy_get_uri_from_clfreq) {
-    CX_TEST_DO {
-        cxstring ret;
-        
-        ret = get_uri_from_clfreq("GET /uri HTTP/1.1");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/uri"));
-        ret = get_uri_from_clfreq("G / HTTP/1.1");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/"));
-        ret = get_uri_from_clfreq("POST   /test%20/path HTTP/1.1");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/test%20/path"));
-        ret = get_uri_from_clfreq("   GET /leading_space HTTP/1.1");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/leading_space"));
-        ret = get_uri_from_clfreq("   PROPFIND   /space2 HTTP/1.1");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/space2"));
-        ret = get_uri_from_clfreq("HEAD /trailing_space     HTTP/1.1");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/trailing_space"));
-        ret = get_uri_from_clfreq("   GET   /space3     HTTP/1.1   ");
-        CX_TEST_ASSERT(!cx_strcmp(ret, "/space3"));
-        
-        // fail test
-        ret = get_uri_from_clfreq("");
-        CX_TEST_ASSERT(ret.ptr == NULL);
-        ret = get_uri_from_clfreq("  ");
-        CX_TEST_ASSERT(ret.ptr == NULL);
-        ret = get_uri_from_clfreq("GET");
-        CX_TEST_ASSERT(ret.ptr == NULL);
-        ret = get_uri_from_clfreq("GET /path");
-        CX_TEST_ASSERT(ret.ptr == NULL);
-        ret = get_uri_from_clfreq(" /path2/ ");
-        CX_TEST_ASSERT(ret.ptr == NULL);
-    }
-}
-
-void http_reverse_proxy_add_tests(CxTestSuite *suite) {
-    cx_test_register(suite, test_safs_proxy_get_uri_from_clfreq);
-}
--- a/src/server/safs/proxy.h	Sun Feb 22 09:24:41 2026 +0100
+++ b/src/server/safs/proxy.h	Sun Feb 22 09:33:48 2026 +0100
@@ -39,9 +39,6 @@
 int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq);
 
 
-void http_reverse_proxy_add_tests(CxTestSuite *suite);
-
-
 #ifdef __cplusplus
 }
 #endif
--- a/src/server/util/uri.c	Sun Feb 22 09:24:41 2026 +0100
+++ b/src/server/util/uri.c	Sun Feb 22 09:33:48 2026 +0100
@@ -230,40 +230,12 @@
 /* --------------------------- util_uri_escape ---------------------------- */
 NSAPI_PUBLIC char *util_uri_escape(char *od, const char *s)
 {
-    int flagDbcsUri = allow_dbcs_uri();
-    char *d;
-
+    size_t len = (strlen(s)*3) + 1;
     if (!od)
-        od = (char *) MALLOC((strlen(s)*3) + 1);
-    d = od;
+        od = (char *) MALLOC(len);
 
-    while (*s) {
-        if (strchr("% ?#:+&*\"'<>\r\n", *s)) {
-            util_sprintf(d, "%%%02x", (unsigned char)*s);
-            ++s; d += 3;
-        }
-#ifdef XP_WIN32
-        else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
-#else
-        // Treat any character with the high bit set as a DBCS lead byte
-        else if (flagDbcsUri && s[1] && (s[0] & 0x80))
-#endif
-	{
-            // Escape the second byte of DBCS characters.  The first byte will
-            // have been escaped already.  IE translates all unescaped '\\'s
-            // into '/'.
-            // Bug 353999
-            util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
-            s += 2; d += 6;
-        }
-        else if (0x80 & *s) {
-            util_sprintf(d, "%%%02x", (unsigned char)*s);
-            ++s; d += 3;
-        } else {
-            *d++ = *s++;
-        }
-    }
-    *d = '\0';
+    util_uri_escape_s(od, len, s);
+    
     return od;
 }
 

mercurial