src/server/safs/proxy.c

changeset 696
27e42da5050f
parent 694
a5aa94800b59
child 699
d794871da099
equal deleted inserted replaced
695:ff14b97bdf14 696:27e42da5050f
32 #include <arpa/inet.h> 32 #include <arpa/inet.h>
33 #include <ctype.h> 33 #include <ctype.h>
34 #include <string.h> 34 #include <string.h>
35 35
36 #include "../util/pblock.h" 36 #include "../util/pblock.h"
37 #include "../util/util.h"
37 #include "../proxy/httpclient.h" 38 #include "../proxy/httpclient.h"
38 39
39 // Gets the uri part from an http request line
40 static cxstring get_uri_from_clfreq(const char *clfreq) {
41 cxstring uri = { NULL, 0 };
42
43 const char *begin = NULL;
44 const char *str = clfreq;
45 for(;*str != '\0';str++) {
46 if(*str < 33) {
47 if(begin) {
48 str++;
49 break;
50 }
51 } else {
52 if(!begin) {
53 begin = str;
54 }
55 }
56 }
57
58 begin = NULL;
59 for(;*str != '\0';str++) {
60 if(*str > 32) {
61 if(!begin) {
62 begin = str;
63 }
64 } else {
65 if(begin) {
66 break;
67 }
68 }
69 }
70
71 if(begin && *str != '\0') {
72 return cx_strn(begin, str-begin);
73 }
74
75 return uri;
76
77 }
78 40
79 typedef struct ProxyRequest { 41 typedef struct ProxyRequest {
80 Session *sn; 42 Session *sn;
81 Request *rq; 43 Request *rq;
82 44
175 } 137 }
176 138
177 int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq) { 139 int http_reverse_proxy_service(pblock *param, Session *sn, Request *rq) {
178 EventHandler *ev = sn->ev; 140 EventHandler *ev = sn->ev;
179 const char *method = pblock_findkeyval(pb_key_method, rq->reqpb); 141 const char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
180 const char *clfreq = pblock_findkeyval(pb_key_clf_request, rq->reqpb); 142 const char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
181 143 const char *query = pblock_findkeyval(pb_key_query, rq->reqpb);
182 cxstring uri = get_uri_from_clfreq(clfreq); 144
183 if(uri.length == 0) { 145 cxmutstr new_uri = CX_NULLSTR;
184 return REQ_ABORTED; 146 size_t uri_len = strlen(uri);
147 size_t query_len = query ? strlen(query) : 0;
148 size_t new_uri_alloc = ((uri_len + query_len) * 3) + 2;
149 new_uri.ptr = pool_malloc(sn->pool, new_uri_alloc);
150 new_uri.length = util_uri_escape_s(new_uri.ptr, new_uri_alloc, uri);
151 if(new_uri.length > 0 && query_len > 0) {
152 new_uri.ptr[new_uri.length] = '?';
153 memcpy(new_uri.ptr + new_uri.length + 1, query, query_len + 1);
154 new_uri.length = new_uri.length + 1 + query_len;
185 } 155 }
186 156
187 // remove some response headers, that were previously set by ObjectType 157 // remove some response headers, that were previously set by ObjectType
188 // or other SAFs 158 // or other SAFs
189 pblock_removekey(pb_key_content_type, rq->srvhdrs); 159 pblock_removekey(pb_key_content_type, rq->srvhdrs);
213 if(http_client_set_method(client, method)) { 183 if(http_client_set_method(client, method)) {
214 http_client_free(client); 184 http_client_free(client);
215 return REQ_ABORTED; 185 return REQ_ABORTED;
216 } 186 }
217 187
218 if(http_client_set_uri_len(client, uri.ptr, uri.length)) { 188 if(http_client_set_uri_len(client, new_uri.ptr, new_uri.length)) {
219 http_client_free(client); 189 http_client_free(client);
220 return REQ_ABORTED; 190 return REQ_ABORTED;
221 } 191 }
222 192
223 // test address 193 // test address
291 } 261 }
292 262
293 return REQ_PROCESSING; 263 return REQ_PROCESSING;
294 } 264 }
295 265
296
297
298 /* --------------------------------- Tests --------------------------------- */
299
300 static CX_TEST(test_safs_proxy_get_uri_from_clfreq) {
301 CX_TEST_DO {
302 cxstring ret;
303
304 ret = get_uri_from_clfreq("GET /uri HTTP/1.1");
305 CX_TEST_ASSERT(!cx_strcmp(ret, "/uri"));
306 ret = get_uri_from_clfreq("G / HTTP/1.1");
307 CX_TEST_ASSERT(!cx_strcmp(ret, "/"));
308 ret = get_uri_from_clfreq("POST /test%20/path HTTP/1.1");
309 CX_TEST_ASSERT(!cx_strcmp(ret, "/test%20/path"));
310 ret = get_uri_from_clfreq(" GET /leading_space HTTP/1.1");
311 CX_TEST_ASSERT(!cx_strcmp(ret, "/leading_space"));
312 ret = get_uri_from_clfreq(" PROPFIND /space2 HTTP/1.1");
313 CX_TEST_ASSERT(!cx_strcmp(ret, "/space2"));
314 ret = get_uri_from_clfreq("HEAD /trailing_space HTTP/1.1");
315 CX_TEST_ASSERT(!cx_strcmp(ret, "/trailing_space"));
316 ret = get_uri_from_clfreq(" GET /space3 HTTP/1.1 ");
317 CX_TEST_ASSERT(!cx_strcmp(ret, "/space3"));
318
319 // fail test
320 ret = get_uri_from_clfreq("");
321 CX_TEST_ASSERT(ret.ptr == NULL);
322 ret = get_uri_from_clfreq(" ");
323 CX_TEST_ASSERT(ret.ptr == NULL);
324 ret = get_uri_from_clfreq("GET");
325 CX_TEST_ASSERT(ret.ptr == NULL);
326 ret = get_uri_from_clfreq("GET /path");
327 CX_TEST_ASSERT(ret.ptr == NULL);
328 ret = get_uri_from_clfreq(" /path2/ ");
329 CX_TEST_ASSERT(ret.ptr == NULL);
330 }
331 }
332
333 void http_reverse_proxy_add_tests(CxTestSuite *suite) {
334 cx_test_register(suite, test_safs_proxy_get_uri_from_clfreq);
335 }

mercurial