Sun, 22 Feb 2026 09:33:48 +0100
proxy: get uri from pb_key_uri/pb_key_query instead of clf-request
--- 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; }