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