]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testHttpRequest.cc
Removed inclusion of protos.h from most clients.
[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 "HttpHeader.h"
8 #include "HttpRequest.h"
9 #include "Mem.h"
10 #include "mime_header.h"
11
12 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest );
13
14 /** wrapper for testing HttpRequest object private and protected functions */
15 class PrivateHttpRequest : public HttpRequest
16 {
17 public:
18 bool doSanityCheckStartLine(MemBuf *b, const size_t h, http_status *e) { return sanityCheckStartLine(b,h,e); };
19 };
20
21 /* init memory pools */
22
23 void
24 testHttpRequest::setUp()
25 {
26 Mem::Init();
27 httpHeaderInitModule();
28 }
29
30 /*
31 * Test creating an HttpRequest object from a Url and method
32 */
33 void
34 testHttpRequest::testCreateFromUrlAndMethod()
35 {
36 /* vanilla url */
37 unsigned short expected_port;
38 char * url = xstrdup("http://foo:90/bar");
39 HttpRequest *aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
40 expected_port = 90;
41 HttpRequest *nullRequest = NULL;
42 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
43 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
44 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
45 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
46 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
47 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
48 xfree(url);
49
50 /* vanilla url, different method */
51 url = xstrdup("http://foo/bar");
52 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_PUT);
53 expected_port = 80;
54 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
55 CPPUNIT_ASSERT(aRequest->method == METHOD_PUT);
56 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
57 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
58 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
59 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url));
60
61 /* a connect url with non-CONNECT data */
62 url = xstrdup(":foo/bar");
63 aRequest = HttpRequest::CreateFromUrlAndMethod(url, 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, METHOD_CONNECT);
70 expected_port = 45;
71 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
72 CPPUNIT_ASSERT(aRequest->method == 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, aRequest->protocol);
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 == 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, aRequest->protocol);
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, METHOD_GET);
113 expected_port = 80;
114 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
115 CPPUNIT_ASSERT(aRequest->method == 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, aRequest->protocol);
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, METHOD_GET);
125 expected_port = 90;
126 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
127 CPPUNIT_ASSERT(aRequest->method == 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, aRequest->protocol);
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, METHOD_GET);
137 expected_port = 80;
138 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
139 CPPUNIT_ASSERT(aRequest->method == 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, aRequest->protocol);
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_status error = HTTP_STATUS_NONE;
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_STATUS_NONE);
161 input.reset();
162 error = HTTP_STATUS_NONE;
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_STATUS_NONE);
168 input.reset();
169 error = HTTP_STATUS_NONE;
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_STATUS_NONE);
176 input.reset();
177 error = HTTP_STATUS_NONE;
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_STATUS_NONE);
183 input.reset();
184 error = HTTP_STATUS_NONE;
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_INVALID_HEADER);
200 input.reset();
201 error = HTTP_STATUS_NONE;
202 }