]>
Commit | Line | Data |
---|---|---|
4e0938ef | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
4e0938ef AJ |
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 | ||
582c2af2 | 9 | #include "squid.h" |
26e65059 | 10 | #include "anyp/Uri.h" |
62ee09ca | 11 | #include "CacheManager.h" |
602d9612 | 12 | #include "mgr/Action.h" |
b707cdeb | 13 | #include "Store.h" |
602d9612 | 14 | #include "testCacheManager.h" |
7f861c77 | 15 | #include "unitTestMain.h" |
62ee09ca | 16 | |
3d41e53a | 17 | #include <cppunit/TestAssert.h> |
62ee09ca | 18 | |
19 | CPPUNIT_TEST_SUITE_REGISTRATION( testCacheManager ); | |
20 | ||
26e65059 AJ |
21 | /// Provides test code access to CacheManager internal symbols |
22 | class CacheManagerInternals : public CacheManager | |
23 | { | |
24 | public: | |
25 | void ParseUrl(const AnyP::Uri &u) { CacheManager::ParseUrl(u); } | |
26 | }; | |
27 | ||
62ee09ca | 28 | /* init memory pools */ |
29 | ||
16555581 | 30 | void testCacheManager::setUp() |
62ee09ca | 31 | { |
16555581 | 32 | Mem::Init(); |
26e65059 | 33 | AnyP::UriScheme::Init(); |
16555581 | 34 | } |
62ee09ca | 35 | |
36 | /* | |
37 | * Test creating a CacheManager | |
38 | */ | |
39 | void | |
40 | testCacheManager::testCreate() | |
41 | { | |
b707cdeb | 42 | CacheManager::GetInstance(); //it's a singleton.. |
62ee09ca | 43 | } |
44 | ||
45 | /* an action to register */ | |
46 | static void | |
47 | dummy_action(StoreEntry * sentry) | |
b707cdeb FC |
48 | { |
49 | sentry->flags=1; | |
50 | } | |
62ee09ca | 51 | |
52 | /* | |
53 | * registering an action makes it findable. | |
54 | */ | |
55 | void | |
56 | testCacheManager::testRegister() | |
57 | { | |
b707cdeb | 58 | CacheManager *manager=CacheManager::GetInstance(); |
aee3523a | 59 | CPPUNIT_ASSERT(manager != nullptr); |
b707cdeb | 60 | |
8822ebee AR |
61 | manager->registerProfile("sample", "my sample", &dummy_action, false, false); |
62 | Mgr::Action::Pointer action = manager->createNamedAction("sample"); | |
aee3523a | 63 | CPPUNIT_ASSERT(action != nullptr); |
b707cdeb | 64 | |
8822ebee | 65 | const Mgr::ActionProfile::Pointer profile = action->command().profile; |
aee3523a AR |
66 | CPPUNIT_ASSERT(profile != nullptr); |
67 | CPPUNIT_ASSERT(profile->creator != nullptr); | |
8822ebee AR |
68 | CPPUNIT_ASSERT_EQUAL(false, profile->isPwReq); |
69 | CPPUNIT_ASSERT_EQUAL(false, profile->isAtomic); | |
70 | CPPUNIT_ASSERT_EQUAL(String("sample"), String(action->name())); | |
b707cdeb FC |
71 | |
72 | StoreEntry *sentry=new StoreEntry(); | |
73 | sentry->flags=0x25; //arbitrary test value | |
8822ebee | 74 | action->run(sentry, false); |
b707cdeb | 75 | CPPUNIT_ASSERT_EQUAL(1,(int)sentry->flags); |
62ee09ca | 76 | } |
f53969cc | 77 | |
26e65059 AJ |
78 | void |
79 | testCacheManager::testParseUrl() | |
80 | { | |
81 | auto *mgr = static_cast<CacheManagerInternals *>(CacheManager::GetInstance()); | |
82 | CPPUNIT_ASSERT(mgr != nullptr); | |
83 | ||
84 | std::vector<AnyP::ProtocolType> validSchemes = { | |
85 | AnyP::PROTO_CACHE_OBJECT, | |
86 | AnyP::PROTO_HTTP, | |
87 | AnyP::PROTO_HTTPS, | |
88 | AnyP::PROTO_FTP | |
89 | }; | |
90 | ||
91 | AnyP::Uri mgrUrl; | |
92 | mgrUrl.host("localhost"); | |
93 | mgrUrl.port(3128); | |
94 | ||
95 | const std::vector<const char *> magicPrefixes = { | |
96 | "/", | |
97 | "/squid-internal-mgr/" | |
98 | }; | |
99 | ||
100 | const std::vector<const char *> validActions = { | |
101 | "", | |
102 | "menu" | |
103 | }; | |
104 | ||
105 | const std::vector<const char *> invalidActions = { | |
106 | "INVALID" // any unregistered name | |
107 | }; | |
108 | ||
109 | const std::vector<const char *> validParams = { | |
110 | "", | |
111 | "?", | |
112 | "?&", | |
113 | "?&&&&&&&&&&&&", | |
114 | "?foo=bar", | |
115 | "?0123456789=bar", | |
116 | "?foo=bar&", | |
117 | "?foo=bar&&&&", | |
118 | "?&foo=bar", | |
119 | "?&&&&foo=bar", | |
120 | "?&foo=bar&", | |
121 | "?&&&&foo=bar&&&&", | |
122 | "?foo=?_weird?~`:[]stuff&bar=okay&&&&&&", | |
123 | "?intlist=1", | |
124 | "?intlist=1,2,3,4,5", | |
125 | "?string=1a", | |
126 | "?string=1,2,3,4,z", | |
127 | "?string=1,2,3,4,[0]", | |
128 | "?intlist=1,2,3,4,5&string=1,2,3,4,y" | |
129 | }; | |
130 | ||
131 | const std::vector<const char *> invalidParams = { | |
132 | "?/", | |
133 | "?foo", | |
134 | "?/foo", | |
135 | "?foo/", | |
136 | "?foo=", | |
137 | "?foo=&", | |
138 | "?=foo", | |
139 | "? foo=bar", | |
140 | "? &", | |
141 | "?& ", | |
142 | "?=&", | |
143 | "?&=", | |
144 | "? &&&", | |
145 | "?& &&", | |
146 | "?&& &", | |
147 | "?=&&&", | |
148 | "?&=&&", | |
149 | "?&&=&" | |
150 | }; | |
151 | ||
152 | const std::vector<const char *> validFragments = { | |
153 | "", | |
154 | "#", | |
155 | "##", | |
156 | "#?a=b", | |
157 | "#fragment" | |
158 | }; | |
159 | ||
160 | for (const auto &scheme : validSchemes) { | |
161 | mgrUrl.setScheme(scheme); | |
162 | ||
163 | for (const auto *magic : magicPrefixes) { | |
164 | ||
165 | // all schemes except cache_object require magic path prefix bytes | |
166 | if (scheme != AnyP::PROTO_CACHE_OBJECT && strlen(magic) <= 2) | |
167 | continue; | |
168 | ||
169 | /* Check the parser accepts all the valid cases */ | |
170 | ||
171 | for (const auto *action : validActions) { | |
172 | for (const auto *param : validParams) { | |
173 | for (const auto *frag : validFragments) { | |
174 | try { | |
175 | SBuf bits; | |
176 | bits.append(magic); | |
177 | bits.append(action); | |
178 | bits.append(param); | |
179 | bits.append(frag); | |
180 | mgrUrl.path(bits); | |
181 | ||
182 | (void)mgr->ParseUrl(mgrUrl); | |
183 | } catch (...) { | |
184 | std::cerr << std::endl | |
185 | << "FAIL: " << mgrUrl | |
186 | << Debug::Extra << "error: " << CurrentException << std::endl; | |
187 | CPPUNIT_FAIL("rejected a valid URL"); | |
188 | } | |
189 | } | |
190 | } | |
191 | } | |
192 | ||
193 | /* Check that invalid parameters are rejected */ | |
194 | ||
195 | for (const auto *action : validActions) { | |
196 | for (const auto *param : invalidParams) { | |
197 | for (const auto *frag : validFragments) { | |
198 | try { | |
199 | SBuf bits; | |
200 | bits.append(magic); | |
201 | bits.append(action); | |
202 | bits.append(param); | |
203 | bits.append(frag); | |
204 | mgrUrl.path(bits); | |
205 | ||
206 | (void)mgr->ParseUrl(mgrUrl); | |
207 | ||
208 | std::cerr << std::endl | |
209 | << "FAIL: " << mgrUrl | |
210 | << Debug::Extra << "error: should be rejected due to '" << param << "'" << std::endl; | |
211 | } catch (const TextException &e) { | |
212 | continue; // success. caught bad input | |
213 | } | |
214 | CPPUNIT_FAIL("failed to reject an invalid URL"); | |
215 | } | |
216 | } | |
217 | } | |
218 | } | |
219 | } | |
220 | } | |
53521734 | 221 |