1 /*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2016 Tatsuhiro Tsujikawa
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 #include "shrpx_http_test.h"
26
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif // HAVE_UNISTD_H
30
31 #include <cstdlib>
32
33 #include "munitxx.h"
34
35 #include "shrpx_http.h"
36 #include "shrpx_config.h"
37 #include "shrpx_log.h"
38
39 using namespace std::literals;
40
41 namespace shrpx {
42
43 namespace {
44 const MunitTest tests[]{
45 munit_void_test(test_shrpx_http_create_forwarded),
46 munit_void_test(test_shrpx_http_create_via_header_value),
47 munit_void_test(test_shrpx_http_create_affinity_cookie),
48 munit_void_test(test_shrpx_http_create_altsvc_header_value),
49 munit_void_test(test_shrpx_http_check_http_scheme),
50 munit_test_end(),
51 };
52 } // namespace
53
54 const MunitSuite http_suite{
55 "/http", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE,
56 };
57
test_shrpx_http_create_forwarded(void)58 void test_shrpx_http_create_forwarded(void) {
59 BlockAllocator balloc(1024, 1024);
60
61 assert_stdsv_equal(
62 "by=\"example.com:3000\";for=\"[::1]\";host=\"www.example.com\";"
63 "proto=https"sv,
64 http::create_forwarded(
65 balloc, FORWARDED_BY | FORWARDED_FOR | FORWARDED_HOST | FORWARDED_PROTO,
66 "example.com:3000"_sr, "[::1]"_sr, "www.example.com"_sr, "https"_sr));
67
68 assert_stdsv_equal("for=192.168.0.1"sv,
69 http::create_forwarded(balloc, FORWARDED_FOR, "alpha"_sr,
70 "192.168.0.1"_sr, "bravo"_sr,
71 "charlie"_sr));
72
73 assert_stdsv_equal(
74 "by=_hidden;for=\"[::1]\""sv,
75 http::create_forwarded(balloc, FORWARDED_BY | FORWARDED_FOR, "_hidden"_sr,
76 "[::1]"_sr, ""_sr, ""_sr));
77
78 assert_stdsv_equal(
79 "by=\"[::1]\";for=_hidden"sv,
80 http::create_forwarded(balloc, FORWARDED_BY | FORWARDED_FOR, "[::1]"_sr,
81 "_hidden"_sr, ""_sr, ""_sr));
82
83 assert_stdsv_equal(""sv,
84 http::create_forwarded(balloc,
85 FORWARDED_BY | FORWARDED_FOR |
86 FORWARDED_HOST | FORWARDED_PROTO,
87 ""_sr, ""_sr, ""_sr, ""_sr));
88 }
89
test_shrpx_http_create_via_header_value(void)90 void test_shrpx_http_create_via_header_value(void) {
91 std::array<char, 16> buf;
92
93 auto end = http::create_via_header_value(std::begin(buf), 1, 1);
94
95 assert_stdstring_equal("1.1 nghttpx", (std::string{std::begin(buf), end}));
96
97 std::fill(std::begin(buf), std::end(buf), '\0');
98
99 end = http::create_via_header_value(std::begin(buf), 2, 0);
100
101 assert_stdstring_equal("2 nghttpx", (std::string{std::begin(buf), end}));
102 }
103
test_shrpx_http_create_affinity_cookie(void)104 void test_shrpx_http_create_affinity_cookie(void) {
105 BlockAllocator balloc(1024, 1024);
106 StringRef c;
107
108 c = http::create_affinity_cookie(balloc, "cookie-val"_sr, 0xf1e2d3c4u,
109 StringRef{}, false);
110
111 assert_stdsv_equal("cookie-val=f1e2d3c4"sv, c);
112
113 c = http::create_affinity_cookie(balloc, "alpha"_sr, 0x00000000u, StringRef{},
114 true);
115
116 assert_stdsv_equal("alpha=00000000; Secure"sv, c);
117
118 c = http::create_affinity_cookie(balloc, "bravo"_sr, 0x01111111u, "bar"_sr,
119 false);
120
121 assert_stdsv_equal("bravo=01111111; Path=bar"sv, c);
122
123 c = http::create_affinity_cookie(balloc, "charlie"_sr, 0x01111111u, "bar"_sr,
124 true);
125
126 assert_stdsv_equal("charlie=01111111; Path=bar; Secure"sv, c);
127 }
128
test_shrpx_http_create_altsvc_header_value(void)129 void test_shrpx_http_create_altsvc_header_value(void) {
130 {
131 BlockAllocator balloc(1024, 1024);
132 std::vector<AltSvc> altsvcs{
133 AltSvc{
134 .protocol_id = "h3"_sr,
135 .host = "127.0.0.1"_sr,
136 .service = "443"_sr,
137 .params = "ma=3600"_sr,
138 },
139 };
140
141 assert_stdsv_equal(R"(h3="127.0.0.1:443"; ma=3600)"sv,
142 http::create_altsvc_header_value(balloc, altsvcs));
143 }
144
145 {
146 BlockAllocator balloc(1024, 1024);
147 std::vector<AltSvc> altsvcs{
148 AltSvc{
149 .protocol_id = "h3"_sr,
150 .service = "443"_sr,
151 .params = "ma=3600"_sr,
152 },
153 AltSvc{
154 .protocol_id = "h3%"_sr,
155 .host = "\"foo\""_sr,
156 .service = "4433"_sr,
157 },
158 };
159
160 assert_stdsv_equal(R"(h3=":443"; ma=3600, h3%25="\"foo\":4433")"sv,
161 http::create_altsvc_header_value(balloc, altsvcs));
162 }
163 }
164
165 void test_shrpx_http_check_http_scheme(void) {
166 assert_true(http::check_http_scheme("https"_sr, true));
167 assert_false(http::check_http_scheme("https"_sr, false));
168 assert_false(http::check_http_scheme("http"_sr, true));
169 assert_true(http::check_http_scheme("http"_sr, false));
170 assert_false(http::check_http_scheme("foo"_sr, true));
171 assert_false(http::check_http_scheme("foo"_sr, false));
172 assert_false(http::check_http_scheme(StringRef{}, true));
173 assert_false(http::check_http_scheme(StringRef{}, false));
174 }
175
176 } // namespace shrpx
177