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