3 #include <cppunit/TestAssert.h>
5 #include "HttpHeader.h"
6 #include "HttpRequest.h"
8 #include "mime_header.h"
9 #include "testHttpRequest.h"
11 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest
);
13 /** wrapper for testing HttpRequest object private and protected functions */
14 class PrivateHttpRequest
: public HttpRequest
17 bool doSanityCheckStartLine(MemBuf
*b
, const size_t h
, Http::StatusCode
*e
) { return sanityCheckStartLine(b
,h
,e
); };
20 /* init memory pools */
23 testHttpRequest::setUp()
26 httpHeaderInitModule();
30 * Test creating an HttpRequest object from a Url and method
33 testHttpRequest::testCreateFromUrlAndMethod()
36 unsigned short expected_port
;
37 char * url
= xstrdup("http://foo:90/bar");
38 HttpRequest
*aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_GET
);
40 HttpRequest
*nullRequest
= NULL
;
41 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
42 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
46 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url
));
49 /* vanilla url, different method */
50 url
= xstrdup("http://foo/bar");
51 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_PUT
);
53 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
54 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
58 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url
));
61 /* a connect url with non-CONNECT data */
62 url
= xstrdup(":foo/bar");
63 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_CONNECT
);
65 CPPUNIT_ASSERT_EQUAL(nullRequest
, aRequest
);
67 /* a CONNECT url with CONNECT data */
68 url
= xstrdup("foo:45");
69 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_CONNECT
);
71 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
72 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
76 CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url
));
81 * Test creating an HttpRequest object from a Url alone.
84 testHttpRequest::testCreateFromUrl()
87 unsigned short expected_port
;
88 char * url
= xstrdup("http://foo:90/bar");
89 HttpRequest
*aRequest
= HttpRequest::CreateFromUrl(url
);
91 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
92 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
96 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url
));
101 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
104 testHttpRequest::testIPv6HostColonBug()
106 unsigned short expected_port
;
108 HttpRequest
*aRequest
= NULL
;
110 /* valid IPv6 address without port */
111 url
= xstrdup("http://[2000:800::45]/foo");
112 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_GET
);
114 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
115 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
119 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url
));
122 /* valid IPv6 address with port */
123 url
= xstrdup("http://[2000:800::45]:90/foo");
124 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_GET
);
126 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
127 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
131 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url
));
134 /* IPv6 address as invalid (bug trigger) */
135 url
= xstrdup("http://2000:800::45/foo");
136 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, Http::METHOD_GET
);
138 CPPUNIT_ASSERT_EQUAL(expected_port
, aRequest
->port
);
139 CPPUNIT_ASSERT(aRequest
->method
== Http::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
, static_cast<AnyP::ProtocolType
>(aRequest
->url
.getScheme()));
143 CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url
));
148 testHttpRequest::testSanityCheckStartLine()
151 PrivateHttpRequest engine
;
152 Http::StatusCode error
= Http::scNone
;
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::scNone
);
162 error
= Http::scNone
;
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::scNone
);
169 error
= Http::scNone
;
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::scNone
);
177 error
= Http::scNone
;
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::scNone
);
184 error
= Http::scNone
;
188 // TODO binary code in method
192 // TODO no status (okay)
194 // TODO non-HTTP protocol
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::scInvalidHeader
);
201 error
= Http::scNone
;