testHttpRequest.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
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
9#include "squid.h"
10
11#include <cppunit/TestAssert.h>
12
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"
19
21
24{
25public:
27 bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); };
28};
29
30/* init memory pools */
31
32void
34{
35 Mem::Init();
38}
39
40/*
41 * Test creating an HttpRequest object from a Url and method
42 */
43void
45{
46 /* vanilla url, implicit method */
47 unsigned short expected_port;
48 SBuf url("http://foo:90/bar");
49 const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
50 HttpRequest *aRequest = HttpRequest::FromUrl(url, mx);
51 expected_port = 90;
52 CPPUNIT_ASSERT(aRequest != nullptr);
53 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
54 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
55 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host()));
56 CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest->url.path());
57 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
58
59 /* vanilla url */
60 url = "http://foo:90/bar";
61 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
62 expected_port = 90;
63 CPPUNIT_ASSERT(aRequest != nullptr);
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
70 /* vanilla url, different method */
71 url = "http://foo/bar";
72 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_PUT);
73 expected_port = 80;
74 CPPUNIT_ASSERT(aRequest != nullptr);
75 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
76 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_PUT);
77 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host()));
78 CPPUNIT_ASSERT_EQUAL(SBuf("/bar"), aRequest->url.path());
79 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
80
81 /* a connect url with non-CONNECT data */
82 HttpRequest *nullRequest = nullptr;
83 url = ":foo/bar";
84 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT);
85 CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
86
87 /* a CONNECT url with CONNECT data */
88 url = "foo:45";
89 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT);
90 expected_port = 45;
91 CPPUNIT_ASSERT(aRequest != nullptr);
92 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
93 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_CONNECT);
94 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->url.host()));
95 CPPUNIT_ASSERT_EQUAL(SBuf(), aRequest->url.path());
96 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_NONE, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
97
98 // XXX: check METHOD_NONE input handling
99}
100
101/*
102 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
103 */
104void
106{
107 unsigned short expected_port;
108 HttpRequest *aRequest = nullptr;
109
110 /* valid IPv6 address without port */
111 SBuf url("http://[2000:800::45]/foo");
112 const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
113 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
114 expected_port = 80;
115 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
116 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
117 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->url.host()));
118 CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest->url.path());
119 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
120
121 /* valid IPv6 address with port */
122 url = "http://[2000:800::45]:90/foo";
123 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
124 expected_port = 90;
125 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
126 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
127 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->url.host()));
128 CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest->url.path());
129 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
130
131 /* IPv6 address as invalid (bug trigger) */
132 url = "http://2000:800::45/foo";
133 aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
134 expected_port = 80;
135 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port());
136 CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
137 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->url.host()));
138 CPPUNIT_ASSERT_EQUAL(SBuf("/foo"), aRequest->url.path());
139 CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, static_cast<AnyP::ProtocolType>(aRequest->url.getScheme()));
140}
141
142void
144{
145 MemBuf input;
146 const auto mx = MasterXaction::MakePortless<XactionInitiator::initHtcp>();
147 PrivateHttpRequest engine(mx);
149 size_t hdr_len;
150 input.init();
151
152 // a valid request line
153 input.append("GET / HTTP/1.1\n\n", 16);
154 hdr_len = headersEnd(input.content(), input.contentSize());
155 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
156 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
157 input.reset();
159
160 input.append("GET / HTTP/1.1\n\n", 18);
161 hdr_len = headersEnd(input.content(), input.contentSize());
162 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
163 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
164 input.reset();
166
167 // strange but valid methods
168 input.append(". / HTTP/1.1\n\n", 14);
169 hdr_len = headersEnd(input.content(), input.contentSize());
170 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
171 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
172 input.reset();
174
175 input.append("OPTIONS * HTTP/1.1\n\n", 20);
176 hdr_len = headersEnd(input.content(), input.contentSize());
177 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
178 CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
179 input.reset();
181
182// TODO no method
183
184// TODO binary code in method
185
186// TODO no URL
187
188// TODO no status (okay)
189
190// TODO non-HTTP protocol
191
192 input.append(" \n\n", 8);
193 hdr_len = headersEnd(input.content(), input.contentSize());
194 CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
195 CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
196 input.reset();
198}
199
void httpHeaderInitModule(void)
Definition: HttpHeader.cc:119
void error(char *format,...)
static void Init()
initializes down-cased protocol scheme names array
Definition: UriScheme.cc:38
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:67
void path(const char *p)
Definition: Uri.h:99
void port(unsigned short p)
Definition: Uri.h:94
void host(const char *src)
Definition: Uri.cc:99
HttpRequestMethod method
Definition: HttpRequest.h:114
static HttpRequest * FromUrl(const SBuf &url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:517
virtual bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error)
Definition: HttpRequest.cc:268
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
Definition: MemBuf.h:24
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:209
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:93
char * content()
start of the added data
Definition: MemBuf.h:41
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
void reset()
Definition: MemBuf.cc:129
bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e)
PrivateHttpRequest(const MasterXaction::Pointer &mx)
Definition: SBuf.h:94
void testSanityCheckStartLine()
size_t headersEnd(const char *mime, size_t l, bool &containsObsFold)
Definition: mime_header.cc:17
ProtocolType
Definition: ProtocolType.h:23
@ PROTO_NONE
Definition: ProtocolType.h:24
@ PROTO_HTTP
Definition: ProtocolType.h:25
StatusCode
Definition: StatusCode.h:20
@ scInvalidHeader
Definition: StatusCode.h:86
@ scNone
Definition: StatusCode.h:21
@ METHOD_PUT
Definition: MethodType.h:27
@ METHOD_CONNECT
Definition: MethodType.h:29
@ METHOD_GET
Definition: MethodType.h:25
void Init()
Definition: old_api.cc:425
CPPUNIT_TEST_SUITE_REGISTRATION(testHttpRequest)

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors