]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testHttpRequest.cc
2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
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.
11 #include <cppunit/TestAssert.h>
13 #include "HttpHeader.h"
14 #include "HttpRequest.h"
15 #include "MasterXaction.h"
16 #include "mime_header.h"
17 #include "testHttpRequest.h"
18 #include "unitTestMain.h"
20 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest
);
22 /** wrapper for testing HttpRequest object private and protected functions */
23 class PrivateHttpRequest
: public HttpRequest
26 PrivateHttpRequest(const MasterXaction::Pointer
&mx
) : HttpRequest(mx
) {}
27 bool doSanityCheckStartLine(const char *b
, const size_t h
, Http::StatusCode
*e
) { return sanityCheckStartLine(b
,h
,e
); };
30 /* init memory pools */
33 testHttpRequest::setUp()
36 AnyP::UriScheme::Init();
37 httpHeaderInitModule();
41 * Test creating an HttpRequest object from a Url and method
44 testHttpRequest::testCreateFromUrl()
46 /* vanilla url, implict method */
47 unsigned short expected_port
;
48 char * url
= xstrdup("http://foo:90/bar");
49 const MasterXaction::Pointer mx
= new MasterXaction(XactionInitiator::initClient
);
50 HttpRequest
*aRequest
= HttpRequest::FromUrl(url
, mx
);
52 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
53 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_GET
);
54 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest
->url
.host()));
55 CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest
->url
.path());
56 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
57 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url
));
61 url
= xstrdup("http://foo:90/bar");
62 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_GET
);
64 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
65 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_GET
);
66 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest
->url
.host()));
67 CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest
->url
.path());
68 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
69 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url
));
72 /* vanilla url, different method */
73 url
= xstrdup("http://foo/bar");
74 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_PUT
);
76 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
77 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_PUT
);
78 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest
->url
.host()));
79 CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest
->url
.path());
80 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
81 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url
));
84 /* a connect url with non-CONNECT data */
85 HttpRequest
*nullRequest
= nullptr;
86 url
= xstrdup(":foo/bar");
87 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_CONNECT
);
89 CPPUNIT_ASSERT_EQUAL(nullRequest
, aRequest
);
91 /* a CONNECT url with CONNECT data */
92 url
= xstrdup("foo:45");
93 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_CONNECT
);
95 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
96 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_CONNECT
);
97 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest
->url
.host()));
98 CPPUNIT_ASSERT_EQUAL(SBuf(), aRequest
->url
.path());
99 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_NONE
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
100 CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url
));
103 // XXX: check METHOD_NONE input handling
107 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
110 testHttpRequest::testIPv6HostColonBug()
112 unsigned short expected_port
;
114 HttpRequest
*aRequest
= NULL
;
116 /* valid IPv6 address without port */
117 url
= xstrdup("http://[2000:800::45]/foo");
118 const MasterXaction::Pointer mx
= new MasterXaction(XactionInitiator::initClient
);
119 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_GET
);
121 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
122 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_GET
);
123 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest
->url
.host()));
124 CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest
->url
.path());
125 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
126 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url
));
129 /* valid IPv6 address with port */
130 url
= xstrdup("http://[2000:800::45]:90/foo");
131 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_GET
);
133 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
134 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_GET
);
135 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest
->url
.host()));
136 CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest
->url
.path());
137 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
138 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url
));
141 /* IPv6 address as invalid (bug trigger) */
142 url
= xstrdup("http://2000:800::45/foo");
143 aRequest
= HttpRequest::FromUrl(url
, mx
, Http::METHOD_GET
);
145 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->url
.port());
146 CPPUNIT_ASSERT(aRequest
->method
== Http::METHOD_GET
);
147 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest
->url
.host()));
148 CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest
->url
.path());
149 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
150 CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url
));
155 testHttpRequest::testSanityCheckStartLine()
158 const MasterXaction::Pointer mx
= new MasterXaction(XactionInitiator::initClient
);
159 PrivateHttpRequest
engine(mx
);
160 Http::StatusCode error
= Http::scNone
;
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
);
170 error
= Http::scNone
;
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
);
177 error
= Http::scNone
;
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
);
185 error
= Http::scNone
;
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
);
192 error
= Http::scNone
;
196 // TODO binary code in method
200 // TODO no status (okay)
202 // TODO non-HTTP protocol
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
);
209 error
= Http::scNone
;