]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testHttpRequest.cc
Cleanup: remove SQUID_NO_STRING_BUFFER_PROTECT and SQUID_UNIT_TEST macros
[thirdparty/squid.git] / src / tests / testHttpRequest.cc
1 #include "squid.h"
2
3 #include <cppunit/TestAssert.h>
4
5 #include "HttpHeader.h"
6 #include "HttpRequest.h"
7 #include "Mem.h"
8 #include "mime_header.h"
9 #include "testHttpRequest.h"
10
11 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest );
12
13 /** wrapper for testing HttpRequest object private and protected functions */
14 class PrivateHttpRequest : public HttpRequest
15 {
16 public:
17 bool doSanityCheckStartLine(MemBuf *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); };
18 };
19
20 /* init memory pools */
21
22 void
23 testHttpRequest::setUp()
24 {
25 Mem::Init();
26 httpHeaderInitModule();
27 }
28
29 /*
30 * Test creating an HttpRequest object from a Url and method
31 */
32 void
33 testHttpRequest::testCreateFromUrlAndMethod()
34 {
35 /* vanilla url */
36 unsigned short expected_port;
37 char * url = xstrdup("http://foo:90/bar");
38 HttpRequest *aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
39 expected_port = 90;
40 HttpRequest *nullRequest = NULL;
41 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
42 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
43 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
44 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
45 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
46 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
47 xfree(url);
48
49 /* vanilla url, different method */
50 url = xstrdup("http://foo/bar");
51 aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_PUT);
52 expected_port = 80;
53 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
54 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_PUT);
55 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
56 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
57 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
58 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url));
59 xfree(url);
60
61 /* a connect url with non-CONNECT data */
62 url = xstrdup(":foo/bar");
63 aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_CONNECT);
64 xfree(url);
65 CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
66
67 /* a CONNECT url with CONNECT data */
68 url = xstrdup("foo:45");
69 aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_CONNECT);
70 expected_port = 45;
71 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
72 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_CONNECT);
73 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
74 CPPUNIT_ASSERT_EQUAL(String(""), aRequest->urlpath);
75 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_NONE, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
76 CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url));
77 xfree(url);
78 }
79
80 /*
81 * Test creating an HttpRequest object from a Url alone.
82 */
83 void
84 testHttpRequest::testCreateFromUrl()
85 {
86 /* vanilla url */
87 unsigned short expected_port;
88 char * url = xstrdup("http://foo:90/bar");
89 HttpRequest *aRequest = HttpRequest::CreateFromUrl(url);
90 expected_port = 90;
91 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
92 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
93 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
94 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
95 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
96 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
97 xfree(url);
98 }
99
100 /*
101 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
102 */
103 void
104 testHttpRequest::testIPv6HostColonBug()
105 {
106 unsigned short expected_port;
107 char * url = NULL;
108 HttpRequest *aRequest = NULL;
109
110 /* valid IPv6 address without port */
111 url = xstrdup("http://[2000:800::45]/foo");
112 aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
113 expected_port = 80;
114 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
115 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
116 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
117 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
118 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
119 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url));
120 xfree(url);
121
122 /* valid IPv6 address with port */
123 url = xstrdup("http://[2000:800::45]:90/foo");
124 aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
125 expected_port = 90;
126 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
127 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
128 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
129 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
130 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
131 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url));
132 xfree(url);
133
134 /* IPv6 address as invalid (bug trigger) */
135 url = xstrdup("http://2000:800::45/foo");
136 aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
137 expected_port = 80;
138 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
139 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
140 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
141 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
142 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
143 CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url));
144 xfree(url);
145 }
146
147 void
148 testHttpRequest::testSanityCheckStartLine()
149 {
150 MemBuf input;
151 PrivateHttpRequest engine;
152 Http::StatusCode error = Http::scNone;
153 size_t hdr_len;
154 input.init();
155
156 // a valid request line
157 input.append("GET / HTTP/1.1\n\n", 16);
158 hdr_len = headersEnd(input.content(), input.contentSize());
159 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
160 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
161 input.reset();
162 error = Http::scNone;
163
164 input.append("GET / HTTP/1.1\n\n", 18);
165 hdr_len = headersEnd(input.content(), input.contentSize());
166 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
167 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
168 input.reset();
169 error = Http::scNone;
170
171 // strange but valid methods
172 input.append(". / HTTP/1.1\n\n", 14);
173 hdr_len = headersEnd(input.content(), input.contentSize());
174 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
175 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
176 input.reset();
177 error = Http::scNone;
178
179 input.append("OPTIONS * HTTP/1.1\n\n", 20);
180 hdr_len = headersEnd(input.content(), input.contentSize());
181 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
182 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
183 input.reset();
184 error = Http::scNone;
185
186 // TODO no method
187
188 // TODO binary code in method
189
190 // TODO no URL
191
192 // TODO no status (okay)
193
194 // TODO non-HTTP protocol
195
196 input.append(" \n\n", 8);
197 hdr_len = headersEnd(input.content(), input.contentSize());
198 CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(&input, hdr_len, &error) );
199 CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
200 input.reset();
201 error = Http::scNone;
202 }