Fri, 13 Feb 2026 12:16:09 +0100
setup HttpClient in proxy SAF
--- a/src/server/proxy/httpclient.c Thu Feb 12 16:02:09 2026 +0100 +++ b/src/server/proxy/httpclient.c Fri Feb 13 12:16:09 2026 +0100 @@ -29,6 +29,8 @@ #include "httpclient.h" #include <cx/buffer.h> +#include <stdlib.h> +#include <string.h> static int client_connected(EventHandler *ev, Event *event); @@ -56,6 +58,15 @@ return client; } +void http_client_free(HttpClient *client) { + cxMempoolFree(client->mp); + header_array_free(client->request_headers); + free(client->addr); + free(client->method); + free(client->uri); + free(client); +} + int http_client_set_addr(HttpClient *client, const struct sockaddr *addr, socklen_t addrlen) { free(client->addr); client->addr = NULL; @@ -72,6 +83,39 @@ return 0; } +int http_client_set_method(HttpClient *client, const char *method) { + return http_client_set_method_len(client, method, method ? strlen(method) : 0); +} + +int http_client_set_uri(HttpClient *client, const char *uri) { + return http_client_set_uri_len(client, uri, uri ? strlen(uri) : 0); +} + +static int client_set_str(char **ptr, const char *str, size_t len) { + free(*ptr); + if(str) { + char *newvalue = malloc(len+1); + if(!newvalue) { + *ptr = NULL; + return 1; + } + memcpy(newvalue, str, len); + newvalue[len] = 0; + *ptr = newvalue; + } else { + *ptr = NULL; + return 0; + } +} + +int http_client_set_method_len(HttpClient *client, const char *method, size_t len) { + return client_set_str(&client->method, method, len); +} + +int http_client_set_uri_len(HttpClient *client, const char *uri, size_t len) { + return client_set_str(&client->uri, uri, len); +} + int http_client_add_request_header(HttpClient *client, cxmutstr name, cxmutstr value) { return header_array_add(client->request_headers, name, value); } @@ -113,7 +157,7 @@ if(ret) { close(socketfd); } - return 1; + return ret; } static int create_req_buffer(HttpClient *client) {
--- a/src/server/proxy/httpclient.h Thu Feb 12 16:02:09 2026 +0100 +++ b/src/server/proxy/httpclient.h Fri Feb 13 12:16:09 2026 +0100 @@ -100,8 +100,18 @@ HttpClient* http_client_new(EventHandler *ev); +void http_client_free(HttpClient *client); + int http_client_set_addr(HttpClient *client, const struct sockaddr *addr, socklen_t addrlen); +int http_client_set_method(HttpClient *client, const char *method); + +int http_client_set_uri(HttpClient *client, const char *uri); + +int http_client_set_method_len(HttpClient *client, const char *method, size_t len); + +int http_client_set_uri_len(HttpClient *client, const char *uri, size_t len); + /* * Adds a request header *
--- 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); +}
--- a/src/server/safs/proxy.h Thu Feb 12 16:02:09 2026 +0100 +++ b/src/server/safs/proxy.h Fri Feb 13 12:16:09 2026 +0100 @@ -30,12 +30,16 @@ #define SAF_PROXY_H #include "../public/nsapi.h" +#include <cx/test.h> #ifdef __cplusplus extern "C" { #endif + +int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq); -int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq); + +void http_reverse_proxy_add_tests(CxTestSuite *suite); #ifdef __cplusplus
--- a/src/server/test/main.c Thu Feb 12 16:02:09 2026 +0100 +++ b/src/server/test/main.c Fri Feb 13 12:16:09 2026 +0100 @@ -39,6 +39,7 @@ #include "../util/plist.h" #include "../util/date.h" #include "../daemon/vfs.h" +#include "../safs/proxy.h" #include "test.h" @@ -191,6 +192,9 @@ cx_test_register(suite, test_webdav_proppatch); cx_test_register(suite, test_webdav_put); + // saf tests + http_reverse_proxy_add_tests(suite); + // plugin tests #ifdef ENABLE_POSTGRESQL register_pg_tests(argc, argv, suite);