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