1 /* 2 * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright Siemens AG 2020 4 * 5 * Licensed under the Apache License 2.0 (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11 #include <openssl/http.h> 12 #include <openssl/pem.h> 13 #include <openssl/x509v3.h> 14 #include <openssl/err.h> 15 #include <string.h> 16 17 #include "testutil.h" 18 19 #define HTTP_STATUS_CODE_OK 200 20 #define HTTP_STATUS_CODES_FATAL_ERROR 399 21 #define HTTP_STATUS_CODES_NONFATAL_ERROR 400 22 23 static const ASN1_ITEM *x509_it = NULL; 24 static X509 *x509 = NULL; 25 #define RPATH "/path" 26 27 typedef struct { 28 BIO *out; 29 const char *content_type; 30 const char *txt; 31 char version; 32 int keep_alive; 33 } server_args; 34 35 /*- 36 * Pretty trivial HTTP mock server: 37 * For POST, copy request headers+body from mem BIO |in| as response to |out|. 38 * For GET, redirect to RPATH unless already there, else use |content_type| and 39 * respond with |txt| if not NULL, else with |rsp| of ASN1 type |it|. 40 * Take the status code suggsted by the client via special prefix of the path. 41 * On fatal status, respond with empty content. 42 * Response hdr has HTTP version 1.|version| and |keep_alive| (unless implicit). 43 */ 44 static int mock_http_server(BIO *in, BIO *out, char version, int keep_alive, 45 const char *content_type, const char *txt, 46 ASN1_VALUE *rsp, const ASN1_ITEM *it) 47 { 48 const char *req, *path; 49 long count = BIO_get_mem_data(in, (unsigned char **)&req); 50 const char *hdr = (char *)req, *suggested_status; 51 char status[4] = "200"; 52 int len; 53 int is_get = count >= 4 && CHECK_AND_SKIP_PREFIX(hdr, "GET "); 54 55 /* first line should contain "(GET|POST) (/<suggested status>)?/<path> HTTP/1.x" */ 56 if (!is_get 57 && !(TEST_true(count >= 5 && CHECK_AND_SKIP_PREFIX(hdr, "POST ")))) 58 return 0; 59 60 /* get any status code string to be returned suggested by test client */ 61 if (*hdr == '/') { 62 suggested_status = ++hdr; 63 while (*hdr >= '0' && *hdr <= '9') 64 hdr++; 65 if (hdr == suggested_status + sizeof(status) - 1) 66 strncpy(status, suggested_status, sizeof(status) - 1); 67 else 68 hdr = suggested_status - 1; 69 } 70 71 path = hdr; 72 hdr = strchr(hdr, ' '); 73 if (hdr == NULL) 74 return 0; 75 len = strlen("HTTP/1."); 76 if (!TEST_strn_eq(++hdr, "HTTP/1.", len)) 77 return 0; 78 hdr += len; 79 /* check for HTTP version 1.0 .. 1.1 */ 80 if (!TEST_char_le('0', *hdr) || !TEST_char_le(*hdr++, '1')) 81 return 0; 82 if (!TEST_char_eq(*hdr++, '\r') || !TEST_char_eq(*hdr++, '\n')) 83 return 0; 84 85 count -= (hdr - req); 86 if (count < 0 || out == NULL) 87 return 0; 88 89 if (!HAS_PREFIX(path, RPATH)) { 90 if (!is_get) 91 return 0; 92 return BIO_printf(out, "HTTP/1.%c 301 Moved Permanently\r\n" 93 "Location: %s\r\n\r\n", 94 version, RPATH) 95 > 0; /* same server */ 96 } 97 if (BIO_printf(out, "HTTP/1.%c %s %s\r\n", version, status, 98 /* mock some reason string: */ 99 strcmp(status, "200") == 0 ? "OK" : strcmp(status, "400") >= 0 ? "error" 100 : "fatal") 101 <= 0) 102 return 0; 103 if ((version == '0') == keep_alive) /* otherwise, default */ 104 if (BIO_printf(out, "Connection: %s\r\n", 105 version == '0' ? "keep-alive" : "close") 106 <= 0) 107 return 0; 108 109 if (strcmp(status, "399") == 0) /* HTTP_STATUS_CODES_FATAL_ERROR */ 110 return BIO_puts(out, "\r\n") == 2; /* empty content */ 111 112 if (is_get) { /* construct new header and body */ 113 if (txt != NULL) 114 len = strlen(txt); 115 else if ((len = ASN1_item_i2d(rsp, NULL, it)) <= 0) 116 return 0; 117 if (BIO_printf(out, "Content-Type: %s\r\n" 118 "Content-Length: %d\r\n\r\n", 119 content_type, len) 120 <= 0) 121 return 0; 122 if (txt != NULL) 123 return BIO_puts(out, txt); 124 return ASN1_item_i2d_bio(it, out, rsp); 125 } else { /* respond on POST request */ 126 if (CHECK_AND_SKIP_PREFIX(hdr, "Connection: ")) { 127 /* skip req Connection header */ 128 hdr = strstr(hdr, "\r\n"); 129 if (hdr == NULL) 130 return 0; 131 hdr += 2; 132 } 133 /* echo remaining request header and body */ 134 return BIO_write(out, hdr, count) == count; 135 } 136 } 137 138 static long http_bio_cb_ex(BIO *bio, int oper, const char *argp, size_t len, 139 int cmd, long argl, int ret, size_t *processed) 140 { 141 server_args *args = (server_args *)BIO_get_callback_arg(bio); 142 143 if (oper == (BIO_CB_CTRL | BIO_CB_RETURN) && cmd == BIO_CTRL_FLUSH) 144 ret = mock_http_server(bio, args->out, args->version, args->keep_alive, 145 args->content_type, args->txt, 146 (ASN1_VALUE *)x509, x509_it); 147 return ret; 148 } 149 150 #define text1 "test\n" 151 #define text2 "more\n" 152 #define REAL_SERVER_URL "http://httpbin.org/" 153 #define DOCTYPE_HTML "<!DOCTYPE html>\n" 154 155 /* do_get > 1 used for testing redirection */ 156 static int test_http_method(int do_get, int do_txt, int suggested_status) 157 { 158 BIO *wbio = BIO_new(BIO_s_mem()); 159 BIO *rbio = BIO_new(BIO_s_mem()); 160 server_args mock_args = { NULL, NULL, NULL, '0', 0 }; 161 BIO *req, *rsp; 162 char path[80]; 163 STACK_OF(CONF_VALUE) *headers = NULL; 164 const char *content_type; 165 int res = 0; 166 int real_server = do_txt && 0; /* remove "&& 0" for using real server */ 167 168 BIO_snprintf(path, sizeof(path), "/%d%s", suggested_status, 169 do_get > 1 ? "/will-be-redirected" : RPATH); 170 if (do_txt) { 171 content_type = "text/plain"; 172 req = BIO_new(BIO_s_mem()); 173 if (req == NULL 174 || BIO_puts(req, text1) != sizeof(text1) - 1 175 || BIO_puts(req, text2) != sizeof(text2) - 1) { 176 BIO_free(req); 177 req = NULL; 178 } 179 mock_args.txt = text1; 180 } else { 181 content_type = "application/x-x509-ca-cert"; 182 req = ASN1_item_i2d_mem_bio(x509_it, (ASN1_VALUE *)x509); 183 mock_args.txt = NULL; 184 } 185 if (wbio == NULL || rbio == NULL || req == NULL) 186 goto err; 187 188 mock_args.out = rbio; 189 mock_args.content_type = content_type; 190 BIO_set_callback_ex(wbio, http_bio_cb_ex); 191 BIO_set_callback_arg(wbio, (char *)&mock_args); 192 193 rsp = do_get ? OSSL_HTTP_get(real_server ? REAL_SERVER_URL : path, 194 NULL /* proxy */, NULL /* no_proxy */, 195 real_server ? NULL : wbio, 196 real_server ? NULL : rbio, 197 NULL /* bio_update_fn */, NULL /* arg */, 198 0 /* buf_size */, headers, 199 real_server ? "text/html; charset=utf-8" : content_type, 200 !do_txt /* expect_asn1 */, 201 OSSL_HTTP_DEFAULT_MAX_RESP_LEN, 0 /* timeout */) 202 : OSSL_HTTP_transfer(NULL, NULL /* host */, NULL /* port */, path, 203 0 /* use_ssl */, NULL /* proxy */, NULL /* no_pr */, 204 wbio, rbio, NULL /* bio_fn */, NULL /* arg */, 205 0 /* buf_size */, headers, content_type, 206 req, content_type, !do_txt /* expect_asn1 */, 207 OSSL_HTTP_DEFAULT_MAX_RESP_LEN, 0 /* timeout */, 208 0 /* keep_alive */); 209 if (!TEST_int_eq(suggested_status == HTTP_STATUS_CODES_FATAL_ERROR, rsp == NULL)) 210 goto err; 211 if (suggested_status == HTTP_STATUS_CODES_FATAL_ERROR) 212 res = 1; 213 if (rsp != NULL) { 214 if (do_get && real_server) { 215 char rtext[sizeof(DOCTYPE_HTML)]; 216 217 res = TEST_int_eq(BIO_gets(rsp, rtext, sizeof(rtext)), 218 sizeof(DOCTYPE_HTML) - 1) 219 && TEST_str_eq(rtext, DOCTYPE_HTML); 220 } else if (do_txt) { 221 char rtext[sizeof(text1) + 1 /* more space than needed */]; 222 223 res = TEST_int_eq(BIO_gets(rsp, rtext, sizeof(rtext)), 224 sizeof(text1) - 1) 225 && TEST_str_eq(rtext, text1); 226 } else { 227 X509 *rcert = d2i_X509_bio(rsp, NULL); 228 229 res = TEST_ptr(rcert) && TEST_int_eq(X509_cmp(x509, rcert), 0); 230 X509_free(rcert); 231 } 232 BIO_free(rsp); 233 } 234 235 err: 236 BIO_free(req); 237 BIO_free(wbio); 238 BIO_free(rbio); 239 sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); 240 return res; 241 } 242 243 static int test_http_keep_alive(char version, int keep_alive, int kept_alive) 244 { 245 BIO *wbio = BIO_new(BIO_s_mem()); 246 BIO *rbio = BIO_new(BIO_s_mem()); 247 BIO *rsp; 248 const char *const content_type = "application/x-x509-ca-cert"; 249 server_args mock_args = { NULL, NULL, NULL, '0', 0 }; 250 OSSL_HTTP_REQ_CTX *rctx = NULL; 251 int i, res = 0; 252 253 if (wbio == NULL || rbio == NULL) 254 goto err; 255 mock_args.out = rbio; 256 mock_args.content_type = content_type; 257 mock_args.version = version; 258 mock_args.keep_alive = kept_alive; 259 BIO_set_callback_ex(wbio, http_bio_cb_ex); 260 BIO_set_callback_arg(wbio, (char *)&mock_args); 261 262 for (res = 1, i = 1; res && i <= 2; i++) { 263 rsp = OSSL_HTTP_transfer(&rctx, NULL /* server */, NULL /* port */, 264 RPATH, 0 /* use_ssl */, 265 NULL /* proxy */, NULL /* no_proxy */, 266 wbio, rbio, NULL /* bio_update_fn */, NULL, 267 0 /* buf_size */, NULL /* headers */, 268 NULL /* content_type */, NULL /* req => GET */, 269 content_type, 0 /* ASN.1 not expected */, 270 0 /* max_resp_len */, 0 /* timeout */, 271 keep_alive); 272 if (keep_alive == 2 && kept_alive == 0) 273 res = res && TEST_ptr_null(rsp) 274 && TEST_int_eq(OSSL_HTTP_is_alive(rctx), 0); 275 else 276 res = res && TEST_ptr(rsp) 277 && TEST_int_eq(OSSL_HTTP_is_alive(rctx), keep_alive > 0); 278 BIO_free(rsp); 279 (void)BIO_reset(rbio); /* discard response contents */ 280 keep_alive = 0; 281 } 282 OSSL_HTTP_close(rctx, res); 283 284 err: 285 BIO_free(wbio); 286 BIO_free(rbio); 287 return res; 288 } 289 290 static int test_http_url_frag_ok(const char *url, int exp_ssl, const char *exp_host, 291 const char *exp_port, const char *exp_path, const char *exp_frag) 292 { 293 char *user, *host, *port, *path, *query, *frag; 294 int exp_num, num, ssl; 295 int res; 296 297 if (!TEST_int_eq(sscanf(exp_port, "%d", &exp_num), 1)) 298 return 0; 299 res = TEST_true(OSSL_HTTP_parse_url(url, &ssl, &user, &host, &port, &num, 300 &path, &query, &frag)) 301 && TEST_str_eq(host, exp_host) 302 && TEST_str_eq(port, exp_port) 303 && TEST_int_eq(num, exp_num) 304 && TEST_str_eq(path, exp_path) 305 && TEST_int_eq(ssl, exp_ssl); 306 if (res && *user != '\0') 307 res = TEST_str_eq(user, "user:pass"); 308 if (res) 309 res = TEST_str_eq(frag, exp_frag); 310 if (res && *query != '\0') 311 res = TEST_str_eq(query, "q"); 312 OPENSSL_free(user); 313 OPENSSL_free(host); 314 OPENSSL_free(port); 315 OPENSSL_free(path); 316 OPENSSL_free(query); 317 OPENSSL_free(frag); 318 return res; 319 } 320 321 static int test_http_url_ok(const char *url, int exp_ssl, const char *exp_host, 322 const char *exp_port, const char *exp_path) 323 { 324 return test_http_url_frag_ok(url, exp_ssl, exp_host, exp_port, exp_path, ""); 325 } 326 327 static int test_http_url_path_query_ok(const char *url, const char *exp_path_qu) 328 { 329 char *host, *path; 330 int res; 331 332 res = TEST_true(OSSL_HTTP_parse_url(url, NULL, NULL, &host, NULL, NULL, 333 &path, NULL, NULL)) 334 && TEST_str_eq(host, "host") 335 && TEST_str_eq(path, exp_path_qu); 336 OPENSSL_free(host); 337 OPENSSL_free(path); 338 return res; 339 } 340 341 static int test_http_url_host_ok(const char *url, const char *exp_host) 342 { 343 char *host; 344 int res; 345 346 res = TEST_true(OSSL_HTTP_parse_url(url, NULL, NULL, &host, NULL, NULL, 347 NULL, NULL, NULL)) 348 && TEST_str_eq(host, exp_host); 349 OPENSSL_free(host); 350 return res; 351 } 352 353 static int test_http_url_dns(void) 354 { 355 return test_http_url_ok("host:65535/path", 0, "host", "65535", "/path"); 356 } 357 358 static int test_http_url_ip(void) 359 { 360 return test_http_url_ok("1.2.3.4:5678//blahblablah", 0, "1.2.3.4", "5678", "//blahblablah"); 361 } 362 363 static int test_http_url_timestamp(void) 364 { 365 return test_http_url_ok("host/p/2017-01-03T00:00:00", 0, "host", "80", 366 "/p/2017-01-03T00:00:00") 367 && test_http_url_ok("http://host/p/2017-01-03T00:00:00", 0, "host", 368 "80", "/p/2017-01-03T00:00:00") 369 && test_http_url_ok("https://host/p/2017-01-03T00:00:00", 1, "host", 370 "443", "/p/2017-01-03T00:00:00"); 371 } 372 373 static int test_http_url_path_query(void) 374 { 375 return test_http_url_path_query_ok("http://usr@host:1/p?q=x#frag", "/p?q=x") 376 && test_http_url_path_query_ok("http://host?query#frag", "/?query") 377 && test_http_url_path_query_ok("http://host:9999#frag", "/"); 378 } 379 380 static int test_http_url_userinfo_query_fragment(void) 381 { 382 return test_http_url_frag_ok("user:pass@host/p?q#fr", 0, "host", "80", "/p", "fr") 383 && test_http_url_frag_ok("host.example.org/some/path#://not-a-scheme/not.a.host:404", 0, 384 "host.example.org", "80", "/some/path", "://not-a-scheme/not.a.host:404"); 385 } 386 387 static int test_http_url_at_sign_outside_authority(void) 388 { 389 return test_http_url_host_ok("http://host/p@attacker.test", "host") 390 && test_http_url_host_ok("http://host/p?q=@attacker.test", "host") 391 && test_http_url_host_ok("http://host/p?q#fr@attacker.test", "host"); 392 } 393 394 static int test_http_url_ipv4(void) 395 { 396 return test_http_url_ok("https://1.2.3.4/p/q", 1, "1.2.3.4", "443", "/p/q"); 397 } 398 399 static int test_http_url_ipv6(void) 400 { 401 return test_http_url_ok("http://[FF01::101]:6", 0, "[FF01::101]", "6", "/"); 402 } 403 404 static int test_http_url_invalid(const char *url) 405 { 406 char *host = "1", *port = "1", *path = "1"; 407 int num = 1, ssl = 1; 408 int res; 409 410 res = TEST_false(OSSL_HTTP_parse_url(url, &ssl, NULL, &host, &port, &num, 411 &path, NULL, NULL)) 412 && TEST_ptr_null(host) 413 && TEST_ptr_null(port) 414 && TEST_ptr_null(path); 415 if (!res) { 416 OPENSSL_free(host); 417 OPENSSL_free(port); 418 OPENSSL_free(path); 419 } 420 return res; 421 } 422 423 static int test_http_url_invalid_prefix(void) 424 { 425 return test_http_url_invalid("htttps://1.2.3.4:65535/pkix"); 426 } 427 428 static int test_http_url_invalid_port(void) 429 { 430 return test_http_url_invalid("https://1.2.3.4:65536/pkix") 431 && test_http_url_invalid("https://1.2.3.4:"); 432 } 433 434 static int test_http_url_invalid_path(void) 435 { 436 return test_http_url_invalid("https://[FF01::101]pkix"); 437 } 438 439 static int test_http_crlf_rejected(void) 440 { 441 BIO *wbio = BIO_new(BIO_s_mem()); 442 BIO *rbio = BIO_new(BIO_s_mem()); 443 BIO *req = BIO_new(BIO_s_mem()); 444 BIO *proxy_bio = BIO_new(BIO_s_mem()); 445 OSSL_HTTP_REQ_CTX *rctx = NULL; 446 int res = 0; 447 448 if (!TEST_ptr(wbio) 449 || !TEST_ptr(rbio) 450 || !TEST_ptr(req) 451 || !TEST_ptr(proxy_bio) 452 || !TEST_int_eq(BIO_puts(req, "x"), 1) 453 || !TEST_ptr(rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, 0))) 454 goto err; 455 456 ERR_clear_error(); 457 res = TEST_false(OSSL_HTTP_REQ_CTX_set_request_line(rctx, 0 /* GET */, 458 NULL, NULL, "/path\r\nInjected: value")) 459 && TEST_false(OSSL_HTTP_REQ_CTX_set_request_line(rctx, 0 /* GET */, 460 "server\r\nInjected: value", "80", RPATH)) 461 && TEST_false(OSSL_HTTP_REQ_CTX_set_request_line(rctx, 0 /* GET */, 462 "server", "80\r\nInjected: value", RPATH)) 463 && TEST_true(OSSL_HTTP_REQ_CTX_set_request_line(rctx, 0 /* GET */, 464 NULL, NULL, RPATH)) 465 && TEST_false(OSSL_HTTP_REQ_CTX_add1_header(rctx, 466 "X-Test\r\nInjected", "value")) 467 && TEST_false(OSSL_HTTP_REQ_CTX_add1_header(rctx, 468 "X-Test", "value\r\nInjected: value")) 469 && TEST_false(OSSL_HTTP_set1_request(rctx, RPATH, NULL, 470 "text/plain\r\nInjected: value", req, 471 NULL, 0 /* expect_asn1 */, 0 /* max_resp_len */, 472 0 /* timeout */, 0 /* keep_alive */)) 473 && TEST_false(OSSL_HTTP_proxy_connect(proxy_bio, 474 "server\r\nInjected: value", "443", NULL, NULL, 475 0 /* timeout */, NULL, NULL)) 476 && TEST_false(OSSL_HTTP_proxy_connect(proxy_bio, 477 "server", "443\r\nInjected: value", NULL, NULL, 478 0 /* timeout */, NULL, NULL)); 479 480 err: 481 ERR_clear_error(); 482 OSSL_HTTP_REQ_CTX_free(rctx); 483 BIO_free(wbio); 484 BIO_free(rbio); 485 BIO_free(req); 486 BIO_free(proxy_bio); 487 return res; 488 } 489 490 static int test_http_get_txt(void) 491 { 492 return test_http_method(1 /* GET */, 1, HTTP_STATUS_CODE_OK); 493 } 494 495 static int test_http_get_txt_redirected(void) 496 { 497 return test_http_method(2 /* GET with redirection */, 1, HTTP_STATUS_CODE_OK); 498 } 499 500 static int test_http_get_txt_fatal_status(void) 501 { 502 return test_http_method(1 /* GET */, 1, HTTP_STATUS_CODES_FATAL_ERROR); 503 } 504 505 static int test_http_get_txt_error_status(void) 506 { 507 return test_http_method(1 /* GET */, 1, HTTP_STATUS_CODES_NONFATAL_ERROR); 508 } 509 510 static int test_http_post_txt(void) 511 { 512 return test_http_method(0 /* POST */, 1, HTTP_STATUS_CODE_OK); 513 } 514 515 static int test_http_get_x509(void) 516 { 517 return test_http_method(1 /* GET */, 0, HTTP_STATUS_CODE_OK); 518 } 519 520 static int test_http_get_x509_redirected(void) 521 { 522 return test_http_method(2 /* GET with redirection */, 0, HTTP_STATUS_CODE_OK); 523 } 524 525 static int test_http_post_x509(void) 526 { 527 return test_http_method(0 /* POST */, 0, HTTP_STATUS_CODE_OK); 528 } 529 530 static int test_http_post_x509_fatal_status(void) 531 { 532 return test_http_method(0 /* POST */, 0, HTTP_STATUS_CODES_FATAL_ERROR); 533 } 534 535 static int test_http_post_x509_error_status(void) 536 { 537 return test_http_method(0 /* POST */, 0, HTTP_STATUS_CODES_NONFATAL_ERROR); 538 } 539 540 static int test_http_keep_alive_0_no_no(void) 541 { 542 return test_http_keep_alive('0', 0, 0); 543 } 544 545 static int test_http_keep_alive_1_no_no(void) 546 { 547 return test_http_keep_alive('1', 0, 0); 548 } 549 550 static int test_http_keep_alive_0_prefer_yes(void) 551 { 552 return test_http_keep_alive('0', 1, 1); 553 } 554 555 static int test_http_keep_alive_1_prefer_yes(void) 556 { 557 return test_http_keep_alive('1', 1, 1); 558 } 559 560 static int test_http_keep_alive_0_require_yes(void) 561 { 562 return test_http_keep_alive('0', 2, 1); 563 } 564 565 static int test_http_keep_alive_1_require_yes(void) 566 { 567 return test_http_keep_alive('1', 2, 1); 568 } 569 570 static int test_http_keep_alive_0_require_no(void) 571 { 572 return test_http_keep_alive('0', 2, 0); 573 } 574 575 static int test_http_keep_alive_1_require_no(void) 576 { 577 return test_http_keep_alive('1', 2, 0); 578 } 579 580 static int test_http_resp_hdr_limit(size_t limit) 581 { 582 BIO *wbio = BIO_new(BIO_s_mem()); 583 BIO *rbio = BIO_new(BIO_s_mem()); 584 BIO *mem = NULL; 585 server_args mock_args = { NULL, NULL, NULL, '0', 0 }; 586 int res = 0; 587 OSSL_HTTP_REQ_CTX *rctx = NULL; 588 589 if (!TEST_ptr(wbio) || !TEST_ptr(rbio)) 590 goto err; 591 592 mock_args.txt = text1; 593 mock_args.content_type = "text/plain"; 594 mock_args.version = '1'; 595 mock_args.out = rbio; 596 597 BIO_set_callback_ex(wbio, http_bio_cb_ex); 598 BIO_set_callback_arg(wbio, (char *)&mock_args); 599 600 rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, 8192); 601 if (!TEST_ptr(rctx)) 602 goto err; 603 604 if (!TEST_true(OSSL_HTTP_REQ_CTX_set_request_line(rctx, 0 /* GET */, 605 NULL, NULL, RPATH))) 606 goto err; 607 608 OSSL_HTTP_REQ_CTX_set_max_response_hdr_lines(rctx, limit); 609 mem = OSSL_HTTP_REQ_CTX_exchange(rctx); 610 611 /* 612 * Note the server sends 4 http response headers, thus we expect to 613 * see failure here when we set header limit in http response to 1. 614 */ 615 if (limit == 1) 616 res = TEST_ptr_null(mem); 617 else 618 res = TEST_ptr(mem); 619 620 err: 621 BIO_free(wbio); 622 BIO_free(rbio); 623 OSSL_HTTP_REQ_CTX_free(rctx); 624 625 return res; 626 } 627 628 static int test_hdr_resp_hdr_limit_none(void) 629 { 630 return test_http_resp_hdr_limit(0); 631 } 632 633 static int test_hdr_resp_hdr_limit_short(void) 634 { 635 return (test_http_resp_hdr_limit(1)); 636 } 637 638 static int test_hdr_resp_hdr_limit_256(void) 639 { 640 return test_http_resp_hdr_limit(256); 641 } 642 643 static int test_http_adapt_proxy_empty_server(void) 644 { 645 const char *proxy = "http://proxy.local:8080"; 646 647 return TEST_str_eq(OSSL_HTTP_adapt_proxy(proxy, "abc", "", 0), proxy) 648 && TEST_str_eq(OSSL_HTTP_adapt_proxy(proxy, "abc", "[]", 0), proxy); 649 } 650 651 void cleanup_tests(void) 652 { 653 X509_free(x509); 654 } 655 656 OPT_TEST_DECLARE_USAGE("cert.pem\n") 657 658 int setup_tests(void) 659 { 660 if (!test_skip_common_options()) 661 return 0; 662 663 x509_it = ASN1_ITEM_rptr(X509); 664 if (!TEST_ptr((x509 = load_cert_pem(test_get_argument(0), NULL)))) 665 return 0; 666 667 ADD_TEST(test_http_url_dns); 668 ADD_TEST(test_http_url_ip); 669 ADD_TEST(test_http_url_timestamp); 670 ADD_TEST(test_http_url_path_query); 671 ADD_TEST(test_http_url_userinfo_query_fragment); 672 ADD_TEST(test_http_url_at_sign_outside_authority); 673 ADD_TEST(test_http_url_ipv4); 674 ADD_TEST(test_http_url_ipv6); 675 ADD_TEST(test_http_url_invalid_prefix); 676 ADD_TEST(test_http_url_invalid_port); 677 ADD_TEST(test_http_url_invalid_path); 678 ADD_TEST(test_http_crlf_rejected); 679 680 ADD_TEST(test_http_get_txt); 681 ADD_TEST(test_http_get_txt_redirected); 682 ADD_TEST(test_http_get_txt_fatal_status); 683 ADD_TEST(test_http_get_txt_error_status); 684 ADD_TEST(test_http_post_txt); 685 ADD_TEST(test_http_get_x509); 686 ADD_TEST(test_http_get_x509_redirected); 687 ADD_TEST(test_http_post_x509); 688 ADD_TEST(test_http_post_x509_fatal_status); 689 ADD_TEST(test_http_post_x509_error_status); 690 691 ADD_TEST(test_http_keep_alive_0_no_no); 692 ADD_TEST(test_http_keep_alive_1_no_no); 693 ADD_TEST(test_http_keep_alive_0_prefer_yes); 694 ADD_TEST(test_http_keep_alive_1_prefer_yes); 695 ADD_TEST(test_http_keep_alive_0_require_yes); 696 ADD_TEST(test_http_keep_alive_1_require_yes); 697 ADD_TEST(test_http_keep_alive_0_require_no); 698 ADD_TEST(test_http_keep_alive_1_require_no); 699 700 ADD_TEST(test_hdr_resp_hdr_limit_none); 701 ADD_TEST(test_hdr_resp_hdr_limit_short); 702 ADD_TEST(test_hdr_resp_hdr_limit_256); 703 ADD_TEST(test_http_adapt_proxy_empty_server); 704 return 1; 705 } 706