OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #include <sstream> | 18 #include <sstream> |
19 #include "BaseJsTest.h" | 19 #include "BaseJsTest.h" |
20 #include "../src/Thread.h" | 20 #include "../src/Thread.h" |
| 21 #include <atomic> |
| 22 #include <mutex> |
| 23 |
| 24 using namespace AdblockPlus; |
21 | 25 |
22 namespace | 26 namespace |
23 { | 27 { |
24 class MockWebRequest : public AdblockPlus::WebRequest | 28 class MockWebRequest : public AdblockPlus::WebRequest |
25 { | 29 { |
26 public: | 30 public: |
27 AdblockPlus::ServerResponse GET(const std::string& url, const AdblockPlus::H
eaderList& requestHeaders) const | 31 AdblockPlus::ServerResponse GET(const std::string& url, const AdblockPlus::H
eaderList& requestHeaders) const |
28 { | 32 { |
29 lastRequestHeaders.clear(); | 33 lastRequestHeaders.clear(); |
30 for (auto header : requestHeaders) | 34 for (auto header : requestHeaders) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 { | 106 { |
103 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); | 107 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
104 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); | 108 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
105 AdblockPlus::Sleep(200); | 109 AdblockPlus::Sleep(200); |
106 ASSERT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); | 110 ASSERT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); |
107 ASSERT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); | 111 ASSERT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
108 ASSERT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")-
>AsString()); | 112 ASSERT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")-
>AsString()); |
109 ASSERT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.response
Headers)")->AsString()); | 113 ASSERT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.response
Headers)")->AsString()); |
110 } | 114 } |
111 | 115 |
| 116 TEST_F(MockWebRequestTest, ConnectionIsAllowedOnJsEngine) |
| 117 { |
| 118 std::atomic<int> isConnectionAllowedCalledTimes(0); |
| 119 jsEngine->SetIsConnectionAllowedCallback([&isConnectionAllowedCalledTimes]()->
bool |
| 120 { |
| 121 ++isConnectionAllowedCalledTimes; |
| 122 return true; |
| 123 }); |
| 124 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 125 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
| 126 AdblockPlus::Sleep(200); |
| 127 EXPECT_EQ(1u, isConnectionAllowedCalledTimes); |
| 128 EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); |
| 129 EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
| 130 EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")-
>AsString()); |
| 131 EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.response
Headers)")->AsString()); |
| 132 } |
| 133 |
| 134 TEST_F(MockWebRequestTest, ConnectionIsNotAllowedOnJsEngine) |
| 135 { |
| 136 std::atomic<int> isConnectionAllowedCalledTimes(0); |
| 137 jsEngine->SetIsConnectionAllowedCallback([&isConnectionAllowedCalledTimes]()->
bool |
| 138 { |
| 139 ++isConnectionAllowedCalledTimes; |
| 140 return false; |
| 141 }); |
| 142 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 143 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
| 144 AdblockPlus::Sleep(200); |
| 145 EXPECT_EQ(1u, isConnectionAllowedCalledTimes); |
| 146 EXPECT_EQ(AdblockPlus::WebRequest::NS_ERROR_CONNECTION_REFUSED, jsEngine->Eval
uate("foo.status")->AsInt()); |
| 147 EXPECT_EQ(0, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
| 148 EXPECT_EQ("", jsEngine->Evaluate("foo.responseText")->AsString()); |
| 149 EXPECT_EQ("{}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsS
tring()); |
| 150 } |
| 151 |
| 152 namespace |
| 153 { |
| 154 class SyncStrings |
| 155 { |
| 156 public: |
| 157 void Add(const std::string* value) |
| 158 { |
| 159 std::lock_guard<std::mutex> lock(mutex); |
| 160 strings.emplace_back(!!value, value ? *value : ""); |
| 161 } |
| 162 std::vector<std::pair<bool, std::string>> GetStrings() const |
| 163 { |
| 164 std::lock_guard<std::mutex> lock(mutex); |
| 165 return strings; |
| 166 } |
| 167 void Clear() |
| 168 { |
| 169 std::lock_guard<std::mutex> lock(mutex); |
| 170 strings.clear(); |
| 171 } |
| 172 private: |
| 173 mutable std::mutex mutex; |
| 174 std::vector<std::pair<bool, std::string>> strings; |
| 175 }; |
| 176 } |
| 177 |
| 178 TEST_F(MockWebRequestTest, ConnectionIsAllowedOnFilterEngine1) |
| 179 { |
| 180 FilterEngine::CreationParameters createParams; |
| 181 std::string predefinedAllowedConnectionType = "non-metered"; |
| 182 createParams.preconfiguredPrefs.emplace("allowed_connection_type", jsEngine->N
ewValue(predefinedAllowedConnectionType)); |
| 183 auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
| 184 createParams.isConnectionAllowedCallback = [receivedConnectionTypes](const std
::string* allowedConnectionType)->bool { |
| 185 receivedConnectionTypes->Add(allowedConnectionType); |
| 186 return true; |
| 187 }; |
| 188 auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
| 189 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 190 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
| 191 AdblockPlus::Sleep(200); |
| 192 auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
| 193 EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
| 194 for (const auto& connectionType : receivedConnectionTypesStrings) |
| 195 { |
| 196 EXPECT_TRUE(connectionType.first); |
| 197 EXPECT_EQ(predefinedAllowedConnectionType, connectionType.second); |
| 198 } |
| 199 EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); |
| 200 EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
| 201 EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")-
>AsString()); |
| 202 EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.response
Headers)")->AsString()); |
| 203 } |
| 204 |
| 205 TEST_F(MockWebRequestTest, ConnectionIsAllowedOnFilterEngine2) |
| 206 { |
| 207 FilterEngine::CreationParameters createParams; |
| 208 auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
| 209 createParams.isConnectionAllowedCallback = [receivedConnectionTypes](const std
::string* allowedConnectionType)->bool { |
| 210 receivedConnectionTypes->Add(allowedConnectionType); |
| 211 return true; |
| 212 }; |
| 213 auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
| 214 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 215 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
| 216 AdblockPlus::Sleep(200); |
| 217 auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
| 218 EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
| 219 for (const auto& connectionType : receivedConnectionTypesStrings) |
| 220 { |
| 221 EXPECT_FALSE(connectionType.first); |
| 222 } |
| 223 EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); |
| 224 EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
| 225 EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")-
>AsString()); |
| 226 EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.response
Headers)")->AsString()); |
| 227 } |
| 228 |
| 229 TEST_F(MockWebRequestTest, ConnectionIsAllowedOnFilterEngine3) |
| 230 { |
| 231 // initially allowed connection type is not defined |
| 232 FilterEngine::CreationParameters createParams; |
| 233 auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
| 234 createParams.isConnectionAllowedCallback = [receivedConnectionTypes](const std
::string* allowedConnectionType)->bool { |
| 235 receivedConnectionTypes->Add(allowedConnectionType); |
| 236 return true; |
| 237 }; |
| 238 auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
| 239 |
| 240 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 241 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
| 242 AdblockPlus::Sleep(200); |
| 243 auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
| 244 EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
| 245 for (const auto& connectionType : receivedConnectionTypesStrings) |
| 246 { |
| 247 EXPECT_FALSE(connectionType.first); |
| 248 } |
| 249 EXPECT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); |
| 250 EXPECT_EQ(123, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
| 251 EXPECT_EQ("http://example.com/\nX\nY", jsEngine->Evaluate("foo.responseText")-
>AsString()); |
| 252 EXPECT_EQ("{\"Foo\":\"Bar\"}", jsEngine->Evaluate("JSON.stringify(foo.response
Headers)")->AsString()); |
| 253 |
| 254 // set allowed connection type |
| 255 std::string allowedConnectionType = "test-connection"; |
| 256 filterEngine->SetAllowedConnectionType(&allowedConnectionType); |
| 257 receivedConnectionTypes->Clear(); |
| 258 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 259 AdblockPlus::Sleep(200); |
| 260 receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
| 261 EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
| 262 for (const auto& connectionType : receivedConnectionTypesStrings) |
| 263 { |
| 264 EXPECT_TRUE(connectionType.first); |
| 265 EXPECT_EQ(allowedConnectionType, connectionType.second); |
| 266 } |
| 267 |
| 268 // remove allowed connection type |
| 269 filterEngine->SetAllowedConnectionType(nullptr); |
| 270 receivedConnectionTypes->Clear(); |
| 271 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 272 AdblockPlus::Sleep(200); |
| 273 receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
| 274 EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
| 275 for (const auto& connectionType : receivedConnectionTypesStrings) |
| 276 { |
| 277 EXPECT_FALSE(connectionType.first); |
| 278 } |
| 279 } |
| 280 |
| 281 TEST_F(MockWebRequestTest, ConnectionIsNotAllowedOnFilterEngine) |
| 282 { |
| 283 FilterEngine::CreationParameters createParams; |
| 284 std::string predefinedAllowedConnectionType = "non-metered"; |
| 285 createParams.preconfiguredPrefs.emplace("allowed_connection_type", jsEngine->N
ewValue(predefinedAllowedConnectionType)); |
| 286 auto receivedConnectionTypes = std::make_shared<SyncStrings>(); |
| 287 createParams.isConnectionAllowedCallback = [receivedConnectionTypes](const std
::string* allowedConnectionType)->bool { |
| 288 receivedConnectionTypes->Add(allowedConnectionType); |
| 289 return false; |
| 290 }; |
| 291 auto filterEngine = FilterEngine::Create(jsEngine, createParams); |
| 292 jsEngine->Evaluate("_webRequest.GET('http://example.com/', {X: 'Y'}, function(
result) {foo = result;} )"); |
| 293 ASSERT_TRUE(jsEngine->Evaluate("this.foo")->IsUndefined()); |
| 294 AdblockPlus::Sleep(200); |
| 295 auto receivedConnectionTypesStrings = receivedConnectionTypes->GetStrings(); |
| 296 EXPECT_FALSE(receivedConnectionTypesStrings.empty()); |
| 297 for (const auto& connectionType : receivedConnectionTypesStrings) |
| 298 { |
| 299 EXPECT_TRUE(connectionType.first); |
| 300 EXPECT_EQ(predefinedAllowedConnectionType, connectionType.second); |
| 301 } |
| 302 EXPECT_EQ(AdblockPlus::WebRequest::NS_ERROR_CONNECTION_REFUSED, jsEngine->Eval
uate("foo.status")->AsInt()); |
| 303 EXPECT_EQ(0, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
| 304 EXPECT_EQ("", jsEngine->Evaluate("foo.responseText")->AsString()); |
| 305 EXPECT_EQ("{}", jsEngine->Evaluate("JSON.stringify(foo.responseHeaders)")->AsS
tring()); |
| 306 } |
| 307 |
112 #if defined(HAVE_CURL) || defined(_WIN32) | 308 #if defined(HAVE_CURL) || defined(_WIN32) |
113 TEST_F(DefaultWebRequestTest, RealWebRequest) | 309 TEST_F(DefaultWebRequestTest, RealWebRequest) |
114 { | 310 { |
115 // This URL should redirect to easylist-downloads.adblockplus.org and we | 311 // This URL should redirect to easylist-downloads.adblockplus.org and we |
116 // should get the actual filter list back. | 312 // should get the actual filter list back. |
117 jsEngine->Evaluate("_webRequest.GET('https://easylist-downloads.adblockplus.or
g/easylist.txt', {}, function(result) {foo = result;} )"); | 313 jsEngine->Evaluate("_webRequest.GET('https://easylist-downloads.adblockplus.or
g/easylist.txt', {}, function(result) {foo = result;} )"); |
118 WaitForVariable("this.foo", jsEngine); | 314 WaitForVariable("this.foo", jsEngine); |
119 ASSERT_EQ("text/plain", jsEngine->Evaluate("foo.responseHeaders['content-type'
].substr(0, 10)")->AsString()); | 315 ASSERT_EQ("text/plain", jsEngine->Evaluate("foo.responseHeaders['content-type'
].substr(0, 10)")->AsString()); |
120 ASSERT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); | 316 ASSERT_EQ(AdblockPlus::WebRequest::NS_OK, jsEngine->Evaluate("foo.status")->As
Int()); |
121 ASSERT_EQ(200, jsEngine->Evaluate("foo.responseStatus")->AsInt()); | 317 ASSERT_EQ(200, jsEngine->Evaluate("foo.responseStatus")->AsInt()); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 catchLogSystem->clear(); | 477 catchLogSystem->clear(); |
282 ResetTestXHR(jsEngine); | 478 ResetTestXHR(jsEngine); |
283 jsEngine->Evaluate("\ | 479 jsEngine->Evaluate("\ |
284 request.setRequestHeader('Security', 'theater');\nrequest.send();"); | 480 request.setRequestHeader('Security', 'theater');\nrequest.send();"); |
285 EXPECT_EQ(AdblockPlus::LogSystem::LOG_LEVEL_TRACE, catchLogSystem->lastLogLeve
l); | 481 EXPECT_EQ(AdblockPlus::LogSystem::LOG_LEVEL_TRACE, catchLogSystem->lastLogLeve
l); |
286 EXPECT_EQ("", catchLogSystem->lastMessage); | 482 EXPECT_EQ("", catchLogSystem->lastMessage); |
287 WaitForVariable("result", jsEngine); | 483 WaitForVariable("result", jsEngine); |
288 EXPECT_FALSE(webRequest->lastRequestHeaders.cend() == | 484 EXPECT_FALSE(webRequest->lastRequestHeaders.cend() == |
289 webRequest->lastRequestHeaders.find("Security")); | 485 webRequest->lastRequestHeaders.find("Security")); |
290 } | 486 } |
OLD | NEW |