]>
Commit | Line | Data |
---|---|---|
4e0938ef | 1 | /* |
4ac4a490 | 2 | * Copyright (C) 1996-2017 The Squid Software Foundation and contributors |
4e0938ef AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
f7f3304a | 9 | #include "squid.h" |
e1f7507e | 10 | |
c21ad0f5 | 11 | #include <cppunit/TestAssert.h> |
12 | ||
ec6f82c1 | 13 | #include "HttpHeader.h" |
c21ad0f5 | 14 | #include "HttpRequest.h" |
b6149797 | 15 | #include "mime_header.h" |
602d9612 | 16 | #include "testHttpRequest.h" |
7f861c77 AJ |
17 | #include "unitTestMain.h" |
18 | ||
c21ad0f5 | 19 | CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest ); |
20 | ||
0f9db2d6 AJ |
21 | /** wrapper for testing HttpRequest object private and protected functions */ |
22 | class PrivateHttpRequest : public HttpRequest | |
23 | { | |
24 | public: | |
84ae6223 | 25 | bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); }; |
0f9db2d6 AJ |
26 | }; |
27 | ||
c21ad0f5 | 28 | /* init memory pools */ |
29 | ||
16555581 | 30 | void |
31 | testHttpRequest::setUp() | |
c21ad0f5 | 32 | { |
16555581 | 33 | Mem::Init(); |
50a43a49 | 34 | AnyP::UriScheme::Init(); |
0f9db2d6 | 35 | httpHeaderInitModule(); |
16555581 | 36 | } |
c21ad0f5 | 37 | |
38 | /* | |
39 | * Test creating an HttpRequest object from a Url and method | |
40 | */ | |
41 | void | |
d6067ac1 | 42 | testHttpRequest::testCreateFromUrl() |
c21ad0f5 | 43 | { |
d6067ac1 | 44 | /* vanilla url, implict method */ |
f45dd259 | 45 | unsigned short expected_port; |
c21ad0f5 | 46 | char * url = xstrdup("http://foo:90/bar"); |
d6067ac1 AJ |
47 | HttpRequest *aRequest = HttpRequest::CreateFromUrl(url); |
48 | expected_port = 90; | |
49 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); | |
50 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); | |
51 | CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host())); | |
52 | CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest->url.path()); | |
53 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); | |
54 | CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url)); | |
55 | xfree(url); | |
56 | ||
57 | /* vanilla url */ | |
58 | url = xstrdup("http://foo:90/bar"); | |
59 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); | |
c21ad0f5 | 60 | expected_port = 90; |
5c51bffb | 61 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); |
c2a7cefd | 62 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); |
5c51bffb | 63 | CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host())); |
51b5dcf5 | 64 | CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest->url.path()); |
4e3f4dc7 | 65 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); |
30abd221 | 66 | CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url)); |
c21ad0f5 | 67 | xfree(url); |
cc192b50 | 68 | |
c21ad0f5 | 69 | /* vanilla url, different method */ |
70 | url = xstrdup("http://foo/bar"); | |
d6067ac1 | 71 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_PUT); |
c21ad0f5 | 72 | expected_port = 80; |
5c51bffb | 73 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); |
c2a7cefd | 74 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_PUT); |
5c51bffb | 75 | CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host())); |
51b5dcf5 | 76 | CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest->url.path()); |
4e3f4dc7 | 77 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); |
30abd221 | 78 | CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url)); |
a0b3b22c | 79 | xfree(url); |
cc192b50 | 80 | |
c21ad0f5 | 81 | /* a connect url with non-CONNECT data */ |
d6067ac1 | 82 | HttpRequest *nullRequest = nullptr; |
c21ad0f5 | 83 | url = xstrdup(":foo/bar"); |
d6067ac1 | 84 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_CONNECT); |
c21ad0f5 | 85 | xfree(url); |
86 | CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest); | |
cc192b50 | 87 | |
c21ad0f5 | 88 | /* a CONNECT url with CONNECT data */ |
89 | url = xstrdup("foo:45"); | |
d6067ac1 | 90 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_CONNECT); |
c21ad0f5 | 91 | expected_port = 45; |
5c51bffb | 92 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); |
c2a7cefd | 93 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_CONNECT); |
5c51bffb | 94 | CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host())); |
51b5dcf5 | 95 | CPPUNIT_ASSERT_EQUAL(SBuf(), aRequest->url.path()); |
4e3f4dc7 | 96 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_NONE, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); |
30abd221 | 97 | CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url)); |
c21ad0f5 | 98 | xfree(url); |
c21ad0f5 | 99 | |
d6067ac1 | 100 | // XXX: check METHOD_NONE input handling |
c21ad0f5 | 101 | } |
cc192b50 | 102 | |
103 | /* | |
104 | * Test BUG: URL '2000:800:45' opens host 2000 port 800 !! | |
105 | */ | |
106 | void | |
107 | testHttpRequest::testIPv6HostColonBug() | |
108 | { | |
f45dd259 | 109 | unsigned short expected_port; |
cc192b50 | 110 | char * url = NULL; |
111 | HttpRequest *aRequest = NULL; | |
112 | ||
113 | /* valid IPv6 address without port */ | |
114 | url = xstrdup("http://[2000:800::45]/foo"); | |
d6067ac1 | 115 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); |
cc192b50 | 116 | expected_port = 80; |
5c51bffb | 117 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); |
c2a7cefd | 118 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); |
5c51bffb | 119 | CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->url.host())); |
51b5dcf5 | 120 | CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest->url.path()); |
4e3f4dc7 | 121 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); |
cc192b50 | 122 | CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url)); |
123 | xfree(url); | |
124 | ||
125 | /* valid IPv6 address with port */ | |
126 | url = xstrdup("http://[2000:800::45]:90/foo"); | |
d6067ac1 | 127 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); |
cc192b50 | 128 | expected_port = 90; |
5c51bffb | 129 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); |
c2a7cefd | 130 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); |
5c51bffb | 131 | CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->url.host())); |
51b5dcf5 | 132 | CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest->url.path()); |
4e3f4dc7 | 133 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); |
cc192b50 | 134 | CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url)); |
135 | xfree(url); | |
136 | ||
137 | /* IPv6 address as invalid (bug trigger) */ | |
138 | url = xstrdup("http://2000:800::45/foo"); | |
d6067ac1 | 139 | aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); |
cc192b50 | 140 | expected_port = 80; |
5c51bffb | 141 | CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); |
c2a7cefd | 142 | CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); |
5c51bffb | 143 | CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->url.host())); |
51b5dcf5 | 144 | CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest->url.path()); |
4e3f4dc7 | 145 | CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme())); |
cc192b50 | 146 | CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url)); |
147 | xfree(url); | |
148 | } | |
0f9db2d6 AJ |
149 | |
150 | void | |
151 | testHttpRequest::testSanityCheckStartLine() | |
152 | { | |
153 | MemBuf input; | |
154 | PrivateHttpRequest engine; | |
955394ce | 155 | Http::StatusCode error = Http::scNone; |
0f9db2d6 AJ |
156 | size_t hdr_len; |
157 | input.init(); | |
158 | ||
159 | // a valid request line | |
160 | input.append("GET / HTTP/1.1\n\n", 16); | |
161 | hdr_len = headersEnd(input.content(), input.contentSize()); | |
84ae6223 | 162 | CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) ); |
955394ce | 163 | CPPUNIT_ASSERT_EQUAL(error, Http::scNone); |
0f9db2d6 | 164 | input.reset(); |
955394ce | 165 | error = Http::scNone; |
0f9db2d6 AJ |
166 | |
167 | input.append("GET / HTTP/1.1\n\n", 18); | |
168 | hdr_len = headersEnd(input.content(), input.contentSize()); | |
84ae6223 | 169 | CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) ); |
955394ce | 170 | CPPUNIT_ASSERT_EQUAL(error, Http::scNone); |
0f9db2d6 | 171 | input.reset(); |
955394ce | 172 | error = Http::scNone; |
0f9db2d6 AJ |
173 | |
174 | // strange but valid methods | |
175 | input.append(". / HTTP/1.1\n\n", 14); | |
176 | hdr_len = headersEnd(input.content(), input.contentSize()); | |
84ae6223 | 177 | CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) ); |
955394ce | 178 | CPPUNIT_ASSERT_EQUAL(error, Http::scNone); |
0f9db2d6 | 179 | input.reset(); |
955394ce | 180 | error = Http::scNone; |
0f9db2d6 AJ |
181 | |
182 | input.append("OPTIONS * HTTP/1.1\n\n", 20); | |
183 | hdr_len = headersEnd(input.content(), input.contentSize()); | |
84ae6223 | 184 | CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) ); |
955394ce | 185 | CPPUNIT_ASSERT_EQUAL(error, Http::scNone); |
0f9db2d6 | 186 | input.reset(); |
955394ce | 187 | error = Http::scNone; |
0f9db2d6 AJ |
188 | |
189 | // TODO no method | |
190 | ||
191 | // TODO binary code in method | |
192 | ||
193 | // TODO no URL | |
194 | ||
195 | // TODO no status (okay) | |
196 | ||
197 | // TODO non-HTTP protocol | |
198 | ||
199 | input.append(" \n\n", 8); | |
200 | hdr_len = headersEnd(input.content(), input.contentSize()); | |
84ae6223 | 201 | CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(input.content(), hdr_len, &error) ); |
955394ce | 202 | CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader); |
0f9db2d6 | 203 | input.reset(); |
955394ce | 204 | error = Http::scNone; |
0f9db2d6 | 205 | } |
f53969cc | 206 |