Skip to content

Commit ac0327c

Browse files
committed
test: add http.c coverage tests
Signed-off-by: Hans Zandbelt <[email protected]>
1 parent 3106108 commit ac0327c

File tree

1 file changed

+207
-1
lines changed

1 file changed

+207
-1
lines changed

test/test_http.c

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include "cfg/cfg_int.h"
4646
#include "cfg/provider.h"
4747
#include "helper.h"
48+
#include "http.h"
49+
#include <curl/curl.h>
4850

4951
START_TEST(test_http_accept) {
5052
request_rec *r = oidc_test_request_get();
@@ -105,14 +107,218 @@ START_TEST(test_http_accept) {
105107
}
106108
END_TEST
107109

110+
START_TEST(test_url_encode_decode) {
111+
request_rec *r = oidc_test_request_get();
112+
const char *in = "a b+c%/&=~";
113+
char *enc = oidc_http_url_encode(r, in);
114+
ck_assert_ptr_nonnull(enc);
115+
char *dec = oidc_http_url_decode(r, enc);
116+
ck_assert_ptr_nonnull(dec);
117+
ck_assert_msg(_oidc_strcmp(dec, in) == 0, "decoded value matches original");
118+
}
119+
END_TEST
120+
121+
START_TEST(test_hdr_getters_and_forwarded) {
122+
request_rec *r = oidc_test_request_get();
123+
apr_table_set(r->headers_in, "User-Agent", "MyAgent/1.0");
124+
apr_table_set(r->headers_in, "Content-Type", "text/plain");
125+
apr_table_set(r->headers_in, "Content-Length", "123");
126+
apr_table_set(r->headers_in, "X-Forwarded-For", "192.0.2.1, 10.0.0.1");
127+
apr_table_set(r->headers_in, "X-Forwarded-Host", "host1, host2");
128+
apr_table_set(r->headers_in, "Forwarded", "for=192.0.2.60; proto=http; by=203.0.113.43");
129+
130+
ck_assert_ptr_nonnull(oidc_http_hdr_in_user_agent_get(r));
131+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_user_agent_get(r), "MyAgent/1.0") == 0, "user-agent matches");
132+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_content_type_get(r), "text/plain") == 0, "content-type matches");
133+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_content_length_get(r), "123") == 0, "content-length matches");
134+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_x_forwarded_for_get(r), "192.0.2.1") == 0,
135+
"left-most X-Forwarded-For returned");
136+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_x_forwarded_host_get(r), "host1") == 0,
137+
"left-most X-Forwarded-Host returned");
138+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_forwarded_get(r, "proto"), "http") == 0, "forwarded proto parsed");
139+
}
140+
END_TEST
141+
142+
START_TEST(test_hdr_normalize_query_form) {
143+
request_rec *r = oidc_test_request_get();
144+
const char *name = "X(Invalid):Header/Name\t";
145+
char *norm = oidc_http_hdr_normalize_name(r, name);
146+
ck_assert_ptr_nonnull(norm);
147+
// ensure separators replaced by '-'
148+
ck_assert_msg(_oidc_strstr(norm, "-") != NULL, "normalized contains '-' character");
149+
150+
apr_table_t *params = apr_table_make(r->pool, 3);
151+
apr_table_set(params, "a", "1");
152+
apr_table_set(params, "b c", "d/e");
153+
char *qurl = oidc_http_query_encoded_url(r, "https://example.com/path", params);
154+
ck_assert_ptr_nonnull(qurl);
155+
// should contain 'a=1' and encoded b+c
156+
ck_assert_msg(_oidc_strstr(qurl, "a=1") != NULL, "query contains a=1");
157+
ck_assert_msg(_oidc_strstr(qurl, "b+c=") != NULL || _oidc_strstr(qurl, "b%20c=") != NULL,
158+
"query contains encoded b c key");
159+
160+
char *form = oidc_http_form_encoded_data(r, params);
161+
ck_assert_ptr_nonnull(form);
162+
ck_assert_msg(_oidc_strstr(form, "a=1") != NULL, "form contains a=1");
163+
}
164+
END_TEST
165+
166+
START_TEST(test_cookies_and_chunking) {
167+
request_rec *r = oidc_test_request_get();
168+
// existing cookie from helper: foo=bar; mod_auth_openidc_session=0123456789abcdef; baz=zot
169+
char *v = oidc_http_get_cookie(r, "foo");
170+
ck_assert_ptr_nonnull(v);
171+
ck_assert_msg(_oidc_strcmp(v, "bar") == 0, "foo cookie value is bar");
172+
173+
// set up chunked cookies in headers_in to simulate browser
174+
const char *cookie_header = "big=; big_chunks=3; big_0=AAA; big_1=BBB; big_2=CCC";
175+
apr_table_set(r->headers_in, "Cookie", cookie_header);
176+
char *big = oidc_http_get_chunked_cookie(r, "big", 5);
177+
ck_assert_ptr_nonnull(big);
178+
ck_assert_msg(_oidc_strcmp(big, "AAABBBCCC") == 0, "chunked cookie reconstructed");
179+
}
180+
END_TEST
181+
182+
START_TEST(test_proxy_options_and_s2auth) {
183+
const char **opts = oidc_http_proxy_auth_options();
184+
ck_assert_ptr_nonnull(opts);
185+
int found_basic = 0, found_digest = 0, found_ntlm = 0, found_any = 0;
186+
for (int i = 0; opts[i] != NULL; i++) {
187+
if (_oidc_strcmp(opts[i], OIDC_HTTP_PROXY_AUTH_BASIC) == 0)
188+
found_basic = 1;
189+
if (_oidc_strcmp(opts[i], OIDC_HTTP_PROXY_AUTH_DIGEST) == 0)
190+
found_digest = 1;
191+
if (_oidc_strcmp(opts[i], OIDC_HTTP_PROXY_AUTH_NTLM) == 0)
192+
found_ntlm = 1;
193+
if (_oidc_strcmp(opts[i], OIDC_HTTP_PROXY_AUTH_ANY) == 0)
194+
found_any = 1;
195+
}
196+
ck_assert_msg(found_basic && found_digest && found_ntlm && found_any, "proxy options include expected values");
197+
198+
unsigned long v;
199+
v = oidc_http_proxy_s2auth(OIDC_HTTP_PROXY_AUTH_BASIC);
200+
ck_assert_msg(v == CURLAUTH_BASIC, "basic maps to CURLAUTH_BASIC");
201+
v = oidc_http_proxy_s2auth(OIDC_HTTP_PROXY_AUTH_DIGEST);
202+
ck_assert_msg(v == CURLAUTH_DIGEST, "digest maps to CURLAUTH_DIGEST");
203+
v = oidc_http_proxy_s2auth(OIDC_HTTP_PROXY_AUTH_NTLM);
204+
ck_assert_msg(v == CURLAUTH_NTLM, "ntlm maps to CURLAUTH_NTLM");
205+
v = oidc_http_proxy_s2auth("no-such");
206+
ck_assert_msg(v == CURLAUTH_NONE, "unknown maps to CURLAUTH_NONE");
207+
}
208+
END_TEST
209+
210+
START_TEST(test_hdr_setters_and_cookie_set) {
211+
request_rec *r = oidc_test_request_get();
212+
oidc_http_hdr_in_set(r, "X-Test-Header", "test-val");
213+
ck_assert_msg(_oidc_strcmp(apr_table_get(r->headers_in, "X-Test-Header"), "test-val") == 0,
214+
"header in set/get works");
215+
216+
oidc_http_hdr_in_cookie_set(r, "a=b;c=d");
217+
ck_assert_ptr_nonnull(oidc_http_hdr_in_cookie_get(r));
218+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_cookie_get(r), "a=b;c=d") == 0, "cookie header set/get works");
219+
}
220+
END_TEST
221+
222+
START_TEST(test_hdr_out_location_and_traceparent) {
223+
request_rec *r = oidc_test_request_get();
224+
oidc_http_hdr_out_location_set(r, "https://example.com/redirect");
225+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_out_location_get(r), "https://example.com/redirect") == 0,
226+
"location out set/get works");
227+
228+
apr_table_set(r->headers_in, "traceparent", "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
229+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_traceparent_get(r),
230+
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01") == 0,
231+
"traceparent get works");
232+
}
233+
END_TEST
234+
235+
START_TEST(test_set_cookie_and_chunked_set) {
236+
request_rec *r = oidc_test_request_get();
237+
apr_time_t expires = apr_time_now() + apr_time_from_sec(3600);
238+
239+
oidc_http_set_cookie(r, "sname", "svalue", expires, "SameSite=Lax");
240+
const apr_array_header_t *h = apr_table_elts(r->err_headers_out);
241+
apr_table_entry_t *elts = (apr_table_entry_t *)h->elts;
242+
int found = 0;
243+
for (int i = 0; i < h->nelts; i++) {
244+
if (_oidc_strstr(elts[i].key, "Set-Cookie") || _oidc_strstr(elts[i].val, "sname=svalue")) {
245+
if (_oidc_strstr(elts[i].val, "sname=svalue")) {
246+
found = 1;
247+
break;
248+
}
249+
}
250+
}
251+
ck_assert_msg(found == 1, "Set-Cookie header contains our cookie");
252+
253+
/* test chunked cookie */
254+
char large[1024];
255+
for (int i = 0; i < 1000; i++)
256+
large[i] = 'A' + (i % 26);
257+
large[1000] = '\0';
258+
oidc_http_set_chunked_cookie(r, "chunked", large, expires, 100, "SameSite=Lax");
259+
/* ensure chunk counter cookie present in err_headers_out */
260+
h = apr_table_elts(r->err_headers_out);
261+
elts = (apr_table_entry_t *)h->elts;
262+
int found_cnt = 0;
263+
for (int i = 0; i < h->nelts; i++) {
264+
if (_oidc_strstr(elts[i].val, "chunked_chunks=")) {
265+
found_cnt = 1;
266+
break;
267+
}
268+
}
269+
ck_assert_msg(found_cnt == 1, "chunked counter cookie set");
270+
}
271+
END_TEST
272+
273+
START_TEST(test_other_header_getters) {
274+
request_rec *r = oidc_test_request_get();
275+
apr_table_set(r->headers_in, "X-Requested-With", "XMLHttpRequest");
276+
apr_table_set(r->headers_in, "Sec-Fetch-Mode", "navigate");
277+
apr_table_set(r->headers_in, "Sec-Fetch-Dest", "document");
278+
apr_table_set(r->headers_in, "Authorization", "Bearer tok123");
279+
apr_table_set(r->headers_in, "X-Forwarded-Proto", "https, http");
280+
apr_table_set(r->headers_in, "X-Forwarded-Port", "443, 80");
281+
apr_table_set(r->headers_in, "Host", "host.example.com");
282+
283+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_x_requested_with_get(r), "XMLHttpRequest") == 0,
284+
"X-Requested-With matches");
285+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_sec_fetch_mode_get(r), "navigate") == 0, "Sec-Fetch-Mode matches");
286+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_sec_fetch_dest_get(r), "document") == 0, "Sec-Fetch-Dest matches");
287+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_authorization_get(r), "Bearer tok123") == 0,
288+
"Authorization matches");
289+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_x_forwarded_proto_get(r), "https") == 0,
290+
"X-Forwarded-Proto left-most matches");
291+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_x_forwarded_port_get(r), "443") == 0,
292+
"X-Forwarded-Port left-most matches");
293+
ck_assert_msg(_oidc_strcmp(oidc_http_hdr_in_host_get(r), "host.example.com") == 0, "Host header matches");
294+
}
295+
END_TEST
296+
297+
START_TEST(test_init_and_cleanup_noop) {
298+
oidc_http_init();
299+
oidc_http_cleanup();
300+
ck_assert_msg(1 == 1, "init/cleanup execute without crash");
301+
}
302+
END_TEST
303+
108304
int main(void) {
109305
TCase *accept = tcase_create("accept");
110306
tcase_add_checked_fixture(accept, oidc_test_setup, oidc_test_teardown);
111307

112308
tcase_add_test(accept, test_http_accept);
309+
tcase_add_test(accept, test_url_encode_decode);
310+
tcase_add_test(accept, test_hdr_getters_and_forwarded);
311+
tcase_add_test(accept, test_hdr_normalize_query_form);
312+
tcase_add_test(accept, test_cookies_and_chunking);
313+
tcase_add_test(accept, test_proxy_options_and_s2auth);
314+
tcase_add_test(accept, test_hdr_setters_and_cookie_set);
315+
tcase_add_test(accept, test_hdr_out_location_and_traceparent);
316+
tcase_add_test(accept, test_set_cookie_and_chunked_set);
317+
tcase_add_test(accept, test_other_header_getters);
318+
tcase_add_test(accept, test_init_and_cleanup_noop);
113319

114320
Suite *s = suite_create("http");
115321
suite_add_tcase(s, accept);
116322

117323
return oidc_test_suite_run(s);
118-
}
324+
}

0 commit comments

Comments
 (0)