]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testHttpRequest.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / tests / testHttpRequest.cc
1 #define SQUID_UNIT_TEST 1
2 #include "squid.h"
3
4 #include <cppunit/TestAssert.h>
5
6 #include "testHttpRequest.h"
7 #include "HttpRequest.h"
8 #include "Mem.h"
9 #include "protos.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_status *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, METHOD_GET);
39 expected_port = 90;
40 HttpRequest *nullRequest = NULL;
41 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
42 CPPUNIT_ASSERT(aRequest->method == 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, aRequest->protocol);
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, METHOD_PUT);
52 expected_port = 80;
53 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
54 CPPUNIT_ASSERT(aRequest->method == 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, aRequest->protocol);
58 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url));
59
60 /* a connect url with non-CONNECT data */
61 url = xstrdup(":foo/bar");
62 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
63 xfree(url);
64 CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
65
66 /* a CONNECT url with CONNECT data */
67 url = xstrdup("foo:45");
68 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
69 expected_port = 45;
70 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
71 CPPUNIT_ASSERT(aRequest->method == METHOD_CONNECT);
72 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
73 CPPUNIT_ASSERT_EQUAL(String(""), aRequest->urlpath);
74 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_NONE, aRequest->protocol);
75 CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url));
76 xfree(url);
77 }
78
79 /*
80 * Test creating an HttpRequest object from a Url alone.
81 */
82 void
83 testHttpRequest::testCreateFromUrl()
84 {
85 /* vanilla url */
86 unsigned short expected_port;
87 char * url = xstrdup("http://foo:90/bar");
88 HttpRequest *aRequest = HttpRequest::CreateFromUrl(url);
89 expected_port = 90;
90 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
91 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
92 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
93 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
94 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
95 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
96 xfree(url);
97 }
98
99 /*
100 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
101 */
102 void
103 testHttpRequest::testIPv6HostColonBug()
104 {
105 unsigned short expected_port;
106 char * url = NULL;
107 HttpRequest *aRequest = NULL;
108
109 /* valid IPv6 address without port */
110 url = xstrdup("http://[2000:800::45]/foo");
111 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
112 expected_port = 80;
113 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
114 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
115 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
116 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
117 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
118 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url));
119 xfree(url);
120
121 /* valid IPv6 address with port */
122 url = xstrdup("http://[2000:800::45]:90/foo");
123 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
124 expected_port = 90;
125 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
126 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
127 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
128 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
129 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
130 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url));
131 xfree(url);
132
133 /* IPv6 address as invalid (bug trigger) */
134 url = xstrdup("http://2000:800::45/foo");
135 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
136 expected_port = 80;
137 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
138 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
139 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
140 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
141 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
142 CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url));
143 xfree(url);
144 }
145
146 void
147 testHttpRequest::testSanityCheckStartLine()
148 {
149 MemBuf input;
150 PrivateHttpRequest engine;
151 http_status error = HTTP_STATUS_NONE;
152 size_t hdr_len;
153 input.init();
154
155 // a valid request line
156 input.append("GET / HTTP/1.1\n\n", 16);
157 hdr_len = headersEnd(input.content(), input.contentSize());
158 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
159 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
160 input.reset();
161 error = HTTP_STATUS_NONE;
162
163 input.append("GET / HTTP/1.1\n\n", 18);
164 hdr_len = headersEnd(input.content(), input.contentSize());
165 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
166 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
167 input.reset();
168 error = HTTP_STATUS_NONE;
169
170 // strange but valid methods
171 input.append(". / HTTP/1.1\n\n", 14);
172 hdr_len = headersEnd(input.content(), input.contentSize());
173 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
174 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
175 input.reset();
176 error = HTTP_STATUS_NONE;
177
178 input.append("OPTIONS * HTTP/1.1\n\n", 20);
179 hdr_len = headersEnd(input.content(), input.contentSize());
180 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
181 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
182 input.reset();
183 error = HTTP_STATUS_NONE;
184
185 // TODO no method
186
187 // TODO binary code in method
188
189 // TODO no URL
190
191 // TODO no status (okay)
192
193 // TODO non-HTTP protocol
194
195 input.append(" \n\n", 8);
196 hdr_len = headersEnd(input.content(), input.contentSize());
197 CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(&input, hdr_len, &error) );
198 CPPUNIT_ASSERT_EQUAL(error, HTTP_INVALID_HEADER);
199 input.reset();
200 error = HTTP_STATUS_NONE;
201 }