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  char * url = xstrdup("http://foo:90/bar");
50  HttpRequest *aRequest = HttpRequest::FromUrl(url, mx);
51  expected_port = 90;
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));
58  xfree(url);
59 
60  /* vanilla url */
61  url = xstrdup("http://foo:90/bar");
62  aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
63  expected_port = 90;
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));
70  xfree(url);
71 
72  /* vanilla url, different method */
73  url = xstrdup("http://foo/bar");
74  aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_PUT);
75  expected_port = 80;
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));
82  xfree(url);
83 
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);
88  xfree(url);
89  CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
90 
91  /* a CONNECT url with CONNECT data */
92  url = xstrdup("foo:45");
93  aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT);
94  expected_port = 45;
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));
101  xfree(url);
102 
103  // XXX: check METHOD_NONE input handling
104 }
105 
106 /*
107  * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
108  */
109 void
111 {
112  unsigned short expected_port;
113  char * url = NULL;
114  HttpRequest *aRequest = NULL;
115 
116  /* valid IPv6 address without port */
117  url = xstrdup("http://[2000:800::45]/foo");
119  aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
120  expected_port = 80;
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));
127  xfree(url);
128 
129  /* valid IPv6 address with port */
130  url = xstrdup("http://[2000:800::45]:90/foo");
131  aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
132  expected_port = 90;
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));
139  xfree(url);
140 
141  /* IPv6 address as invalid (bug trigger) */
142  url = xstrdup("http://2000:800::45/foo");
143  aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET);
144  expected_port = 80;
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));
151  xfree(url);
152 }
153 
154 void
156 {
157  MemBuf input;
159  PrivateHttpRequest engine(mx);
161  size_t hdr_len;
162  input.init();
163 
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);
169  input.reset();
170  error = Http::scNone;
171 
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);
176  input.reset();
177  error = Http::scNone;
178 
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);
184  input.reset();
185  error = Http::scNone;
186 
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);
191  input.reset();
192  error = Http::scNone;
193 
194 // TODO no method
195 
196 // TODO binary code in method
197 
198 // TODO no URL
199 
200 // TODO no status (okay)
201 
202 // TODO non-HTTP protocol
203 
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);
208  input.reset();
209  error = Http::scNone;
210 }
211 
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:216
void path(const char *p)
Definition: Uri.h:88
Definition: SBuf.h:86
HttpRequestMethod method
Definition: HttpRequest.h:114
void error(char *format,...)
#define xstrdup
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:83
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:47
CPPUNIT_TEST_SUITE_REGISTRATION(testHttpRequest)
char * content()
start of the added data
Definition: MemBuf.h:41
static HttpRequest * FromUrl(const char *url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:543
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
#define xfree
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