quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

unit2603.c (5456B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "unitcheck.h"
     25 
     26 #include "urldata.h"
     27 #include "http.h"
     28 #include "http1.h"
     29 #include "curl_trc.h"
     30 
     31 #ifndef CURL_DISABLE_HTTP
     32 static void check_eq(const char *s, const char *exp_s, const char *name)
     33 {
     34   if(s && exp_s) {
     35     if(strcmp(s, exp_s)) {
     36       curl_mfprintf(stderr, "expected %s: '%s' but got '%s'\n",
     37                     name, exp_s, s);
     38       fail("unexpected req component");
     39     }
     40   }
     41   else if(!s && exp_s) {
     42     curl_mfprintf(stderr, "expected %s: '%s' but got NULL\n", name, exp_s);
     43     fail("unexpected req component");
     44   }
     45   else if(s && !exp_s) {
     46     curl_mfprintf(stderr, "expected %s: NULL but got '%s'\n", name, s);
     47     fail("unexpected req component");
     48   }
     49 }
     50 
     51 struct tcase {
     52   const char **input;
     53   const char *default_scheme;
     54   const char *method;
     55   const char *scheme;
     56   const char *authority;
     57   const char *path;
     58   size_t header_count;
     59   size_t input_remain;
     60 };
     61 
     62 static void parse_success(const struct tcase *t)
     63 {
     64   struct h1_req_parser p;
     65   const char *buf;
     66   size_t buflen, i, in_len, in_consumed;
     67   CURLcode err;
     68   ssize_t nread;
     69 
     70   Curl_h1_req_parse_init(&p, 1024);
     71   in_len = in_consumed = 0;
     72   for(i = 0; t->input[i]; ++i) {
     73     buf = t->input[i];
     74     buflen = strlen(buf);
     75     in_len += buflen;
     76     nread = Curl_h1_req_parse_read(&p, buf, buflen, t->default_scheme,
     77                                    0, &err);
     78     if(nread < 0) {
     79       curl_mfprintf(stderr, "got err %d parsing: '%s'\n", err, buf);
     80       fail("error consuming");
     81     }
     82     in_consumed += (size_t)nread;
     83     if((size_t)nread != buflen) {
     84       if(!p.done) {
     85         curl_mfprintf(stderr, "only %zd/%zu consumed for: '%s'\n",
     86                       nread, buflen, buf);
     87         fail("not all consumed");
     88       }
     89     }
     90   }
     91 
     92   fail_if(!p.done, "end not detected");
     93   fail_if(!p.req, "not request created");
     94   if(t->input_remain != (in_len - in_consumed)) {
     95     curl_mfprintf(stderr, "expected %zu input bytes to remain, but got %zu\n",
     96                   t->input_remain, in_len - in_consumed);
     97     fail("unexpected input consumption");
     98   }
     99   if(p.req) {
    100     check_eq(p.req->method, t->method, "method");
    101     check_eq(p.req->scheme, t->scheme, "scheme");
    102     check_eq(p.req->authority, t->authority, "authority");
    103     check_eq(p.req->path, t->path, "path");
    104     if(Curl_dynhds_count(&p.req->headers) != t->header_count) {
    105       curl_mfprintf(stderr, "expected %zu headers but got %zu\n",
    106                     t->header_count, Curl_dynhds_count(&p.req->headers));
    107       fail("unexpected req header count");
    108     }
    109   }
    110 
    111   Curl_h1_req_parse_free(&p);
    112 }
    113 #endif
    114 
    115 static CURLcode test_unit2603(char *arg)
    116 {
    117   UNITTEST_BEGIN_SIMPLE
    118 
    119 #ifndef CURL_DISABLE_HTTP
    120   static const char *T1_INPUT[] = {
    121     "GET /path HTTP/1.1\r\nHost: test.curl.se\r\n\r\n",
    122     NULL,
    123   };
    124   static const struct tcase TEST1a = {
    125     T1_INPUT, NULL, "GET", NULL, NULL, "/path", 1, 0
    126   };
    127   static const struct tcase TEST1b = {
    128     T1_INPUT, "https", "GET", "https", NULL, "/path", 1, 0
    129   };
    130 
    131   static const char *T2_INPUT[] = {
    132     "GET /path HTT",
    133     "P/1.1\r\nHost: te",
    134     "st.curl.se\r\n\r",
    135     "\n12345678",
    136     NULL,
    137   };
    138   static const struct tcase TEST2 = {
    139     T2_INPUT, NULL, "GET", NULL, NULL, "/path", 1, 8
    140   };
    141 
    142   static const char *T3_INPUT[] = {
    143     "GET ftp://ftp.curl.se/xxx?a=2 HTTP/1.1\r\nContent-Length: 0\r",
    144     "\nUser-Agent: xxx\r\n\r\n",
    145     NULL,
    146   };
    147   static const struct tcase TEST3a = {
    148     T3_INPUT, NULL, "GET", "ftp", "ftp.curl.se", "/xxx?a=2", 2, 0
    149   };
    150 
    151   static const char *T4_INPUT[] = {
    152     "CONNECT ftp.curl.se:123 HTTP/1.1\r\nContent-Length: 0\r\n",
    153     "User-Agent: xxx\r\n",
    154     "nothing:  \r\n\r\n\n\n",
    155     NULL,
    156   };
    157   static const struct tcase TEST4a = {
    158     T4_INPUT, NULL, "CONNECT", NULL, "ftp.curl.se:123", NULL, 3, 2
    159   };
    160 
    161   static const char *T5_INPUT[] = {
    162     "OPTIONS * HTTP/1.1\r\nContent-Length: 0\r\nBlabla: xxx.yyy\r",
    163     "\n\tzzzzzz\r\n\r\n",
    164     "123",
    165     NULL,
    166   };
    167   static const struct tcase TEST5a = {
    168     T5_INPUT, NULL, "OPTIONS", NULL, NULL, "*", 2, 3
    169   };
    170 
    171   static const char *T6_INPUT[] = {
    172     "PUT /path HTTP/1.1\nHost: test.curl.se\n\n123",
    173     NULL,
    174   };
    175   static const struct tcase TEST6a = {
    176     T6_INPUT, NULL, "PUT", NULL, NULL, "/path", 1, 3
    177   };
    178 
    179   parse_success(&TEST1a);
    180   parse_success(&TEST1b);
    181   parse_success(&TEST2);
    182   parse_success(&TEST3a);
    183   parse_success(&TEST4a);
    184   parse_success(&TEST5a);
    185   parse_success(&TEST6a);
    186 #endif
    187 
    188   UNITTEST_END_SIMPLE
    189 }