--- a/src/server/safs/proxy.c Thu Feb 12 16:02:09 2026 +0100 +++ b/src/server/safs/proxy.c Fri Feb 13 12:16:09 2026 +0100 @@ -32,12 +32,124 @@ #include "../proxy/httpclient.h" +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; + +} + 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); + cxstring uri = get_uri_from_clfreq(clfreq); + if(uri.length == 0) { + return REQ_ABORTED; + } + + // setup HttpClient HttpClient *client = http_client_new(ev); + if(!client) { + return REQ_ABORTED; + } + if(http_client_set_method(client, method)) { + http_client_free(client); + return REQ_ABORTED; + } + if(http_client_set_uri_len(client, uri.ptr, uri.length)) { + http_client_free(client); + return REQ_ABORTED; + } + + // add request headers to the client + CxIterator i = pblock_iterator(rq->headers); + cx_foreach(pb_entry*, entry, i) { + // TODO: don't pass all headers + if(http_client_add_request_header(client, cx_mutstr(entry->param->name), cx_mutstr(entry->param->value))) { + http_client_free(client); + return REQ_ABORTED; + } + } + + if(http_client_start(client)) { + http_client_free(client); + return REQ_ABORTED; + } return REQ_PROCESSING; } + + + +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("GET / HTTP/1.1"); + CX_TEST_ASSERT(!cx_strcmp(ret, "/")); + ret = get_uri_from_clfreq("GET /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(" GET /space2 HTTP/1.1"); + CX_TEST_ASSERT(!cx_strcmp(ret, "/space2")); + ret = get_uri_from_clfreq("GET /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); +}