testHttpRequest.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 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 {
25 public:
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 
32 void
34 {
35  Mem::Init();
38 }
39 
40 /*
41  * Test creating an HttpRequest object from a Url and method
42  */
43 void
45 {
46  /* vanilla url, implict method */
47  unsigned short expected_port;
48  SBuf url("http://foo:90/bar");
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  */
104 void
106 {
107  unsigned short expected_port;
108  HttpRequest *aRequest = NULL;
109 
110  /* valid IPv6 address without port */
111  SBuf url("http://[2000:800::45]/foo");
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 
142 void
144 {
145  MemBuf input;
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();
158  error = Http::scNone;
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();
165  error = Http::scNone;
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();
173  error = Http::scNone;
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();
180  error = Http::scNone;
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();
197  error = Http::scNone;
198 }
199 
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:216
void path(const char *p)
Definition: Uri.h:97
Definition: SBuf.h:86
HttpRequestMethod method
Definition: HttpRequest.h:114
void error(char *format,...)
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:96
StatusCode
Definition: StatusCode.h:20
void port(unsigned short p)
Definition: Uri.h:92
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
void reset()
Definition: MemBuf.cc:132
void Init()
Definition: old_api.cc:437
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
void host(const char *src)
Definition: Uri.cc:48
static HttpRequest * FromUrl(const SBuf &url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:535
CPPUNIT_TEST_SUITE_REGISTRATION(testHttpRequest)
char * content()
start of the added data
Definition: MemBuf.h:41
void httpHeaderInitModule(void)
Definition: HttpHeader.cc:119
void testSanityCheckStartLine()
PrivateHttpRequest(const MasterXaction::Pointer &mx)
Definition: MemBuf.h:23
bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e)
AnyP::UriScheme const & getScheme() const
Definition: Uri.h:67
virtual bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error)
Definition: HttpRequest.cc:271
size_t headersEnd(const char *mime, size_t l, bool &containsObsFold)
Definition: mime_header.cc:16
static void Init()
initializes down-cased protocol scheme names array
Definition: UriScheme.cc:38
#define NULL
Definition: types.h:166

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors