1 /*
2  * Copyright (C) 1996-2021 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 #include <cppunit/TestAssert.h>
11 
12 #include "http/RequestMethod.h"
13 #include "SquidConfig.h"
14 #include "testHttpRequestMethod.h"
15 
16 #include <sstream>
17 
18 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequestMethod );
19 
20 /*
21  * We should be able to make an HttpRequestMethod straight from a string.
22  */
23 void
testConstructCharStart()24 testHttpRequestMethod::testConstructCharStart()
25 {
26     // string in SBuf
27 
28     /* parse an empty string -> Http::METHOD_NONE */
29     CPPUNIT_ASSERT(HttpRequestMethod(SBuf()) == Http::METHOD_NONE);
30 
31     /* parsing a literal should work */
32     CPPUNIT_ASSERT(HttpRequestMethod(SBuf("GET")) == Http::METHOD_GET);
33     CPPUNIT_ASSERT(HttpRequestMethod(SBuf("QWERTY")) == Http::METHOD_OTHER);
34 
35     // string in char*
36 
37     /* parse an empty string -> Http::METHOD_NONE */
38     HttpRequestMethod a;
39     a.HttpRequestMethodXXX(NULL);
40     CPPUNIT_ASSERT(a == Http::METHOD_NONE);
41 
42     /* parsing a literal should work */
43     HttpRequestMethod b;
44     b.HttpRequestMethodXXX("GET");
45     CPPUNIT_ASSERT(b == Http::METHOD_GET);
46     CPPUNIT_ASSERT_EQUAL(SBuf("GET"), b.image());
47     HttpRequestMethod c;
48     c.HttpRequestMethodXXX("QWERTY");
49     CPPUNIT_ASSERT(c == Http::METHOD_OTHER);
50     CPPUNIT_ASSERT_EQUAL(SBuf("QWERTY"), c.image());
51 
52     // parsing error should not leave stale results
53     b.HttpRequestMethodXXX(NULL);
54     CPPUNIT_ASSERT(b == Http::METHOD_NONE);
55     CPPUNIT_ASSERT_EQUAL(SBuf("NONE"), b.image());
56 }
57 
58 /*
59  * We can also parse precise ranges of characters with SBuf
60  */
61 void
testConstructCharStartEnd()62 testHttpRequestMethod::testConstructCharStartEnd()
63 {
64     char const * buffer;
65     /* parse an empty string -> Http::METHOD_NONE */
66     CPPUNIT_ASSERT(HttpRequestMethod(SBuf()) == Http::METHOD_NONE);
67     /* parsing a literal should work */
68     CPPUNIT_ASSERT(HttpRequestMethod(SBuf("GET")) == Http::METHOD_GET);
69     /* parsing with an explicit end should work */
70     buffer = "POSTPLUS";
71     CPPUNIT_ASSERT(HttpRequestMethod(SBuf(buffer, 4)) == Http::METHOD_POST);
72 }
73 
74 /*
75  * we should be able to assign a Http::MethodType to a HttpRequestMethod
76  */
77 void
testAssignFrommethod_t()78 testHttpRequestMethod::testAssignFrommethod_t()
79 {
80     HttpRequestMethod method;
81     method = Http::METHOD_NONE;
82     CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_NONE), method);
83     method = Http::METHOD_POST;
84     CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_POST), method);
85 }
86 
87 /*
88  * a default constructed HttpRequestMethod is == Http::METHOD_NONE
89  */
90 void
testDefaultConstructor()91 testHttpRequestMethod::testDefaultConstructor()
92 {
93     HttpRequestMethod lhs;
94     HttpRequestMethod rhs(Http::METHOD_NONE);
95     CPPUNIT_ASSERT_EQUAL(lhs, rhs);
96 }
97 
98 /*
99  * we should be able to construct a HttpRequestMethod from a Http::MethodType
100  */
101 void
testConstructmethod_t()102 testHttpRequestMethod::testConstructmethod_t()
103 {
104     CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_NONE), HttpRequestMethod(Http::METHOD_NONE));
105     CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_POST), HttpRequestMethod(Http::METHOD_POST));
106     CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_NONE) != HttpRequestMethod(Http::METHOD_POST));
107 }
108 
109 /*
110  * we should be able to get a char const * version of the method.
111  */
112 void
testImage()113 testHttpRequestMethod::testImage()
114 {
115     // relaxed RFC-compliance parse HTTP methods are upgraded to correct case
116     Config.onoff.relaxed_header_parser = 1;
117     CPPUNIT_ASSERT_EQUAL(SBuf("POST"), HttpRequestMethod(SBuf("POST")).image());
118     CPPUNIT_ASSERT_EQUAL(SBuf("POST"), HttpRequestMethod(SBuf("pOsT")).image());
119     CPPUNIT_ASSERT_EQUAL(SBuf("POST"), HttpRequestMethod(SBuf("post")).image());
120 
121     // strict RFC-compliance parse HTTP methods are case sensitive
122     Config.onoff.relaxed_header_parser = 0;
123     CPPUNIT_ASSERT_EQUAL(SBuf("POST"), HttpRequestMethod(SBuf("POST")).image());
124     CPPUNIT_ASSERT_EQUAL(SBuf("pOsT"), HttpRequestMethod(SBuf("pOsT")).image());
125     CPPUNIT_ASSERT_EQUAL(SBuf("post"), HttpRequestMethod(SBuf("post")).image());
126 }
127 
128 /*
129  * an HttpRequestMethod should be comparable to a Http::MethodType without false
130  * matches
131  */
132 void
testEqualmethod_t()133 testHttpRequestMethod::testEqualmethod_t()
134 {
135     CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_NONE) == Http::METHOD_NONE);
136     CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_POST) == Http::METHOD_GET));
137     CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_GET) == Http::METHOD_GET);
138     CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_TRACE) == Http::METHOD_SEARCH));
139 }
140 
141 /*
142  * an HttpRequestMethod should testable for inequality without fail maatches
143  */
144 void
testNotEqualmethod_t()145 testHttpRequestMethod::testNotEqualmethod_t()
146 {
147     CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_NONE) != Http::METHOD_GET);
148     CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_POST) != Http::METHOD_POST));
149     CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_GET) != Http::METHOD_NONE);
150     CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_SEARCH) != Http::METHOD_SEARCH));
151 }
152 
153 /*
154  * we should be able to send it to a stream and get the normalised version
155  */
156 void
testStream()157 testHttpRequestMethod::testStream()
158 {
159     // relaxed RFC-compliance parse HTTP methods are upgraded to correct case
160     Config.onoff.relaxed_header_parser = 1;
161     std::ostringstream buffer;
162     buffer << HttpRequestMethod(SBuf("get"));
163     CPPUNIT_ASSERT_EQUAL(String("GET"), String(buffer.str().c_str()));
164 
165     // strict RFC-compliance parse HTTP methods are case sensitive
166     Config.onoff.relaxed_header_parser = 0;
167     std::ostringstream buffer2;
168     buffer2 << HttpRequestMethod(SBuf("get"));
169     CPPUNIT_ASSERT_EQUAL(String("get"), String(buffer2.str().c_str()));
170 }
171 
172