1 // Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include <algorithm>
6 #include <vector>
7
8 #include "include/base/cef_callback.h"
9 #include "include/cef_callback.h"
10 #include "include/cef_origin_whitelist.h"
11 #include "include/cef_scheme.h"
12 #include "include/wrapper/cef_closure_task.h"
13 #include "tests/ceftests/test_handler.h"
14 #include "tests/ceftests/test_suite.h"
15 #include "tests/ceftests/test_util.h"
16
17 namespace {
18
19 class TestResults {
20 public:
TestResults()21 TestResults() : status_code(200), sub_status_code(200), delay(0) {}
22
reset()23 void reset() {
24 url.clear();
25 html.clear();
26 status_code = 200;
27 response_error_code = ERR_NONE;
28 expected_error_code = ERR_NONE;
29 redirect_url.clear();
30 sub_url.clear();
31 sub_html.clear();
32 sub_status_code = 200;
33 sub_allow_origin.clear();
34 exit_url.clear();
35 accept_language.clear();
36 console_messages.clear();
37 delay = 0;
38 got_request.reset();
39 got_read.reset();
40 got_output.reset();
41 got_sub_output.reset();
42 got_redirect.reset();
43 got_error.reset();
44 got_sub_error.reset();
45 got_sub_request.reset();
46 got_sub_read.reset();
47 got_sub_success.reset();
48 got_exit_request.reset();
49 }
50
51 std::string url;
52 std::string html;
53 int status_code;
54
55 // Error code set on the response.
56 cef_errorcode_t response_error_code;
57 // Error code expected in OnLoadError.
58 cef_errorcode_t expected_error_code;
59
60 // Used for testing redirects
61 std::string redirect_url;
62
63 // Used for testing XHR requests
64 std::string sub_url;
65 std::string sub_html;
66 int sub_status_code;
67 std::string sub_allow_origin;
68 std::string sub_redirect_url;
69 std::string exit_url;
70
71 // Used for testing per-browser Accept-Language.
72 std::string accept_language;
73
74 // Used for testing received console messages.
75 std::vector<std::string> console_messages;
76
77 // Delay for returning scheme handler results.
78 int delay;
79
80 TrackCallback got_request, got_read, got_output, got_sub_output, got_redirect,
81 got_error, got_sub_error, got_sub_redirect, got_sub_request, got_sub_read,
82 got_sub_success, got_exit_request;
83 };
84
85 // Current scheme handler object. Used when destroying the test from
86 // ClientSchemeHandler::ProcessRequest().
87 class TestSchemeHandler;
88 TestSchemeHandler* g_current_handler = nullptr;
89
90 class TestSchemeHandler : public TestHandler {
91 public:
TestSchemeHandler(TestResults * tr)92 explicit TestSchemeHandler(TestResults* tr) : test_results_(tr) {
93 g_current_handler = this;
94 }
95
PopulateBrowserSettings(CefBrowserSettings * settings)96 void PopulateBrowserSettings(CefBrowserSettings* settings) override {
97 if (!test_results_->accept_language.empty()) {
98 CefString(&settings->accept_language_list) =
99 test_results_->accept_language;
100 }
101 }
102
RunTest()103 void RunTest() override {
104 CreateBrowser(test_results_->url);
105
106 // Time out the test after a reasonable period of time.
107 SetTestTimeout();
108 }
109
110 // Necessary to make the method public in order to destroy the test from
111 // ClientSchemeHandler::ProcessRequest().
DestroyTest()112 void DestroyTest() override {
113 EXPECT_TRUE(test_results_->console_messages.empty())
114 << "Did not receive expected console message: "
115 << test_results_->console_messages.front();
116
117 TestHandler::DestroyTest();
118 }
119
DestroyTestIfDone()120 void DestroyTestIfDone() {
121 if (!test_results_->exit_url.empty() && !test_results_->got_exit_request) {
122 return;
123 }
124
125 if (!test_results_->sub_url.empty() &&
126 !(test_results_->got_sub_output || test_results_->got_sub_error ||
127 test_results_->got_exit_request)) {
128 return;
129 }
130
131 if (!(test_results_->got_output || test_results_->got_error)) {
132 return;
133 }
134
135 DestroyTest();
136 }
137
IsExitURL(const std::string & url) const138 bool IsExitURL(const std::string& url) const {
139 return !test_results_->exit_url.empty() &&
140 url.find(test_results_->exit_url) != std::string::npos;
141 }
142
OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefCallback> callback)143 cef_return_value_t OnBeforeResourceLoad(
144 CefRefPtr<CefBrowser> browser,
145 CefRefPtr<CefFrame> frame,
146 CefRefPtr<CefRequest> request,
147 CefRefPtr<CefCallback> callback) override {
148 if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
149 // Ignore favicon requests.
150 return RV_CANCEL;
151 }
152
153 const std::string& newUrl = request->GetURL();
154 if (IsExitURL(newUrl)) {
155 test_results_->got_exit_request.yes();
156 // XHR tests use an exit URL to destroy the test.
157 if (newUrl.find("SUCCESS") != std::string::npos)
158 test_results_->got_sub_success.yes();
159 DestroyTestIfDone();
160 return RV_CANCEL;
161 }
162
163 if (!test_results_->sub_redirect_url.empty() &&
164 newUrl == test_results_->sub_redirect_url) {
165 test_results_->got_sub_redirect.yes();
166 // Redirect to the sub URL.
167 request->SetURL(test_results_->sub_url);
168 } else if (newUrl == test_results_->redirect_url) {
169 test_results_->got_redirect.yes();
170
171 // No read should have occurred for the redirect.
172 EXPECT_TRUE(test_results_->got_request);
173 EXPECT_FALSE(test_results_->got_read);
174
175 // Now loading the redirect URL.
176 test_results_->url = test_results_->redirect_url;
177 test_results_->redirect_url.clear();
178 }
179
180 return RV_CONTINUE;
181 }
182
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)183 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
184 CefRefPtr<CefFrame> frame,
185 int httpStatusCode) override {
186 const std::string& url = frame->GetURL();
187 if (url == test_results_->url)
188 test_results_->got_output.yes();
189 else if (url == test_results_->sub_url)
190 test_results_->got_sub_output.yes();
191 else if (IsExitURL(url))
192 return;
193
194 if (url == test_results_->url || test_results_->status_code != 200) {
195 // Test that the status code is correct.
196 EXPECT_EQ(httpStatusCode, test_results_->status_code);
197 }
198
199 DestroyTestIfDone();
200 }
201
OnLoadError(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,ErrorCode errorCode,const CefString & errorText,const CefString & failedUrl)202 void OnLoadError(CefRefPtr<CefBrowser> browser,
203 CefRefPtr<CefFrame> frame,
204 ErrorCode errorCode,
205 const CefString& errorText,
206 const CefString& failedUrl) override {
207 const std::string& url = failedUrl;
208 if (url == test_results_->url)
209 test_results_->got_error.yes();
210 else if (url == test_results_->sub_url)
211 test_results_->got_sub_error.yes();
212 else if (IsExitURL(url))
213 return;
214
215 // Tests sometimes also fail with ERR_ABORTED or ERR_UNKNOWN_URL_SCHEME.
216 if (!(test_results_->expected_error_code == 0 &&
217 (errorCode == ERR_ABORTED || errorCode == ERR_UNKNOWN_URL_SCHEME))) {
218 EXPECT_EQ(test_results_->expected_error_code, errorCode)
219 << failedUrl.ToString();
220 }
221
222 DestroyTestIfDone();
223 }
224
OnConsoleMessage(CefRefPtr<CefBrowser> browser,cef_log_severity_t level,const CefString & message,const CefString & source,int line)225 bool OnConsoleMessage(CefRefPtr<CefBrowser> browser,
226 cef_log_severity_t level,
227 const CefString& message,
228 const CefString& source,
229 int line) override {
230 bool expected = false;
231 if (!test_results_->console_messages.empty()) {
232 std::vector<std::string>::iterator it =
233 test_results_->console_messages.begin();
234 for (; it != test_results_->console_messages.end(); ++it) {
235 const std::string& possible = *it;
236 const std::string& actual = message.ToString();
237 if (actual.find(possible) == 0U) {
238 expected = true;
239 test_results_->console_messages.erase(it);
240 break;
241 }
242 }
243 }
244
245 EXPECT_TRUE(expected) << "Unexpected console message: "
246 << message.ToString();
247 return false;
248 }
249
250 protected:
251 TestResults* test_results_;
252
253 IMPLEMENT_REFCOUNTING(TestSchemeHandler);
254 };
255
256 class ClientSchemeHandlerOld : public CefResourceHandler {
257 public:
ClientSchemeHandlerOld(TestResults * tr)258 explicit ClientSchemeHandlerOld(TestResults* tr)
259 : test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
260
ProcessRequest(CefRefPtr<CefRequest> request,CefRefPtr<CefCallback> callback)261 bool ProcessRequest(CefRefPtr<CefRequest> request,
262 CefRefPtr<CefCallback> callback) override {
263 EXPECT_TRUE(CefCurrentlyOn(TID_IO));
264
265 bool handled = false;
266
267 std::string url = request->GetURL();
268 is_sub_ =
269 (!test_results_->sub_url.empty() && test_results_->sub_url == url);
270
271 if (is_sub_) {
272 test_results_->got_sub_request.yes();
273
274 if (!test_results_->sub_html.empty())
275 handled = true;
276 } else {
277 EXPECT_EQ(url, test_results_->url);
278
279 test_results_->got_request.yes();
280
281 if (!test_results_->html.empty())
282 handled = true;
283 }
284
285 std::string accept_language;
286 CefRequest::HeaderMap headerMap;
287 CefRequest::HeaderMap::iterator headerIter;
288 request->GetHeaderMap(headerMap);
289 headerIter = headerMap.find("Accept-Language");
290 if (headerIter != headerMap.end())
291 accept_language = headerIter->second;
292 EXPECT_TRUE(!accept_language.empty());
293
294 if (!test_results_->accept_language.empty()) {
295 // Value from CefBrowserSettings.accept_language set in
296 // PopulateBrowserSettings().
297 EXPECT_STREQ(test_results_->accept_language.data(),
298 accept_language.data());
299 } else {
300 // CEF_SETTINGS_ACCEPT_LANGUAGE value from
301 // CefSettings.accept_language_list set in CefTestSuite::GetSettings()
302 // and expanded internally by ComputeAcceptLanguageFromPref.
303 EXPECT_STREQ("en-GB,en;q=0.9", accept_language.data());
304 }
305
306 if (handled) {
307 if (test_results_->delay > 0) {
308 // Continue after the delay.
309 CefPostDelayedTask(
310 TID_IO, base::BindOnce(&CefCallback::Continue, callback.get()),
311 test_results_->delay);
312 } else {
313 // Continue immediately.
314 callback->Continue();
315 }
316 return true;
317 } else if (test_results_->response_error_code != ERR_NONE) {
318 // Propagate the error code.
319 callback->Continue();
320 return true;
321 }
322
323 // Response was canceled.
324 if (g_current_handler)
325 g_current_handler->DestroyTest();
326 return false;
327 }
328
GetResponseHeaders(CefRefPtr<CefResponse> response,int64 & response_length,CefString & redirectUrl)329 void GetResponseHeaders(CefRefPtr<CefResponse> response,
330 int64& response_length,
331 CefString& redirectUrl) override {
332 if (is_sub_) {
333 response->SetStatus(test_results_->sub_status_code);
334
335 if (!test_results_->sub_allow_origin.empty()) {
336 // Set the Access-Control-Allow-Origin header to allow cross-domain
337 // scripting.
338 CefResponse::HeaderMap headers;
339 headers.insert(std::make_pair("Access-Control-Allow-Origin",
340 test_results_->sub_allow_origin));
341 response->SetHeaderMap(headers);
342 }
343
344 if (!test_results_->sub_html.empty()) {
345 response->SetMimeType("text/html");
346 response_length = test_results_->sub_html.size();
347 }
348 } else if (!test_results_->redirect_url.empty()) {
349 redirectUrl = test_results_->redirect_url;
350 } else if (test_results_->response_error_code != ERR_NONE) {
351 response->SetError(test_results_->response_error_code);
352 } else {
353 response->SetStatus(test_results_->status_code);
354
355 if (!test_results_->html.empty()) {
356 response->SetMimeType("text/html");
357 response_length = test_results_->html.size();
358 }
359 }
360 }
361
Cancel()362 void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }
363
ReadResponse(void * data_out,int bytes_to_read,int & bytes_read,CefRefPtr<CefCallback> callback)364 bool ReadResponse(void* data_out,
365 int bytes_to_read,
366 int& bytes_read,
367 CefRefPtr<CefCallback> callback) override {
368 EXPECT_TRUE(CefCurrentlyOn(TID_IO));
369
370 if (test_results_->delay > 0) {
371 if (!has_delayed_) {
372 // Continue after a delay.
373 CefPostDelayedTask(
374 TID_IO,
375 base::BindOnce(&ClientSchemeHandlerOld::ContinueAfterDelay, this,
376 callback),
377 test_results_->delay);
378 bytes_read = 0;
379 return true;
380 }
381
382 has_delayed_ = false;
383 }
384
385 std::string* data;
386
387 if (is_sub_) {
388 test_results_->got_sub_read.yes();
389 data = &test_results_->sub_html;
390 } else {
391 test_results_->got_read.yes();
392 data = &test_results_->html;
393 }
394
395 bool has_data = false;
396 bytes_read = 0;
397
398 size_t size = data->size();
399 if (offset_ < size) {
400 int transfer_size =
401 std::min(bytes_to_read, static_cast<int>(size - offset_));
402 memcpy(data_out, data->c_str() + offset_, transfer_size);
403 offset_ += transfer_size;
404
405 bytes_read = transfer_size;
406 has_data = true;
407 }
408
409 return has_data;
410 }
411
412 private:
ContinueAfterDelay(CefRefPtr<CefCallback> callback)413 void ContinueAfterDelay(CefRefPtr<CefCallback> callback) {
414 has_delayed_ = true;
415 callback->Continue();
416 }
417
418 TestResults* test_results_;
419 size_t offset_;
420 bool is_sub_;
421 bool has_delayed_;
422
423 IMPLEMENT_REFCOUNTING(ClientSchemeHandlerOld);
424 DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerOld);
425 };
426
427 class ClientSchemeHandler : public CefResourceHandler {
428 public:
ClientSchemeHandler(TestResults * tr)429 explicit ClientSchemeHandler(TestResults* tr)
430 : test_results_(tr), offset_(0), is_sub_(false), has_delayed_(false) {}
431
Open(CefRefPtr<CefRequest> request,bool & handle_request,CefRefPtr<CefCallback> callback)432 bool Open(CefRefPtr<CefRequest> request,
433 bool& handle_request,
434 CefRefPtr<CefCallback> callback) override {
435 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
436
437 if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
438 // Ignore favicon requests.
439 return false;
440 }
441
442 bool handled = false;
443
444 std::string url = request->GetURL();
445 is_sub_ =
446 (!test_results_->sub_url.empty() && test_results_->sub_url == url);
447
448 if (is_sub_) {
449 test_results_->got_sub_request.yes();
450
451 if (!test_results_->sub_html.empty())
452 handled = true;
453 } else {
454 EXPECT_EQ(url, test_results_->url);
455
456 test_results_->got_request.yes();
457
458 if (!test_results_->html.empty())
459 handled = true;
460 }
461
462 std::string accept_language;
463 CefRequest::HeaderMap headerMap;
464 CefRequest::HeaderMap::iterator headerIter;
465 request->GetHeaderMap(headerMap);
466 headerIter = headerMap.find("Accept-Language");
467 if (headerIter != headerMap.end())
468 accept_language = headerIter->second;
469 EXPECT_TRUE(!accept_language.empty());
470
471 if (!test_results_->accept_language.empty()) {
472 // Value from CefBrowserSettings.accept_language set in
473 // PopulateBrowserSettings().
474 EXPECT_STREQ(test_results_->accept_language.data(),
475 accept_language.data());
476 } else {
477 // CEF_SETTINGS_ACCEPT_LANGUAGE value from
478 // CefSettings.accept_language_list set in CefTestSuite::GetSettings()
479 // and expanded internally by ComputeAcceptLanguageFromPref.
480 EXPECT_STREQ("en-GB,en;q=0.9", accept_language.data());
481 }
482
483 // Continue or cancel the request immediately based on the return value.
484 handle_request = true;
485
486 if (handled) {
487 if (test_results_->delay > 0) {
488 // Continue after the delay.
489 handle_request = false;
490 CefPostDelayedTask(
491 TID_FILE_USER_BLOCKING,
492 base::BindOnce(&CefCallback::Continue, callback.get()),
493 test_results_->delay);
494 }
495 return true;
496 } else if (test_results_->response_error_code != ERR_NONE) {
497 // Propagate the error code.
498 return true;
499 }
500
501 // Response was canceled.
502 if (g_current_handler)
503 g_current_handler->DestroyTest();
504 return false;
505 }
506
ProcessRequest(CefRefPtr<CefRequest> request,CefRefPtr<CefCallback> callback)507 bool ProcessRequest(CefRefPtr<CefRequest> request,
508 CefRefPtr<CefCallback> callback) override {
509 if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
510 // Ignore favicon requests.
511 return false;
512 }
513
514 EXPECT_TRUE(false); // Not reached.
515 return false;
516 }
517
GetResponseHeaders(CefRefPtr<CefResponse> response,int64 & response_length,CefString & redirectUrl)518 void GetResponseHeaders(CefRefPtr<CefResponse> response,
519 int64& response_length,
520 CefString& redirectUrl) override {
521 if (is_sub_) {
522 response->SetStatus(test_results_->sub_status_code);
523
524 if (!test_results_->sub_allow_origin.empty()) {
525 // Set the Access-Control-Allow-Origin header to allow cross-domain
526 // scripting.
527 CefResponse::HeaderMap headers;
528 headers.insert(std::make_pair("Access-Control-Allow-Origin",
529 test_results_->sub_allow_origin));
530 response->SetHeaderMap(headers);
531 }
532
533 if (!test_results_->sub_html.empty()) {
534 response->SetMimeType("text/html");
535 response_length = test_results_->sub_html.size();
536 }
537 } else if (!test_results_->redirect_url.empty()) {
538 redirectUrl = test_results_->redirect_url;
539 } else if (test_results_->response_error_code != ERR_NONE) {
540 response->SetError(test_results_->response_error_code);
541 } else {
542 response->SetStatus(test_results_->status_code);
543
544 if (!test_results_->html.empty()) {
545 response->SetMimeType("text/html");
546 response_length = test_results_->html.size();
547 }
548 }
549 }
550
Cancel()551 void Cancel() override { EXPECT_TRUE(CefCurrentlyOn(TID_IO)); }
552
Read(void * data_out,int bytes_to_read,int & bytes_read,CefRefPtr<CefResourceReadCallback> callback)553 bool Read(void* data_out,
554 int bytes_to_read,
555 int& bytes_read,
556 CefRefPtr<CefResourceReadCallback> callback) override {
557 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
558
559 if (test_results_->delay > 0) {
560 if (!has_delayed_) {
561 // Continue after a delay.
562 CefPostDelayedTask(
563 TID_FILE_USER_BLOCKING,
564 base::BindOnce(&ClientSchemeHandler::ContinueAfterDelay, this,
565 data_out, bytes_to_read, callback),
566 test_results_->delay);
567 bytes_read = 0;
568 return true;
569 }
570
571 has_delayed_ = false;
572 }
573
574 return GetData(data_out, bytes_to_read, bytes_read);
575 }
576
ReadResponse(void * data_out,int bytes_to_read,int & bytes_read,CefRefPtr<CefCallback> callback)577 bool ReadResponse(void* data_out,
578 int bytes_to_read,
579 int& bytes_read,
580 CefRefPtr<CefCallback> callback) override {
581 EXPECT_TRUE(false); // Not reached.
582 bytes_read = -2;
583 return false;
584 }
585
586 private:
ContinueAfterDelay(void * data_out,int bytes_to_read,CefRefPtr<CefResourceReadCallback> callback)587 void ContinueAfterDelay(void* data_out,
588 int bytes_to_read,
589 CefRefPtr<CefResourceReadCallback> callback) {
590 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
591
592 has_delayed_ = true;
593
594 int bytes_read = 0;
595 GetData(data_out, bytes_to_read, bytes_read);
596 callback->Continue(bytes_read);
597 }
598
GetData(void * data_out,int bytes_to_read,int & bytes_read)599 bool GetData(void* data_out, int bytes_to_read, int& bytes_read) {
600 std::string* data;
601
602 if (is_sub_) {
603 test_results_->got_sub_read.yes();
604 data = &test_results_->sub_html;
605 } else {
606 test_results_->got_read.yes();
607 data = &test_results_->html;
608 }
609
610 // Default to response complete.
611 bool has_data = false;
612 bytes_read = 0;
613
614 size_t size = data->size();
615 if (offset_ < size) {
616 int transfer_size =
617 std::min(bytes_to_read, static_cast<int>(size - offset_));
618 memcpy(data_out, data->c_str() + offset_, transfer_size);
619 offset_ += transfer_size;
620
621 bytes_read = transfer_size;
622 has_data = true;
623 }
624
625 return has_data;
626 }
627
628 TestResults* test_results_;
629 size_t offset_;
630 bool is_sub_;
631 bool has_delayed_;
632
633 IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
634 DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandler);
635 };
636
637 class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory {
638 public:
ClientSchemeHandlerFactory(TestResults * tr)639 explicit ClientSchemeHandlerFactory(TestResults* tr) : test_results_(tr) {}
640
Create(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const CefString & scheme_name,CefRefPtr<CefRequest> request)641 CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
642 CefRefPtr<CefFrame> frame,
643 const CefString& scheme_name,
644 CefRefPtr<CefRequest> request) override {
645 EXPECT_TRUE(CefCurrentlyOn(TID_IO));
646 if (TestOldResourceAPI()) {
647 return new ClientSchemeHandlerOld(test_results_);
648 }
649 return new ClientSchemeHandler(test_results_);
650 }
651
652 TestResults* test_results_;
653
654 IMPLEMENT_REFCOUNTING(ClientSchemeHandlerFactory);
655 DISALLOW_COPY_AND_ASSIGN(ClientSchemeHandlerFactory);
656 };
657
658 // Global test results object.
659 TestResults g_TestResults;
660
661 // If |domain| is empty the scheme will be registered as non-standard.
RegisterTestScheme(const std::string & scheme,const std::string & domain)662 void RegisterTestScheme(const std::string& scheme, const std::string& domain) {
663 g_TestResults.reset();
664
665 EXPECT_TRUE(CefRegisterSchemeHandlerFactory(
666 scheme, domain, new ClientSchemeHandlerFactory(&g_TestResults)));
667 WaitForIOThread();
668 }
669
ClearTestSchemes()670 void ClearTestSchemes() {
671 EXPECT_TRUE(CefClearSchemeHandlerFactories());
672 WaitForIOThread();
673 }
674
675 struct XHRTestSettings {
XHRTestSettings__anona20967f80111::XHRTestSettings676 XHRTestSettings() : synchronous(true) {}
677
678 std::string url;
679 std::string sub_url;
680 std::string sub_allow_origin;
681 std::string sub_redirect_url;
682 bool synchronous;
683 };
684
SetUpXHR(const XHRTestSettings & settings)685 void SetUpXHR(const XHRTestSettings& settings) {
686 g_TestResults.sub_url = settings.sub_url;
687 g_TestResults.sub_html = "SUCCESS";
688 g_TestResults.sub_allow_origin = settings.sub_allow_origin;
689 g_TestResults.sub_redirect_url = settings.sub_redirect_url;
690
691 std::string request_url;
692 if (!settings.sub_redirect_url.empty())
693 request_url = settings.sub_redirect_url;
694 else
695 request_url = settings.sub_url;
696
697 g_TestResults.url = settings.url;
698 std::stringstream ss;
699 ss << "<html><head>"
700 "<script language=\"JavaScript\">"
701 "function onResult(val) {"
702 " document.location = \"http://tests/exit?result=\"+val;"
703 "}"
704 "function execXMLHttpRequest() {";
705 if (settings.synchronous) {
706 ss << "var result = 'FAILURE';"
707 "try {"
708 " xhr = new XMLHttpRequest();"
709 " xhr.open(\"GET\", \""
710 << request_url.c_str()
711 << "\", false);"
712 " xhr.send();"
713 " result = xhr.responseText;"
714 "} catch(e) {}"
715 "onResult(result)";
716 } else {
717 ss << "xhr = new XMLHttpRequest();"
718 "xhr.open(\"GET\", \""
719 << request_url.c_str()
720 << "\", true);"
721 "xhr.onload = function(e) {"
722 " if (xhr.readyState === 4) {"
723 " if (xhr.status === 200) {"
724 " onResult(xhr.responseText);"
725 " } else {"
726 " console.log('XMLHttpRequest failed with status ' + "
727 "xhr.status);"
728 " onResult('FAILURE');"
729 " }"
730 " }"
731 "};"
732 "xhr.onerror = function(e) {"
733 " onResult('FAILURE');"
734 "};"
735 "xhr.send()";
736 }
737 ss << "}"
738 "</script>"
739 "</head><body onload=\"execXMLHttpRequest();\">"
740 "Running execXMLHttpRequest..."
741 "</body></html>";
742 g_TestResults.html = ss.str();
743
744 g_TestResults.exit_url = "http://tests/exit";
745 }
746
747 struct FetchTestSettings {
FetchTestSettings__anona20967f80111::FetchTestSettings748 FetchTestSettings() {}
749
750 std::string url;
751 std::string sub_url;
752 std::string sub_allow_origin;
753 std::string sub_redirect_url;
754 };
755
SetUpFetch(const FetchTestSettings & settings)756 void SetUpFetch(const FetchTestSettings& settings) {
757 g_TestResults.sub_url = settings.sub_url;
758 g_TestResults.sub_html = "SUCCESS";
759 g_TestResults.sub_allow_origin = settings.sub_allow_origin;
760 g_TestResults.sub_redirect_url = settings.sub_redirect_url;
761
762 std::string request_url;
763 if (!settings.sub_redirect_url.empty())
764 request_url = settings.sub_redirect_url;
765 else
766 request_url = settings.sub_url;
767
768 g_TestResults.url = settings.url;
769 std::stringstream ss;
770 ss << "<html><head>"
771 "<script language=\"JavaScript\">"
772 "function onResult(val) {"
773 " document.location = \"http://tests/exit?result=\"+val;"
774 "}"
775 "function execFetchHttpRequest() {";
776 ss << "fetch('" << request_url.c_str()
777 << "')"
778 ".then(function(response) {"
779 " if (response.status === 200) {"
780 " response.text().then(function(text) {"
781 " onResult(text);"
782 " }).catch(function(e) {"
783 " onResult('FAILURE'); "
784 " });"
785 " } else {"
786 " onResult('FAILURE');"
787 " }"
788 "}).catch(function(e) {"
789 " onResult('FAILURE');"
790 "});"
791 << "}"
792 "</script>"
793 "</head><body onload=\"execFetchHttpRequest();\">"
794 "Running execFetchHttpRequest..."
795 "</body></html>";
796 g_TestResults.html = ss.str();
797
798 g_TestResults.exit_url = "http://tests/exit";
799 } // namespace
800
SetUpXSS(const std::string & url,const std::string & sub_url,const std::string & domain=std::string ())801 void SetUpXSS(const std::string& url,
802 const std::string& sub_url,
803 const std::string& domain = std::string()) {
804 // 1. Load |url| which contains an iframe.
805 // 2. The iframe loads |sub_url|.
806 // 3. |sub_url| tries to call a JS function in |url|.
807 // 4. |url| tries to call a JS function in |sub_url|.
808
809 std::stringstream ss;
810 std::string domain_line;
811 if (!domain.empty())
812 domain_line = "document.domain = '" + domain + "';";
813
814 g_TestResults.sub_url = sub_url;
815 ss << "<html><head>"
816 "<script language=\"JavaScript\">"
817 << domain_line
818 << "function getResult() {"
819 " return 'SUCCESS';"
820 "}"
821 "function execXSSRequest() {"
822 " var result = 'FAILURE';"
823 " try {"
824 " result = parent.getResult();"
825 " } catch(e) { console.log(e.stack); }"
826 " document.location = \"http://tests/exit?result=\"+result;"
827 "}"
828 "</script>"
829 "</head><body onload=\"execXSSRequest();\">"
830 "Running execXSSRequest..."
831 "</body></html>";
832 g_TestResults.sub_html = ss.str();
833
834 g_TestResults.url = url;
835 ss.str("");
836 ss << "<html><head>"
837 "<script language=\"JavaScript\">"
838 << domain_line
839 << ""
840 "function getResult() {"
841 " try {"
842 " return document.getElementById('s').contentWindow.getResult();"
843 " } catch(e) { console.log(e.stack); }"
844 " return 'FAILURE';"
845 "}"
846 "</script>"
847 "</head><body>"
848 "<iframe src=\""
849 << sub_url.c_str()
850 << "\" id=\"s\">"
851 "</body></html>";
852 g_TestResults.html = ss.str();
853
854 g_TestResults.exit_url = "http://tests/exit";
855 }
856
857 } // namespace
858
859 // Test that scheme registration/unregistration works as expected.
TEST(SchemeHandlerTest,Registration)860 TEST(SchemeHandlerTest, Registration) {
861 RegisterTestScheme("customstd", "test");
862 g_TestResults.url = "customstd://test/run.html";
863 g_TestResults.html =
864 "<html><head></head><body><h1>Success!</h1></body></html>";
865
866 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
867 handler->ExecuteTest();
868
869 EXPECT_TRUE(g_TestResults.got_request);
870 EXPECT_TRUE(g_TestResults.got_read);
871 EXPECT_TRUE(g_TestResults.got_output);
872
873 // Unregister the handler.
874 EXPECT_TRUE(CefRegisterSchemeHandlerFactory("customstd", "test", nullptr));
875 WaitForIOThread();
876
877 g_TestResults.got_request.reset();
878 g_TestResults.got_read.reset();
879 g_TestResults.got_output.reset();
880 g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
881 handler->ExecuteTest();
882
883 EXPECT_TRUE(g_TestResults.got_error);
884 EXPECT_FALSE(g_TestResults.got_request);
885 EXPECT_FALSE(g_TestResults.got_read);
886 EXPECT_FALSE(g_TestResults.got_output);
887
888 // Re-register the handler.
889 EXPECT_TRUE(CefRegisterSchemeHandlerFactory(
890 "customstd", "test", new ClientSchemeHandlerFactory(&g_TestResults)));
891 WaitForIOThread();
892
893 g_TestResults.got_error.reset();
894 g_TestResults.expected_error_code = ERR_NONE;
895 handler->ExecuteTest();
896
897 ReleaseAndWaitForDestructor(handler);
898
899 EXPECT_FALSE(g_TestResults.got_error);
900 EXPECT_TRUE(g_TestResults.got_request);
901 EXPECT_TRUE(g_TestResults.got_read);
902 EXPECT_TRUE(g_TestResults.got_output);
903
904 ClearTestSchemes();
905 }
906
907 // Test that a custom standard scheme can return normal results.
TEST(SchemeHandlerTest,CustomStandardNormalResponse)908 TEST(SchemeHandlerTest, CustomStandardNormalResponse) {
909 RegisterTestScheme("customstd", "test");
910 g_TestResults.url = "customstd://test/run.html";
911 g_TestResults.html =
912 "<html><head></head><body><h1>Success!</h1></body></html>";
913
914 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
915 handler->ExecuteTest();
916 ReleaseAndWaitForDestructor(handler);
917
918 EXPECT_TRUE(g_TestResults.got_request);
919 EXPECT_TRUE(g_TestResults.got_read);
920 EXPECT_TRUE(g_TestResults.got_output);
921
922 ClearTestSchemes();
923 }
924
925 // Test that a custom standard scheme can return normal results with delayed
926 // responses.
TEST(SchemeHandlerTest,CustomStandardNormalResponseDelayed)927 TEST(SchemeHandlerTest, CustomStandardNormalResponseDelayed) {
928 RegisterTestScheme("customstd", "test");
929 g_TestResults.url = "customstd://test/run.html";
930 g_TestResults.html =
931 "<html><head></head><body><h1>Success!</h1></body></html>";
932 g_TestResults.delay = 100;
933
934 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
935 handler->ExecuteTest();
936 ReleaseAndWaitForDestructor(handler);
937
938 EXPECT_TRUE(g_TestResults.got_request);
939 EXPECT_TRUE(g_TestResults.got_read);
940 EXPECT_TRUE(g_TestResults.got_output);
941
942 ClearTestSchemes();
943 }
944
945 // Test that a custom nonstandard scheme can return normal results.
TEST(SchemeHandlerTest,CustomNonStandardNormalResponse)946 TEST(SchemeHandlerTest, CustomNonStandardNormalResponse) {
947 RegisterTestScheme("customnonstd", std::string());
948 g_TestResults.url = "customnonstd:some%20value";
949 g_TestResults.html =
950 "<html><head></head><body><h1>Success!</h1></body></html>";
951
952 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
953 handler->ExecuteTest();
954 ReleaseAndWaitForDestructor(handler);
955
956 EXPECT_TRUE(g_TestResults.got_request);
957 EXPECT_TRUE(g_TestResults.got_read);
958 EXPECT_TRUE(g_TestResults.got_output);
959
960 ClearTestSchemes();
961 }
962
963 // Test that a custom standard scheme can return an error code.
TEST(SchemeHandlerTest,CustomStandardErrorResponse)964 TEST(SchemeHandlerTest, CustomStandardErrorResponse) {
965 RegisterTestScheme("customstd", "test");
966 g_TestResults.url = "customstd://test/run.html";
967 g_TestResults.html = "<html><head></head><body><h1>404</h1></body></html>";
968 g_TestResults.status_code = 404;
969
970 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
971 handler->ExecuteTest();
972 ReleaseAndWaitForDestructor(handler);
973
974 EXPECT_TRUE(g_TestResults.got_request);
975 EXPECT_TRUE(g_TestResults.got_read);
976 EXPECT_TRUE(g_TestResults.got_output);
977
978 ClearTestSchemes();
979 }
980
981 // Test that a custom standard scheme can return a CEF error code in the
982 // response.
TEST(SchemeHandlerTest,CustomStandardErrorCodeResponse)983 TEST(SchemeHandlerTest, CustomStandardErrorCodeResponse) {
984 RegisterTestScheme("customstd", "test");
985 g_TestResults.url = "customstd://test/run.html";
986 g_TestResults.response_error_code = ERR_FILE_TOO_BIG;
987 g_TestResults.expected_error_code = ERR_FILE_TOO_BIG;
988
989 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
990 handler->ExecuteTest();
991 ReleaseAndWaitForDestructor(handler);
992
993 EXPECT_TRUE(g_TestResults.got_request);
994 EXPECT_FALSE(g_TestResults.got_read);
995 EXPECT_FALSE(g_TestResults.got_output);
996 EXPECT_TRUE(g_TestResults.got_error);
997
998 ClearTestSchemes();
999 }
1000
1001 // Test that a custom nonstandard scheme can return an error code.
TEST(SchemeHandlerTest,CustomNonStandardErrorResponse)1002 TEST(SchemeHandlerTest, CustomNonStandardErrorResponse) {
1003 RegisterTestScheme("customnonstd", std::string());
1004 g_TestResults.url = "customnonstd:some%20value";
1005 g_TestResults.html = "<html><head></head><body><h1>404</h1></body></html>";
1006 g_TestResults.status_code = 404;
1007
1008 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1009 handler->ExecuteTest();
1010 ReleaseAndWaitForDestructor(handler);
1011
1012 EXPECT_TRUE(g_TestResults.got_request);
1013 EXPECT_TRUE(g_TestResults.got_read);
1014 EXPECT_TRUE(g_TestResults.got_output);
1015
1016 ClearTestSchemes();
1017 }
1018
1019 // Test that custom standard scheme handling fails when the scheme name is
1020 // incorrect.
TEST(SchemeHandlerTest,CustomStandardNameNotHandled)1021 TEST(SchemeHandlerTest, CustomStandardNameNotHandled) {
1022 RegisterTestScheme("customstd", "test");
1023 g_TestResults.url = "customstd2://test/run.html";
1024 g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
1025
1026 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1027 handler->ExecuteTest();
1028 ReleaseAndWaitForDestructor(handler);
1029
1030 EXPECT_FALSE(g_TestResults.got_request);
1031 EXPECT_FALSE(g_TestResults.got_read);
1032 EXPECT_FALSE(g_TestResults.got_output);
1033 EXPECT_TRUE(g_TestResults.got_error);
1034
1035 ClearTestSchemes();
1036 }
1037
1038 // Test that custom nonstandard scheme handling fails when the scheme name is
1039 // incorrect.
TEST(SchemeHandlerTest,CustomNonStandardNameNotHandled)1040 TEST(SchemeHandlerTest, CustomNonStandardNameNotHandled) {
1041 RegisterTestScheme("customnonstd", std::string());
1042 g_TestResults.url = "customnonstd2:some%20value";
1043 g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
1044
1045 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1046 handler->ExecuteTest();
1047 ReleaseAndWaitForDestructor(handler);
1048
1049 EXPECT_FALSE(g_TestResults.got_request);
1050 EXPECT_FALSE(g_TestResults.got_read);
1051 EXPECT_FALSE(g_TestResults.got_output);
1052 EXPECT_TRUE(g_TestResults.got_error);
1053
1054 ClearTestSchemes();
1055 }
1056
1057 // Test that custom standard scheme handling fails when the domain name is
1058 // incorrect.
TEST(SchemeHandlerTest,CustomStandardDomainNotHandled)1059 TEST(SchemeHandlerTest, CustomStandardDomainNotHandled) {
1060 RegisterTestScheme("customstd", "test");
1061 g_TestResults.url = "customstd://noexist/run.html";
1062 g_TestResults.expected_error_code = ERR_UNKNOWN_URL_SCHEME;
1063
1064 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1065 handler->ExecuteTest();
1066 ReleaseAndWaitForDestructor(handler);
1067
1068 EXPECT_FALSE(g_TestResults.got_request);
1069 EXPECT_FALSE(g_TestResults.got_read);
1070 EXPECT_FALSE(g_TestResults.got_output);
1071 EXPECT_TRUE(g_TestResults.got_error);
1072
1073 ClearTestSchemes();
1074 }
1075
1076 // Test that a custom standard scheme can return no response.
TEST(SchemeHandlerTest,CustomStandardNoResponse)1077 TEST(SchemeHandlerTest, CustomStandardNoResponse) {
1078 RegisterTestScheme("customstd", "test");
1079 g_TestResults.url = "customstd://test/run.html";
1080
1081 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1082 handler->ExecuteTest();
1083 ReleaseAndWaitForDestructor(handler);
1084
1085 EXPECT_TRUE(g_TestResults.got_request);
1086 EXPECT_FALSE(g_TestResults.got_read);
1087 EXPECT_FALSE(g_TestResults.got_output);
1088
1089 ClearTestSchemes();
1090 }
1091
1092 // Test that a custom nonstandard scheme can return no response.
TEST(SchemeHandlerTest,CustomNonStandardNoResponse)1093 TEST(SchemeHandlerTest, CustomNonStandardNoResponse) {
1094 RegisterTestScheme("customnonstd", std::string());
1095 g_TestResults.url = "customnonstd:some%20value";
1096
1097 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1098 handler->ExecuteTest();
1099 ReleaseAndWaitForDestructor(handler);
1100
1101 EXPECT_TRUE(g_TestResults.got_request);
1102 EXPECT_FALSE(g_TestResults.got_read);
1103 EXPECT_FALSE(g_TestResults.got_output);
1104
1105 ClearTestSchemes();
1106 }
1107
1108 // Test that a custom standard scheme can generate redirects.
TEST(SchemeHandlerTest,CustomStandardRedirect)1109 TEST(SchemeHandlerTest, CustomStandardRedirect) {
1110 RegisterTestScheme("customstd", "test");
1111 g_TestResults.url = "customstd://test/run.html";
1112 g_TestResults.redirect_url = "customstd://test/redirect.html";
1113 g_TestResults.html =
1114 "<html><head></head><body><h1>Redirected</h1></body></html>";
1115
1116 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1117 handler->ExecuteTest();
1118 ReleaseAndWaitForDestructor(handler);
1119
1120 EXPECT_TRUE(g_TestResults.got_request);
1121 EXPECT_TRUE(g_TestResults.got_read);
1122 EXPECT_TRUE(g_TestResults.got_output);
1123 EXPECT_TRUE(g_TestResults.got_redirect);
1124
1125 ClearTestSchemes();
1126 }
1127
1128 // Test that a custom nonstandard scheme can generate redirects.
TEST(SchemeHandlerTest,CustomNonStandardRedirect)1129 TEST(SchemeHandlerTest, CustomNonStandardRedirect) {
1130 RegisterTestScheme("customnonstd", std::string());
1131 g_TestResults.url = "customnonstd:some%20value";
1132 g_TestResults.redirect_url = "customnonstd:some%20other%20value";
1133 g_TestResults.html =
1134 "<html><head></head><body><h1>Redirected</h1></body></html>";
1135
1136 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1137 handler->ExecuteTest();
1138 ReleaseAndWaitForDestructor(handler);
1139
1140 EXPECT_TRUE(g_TestResults.got_request);
1141 EXPECT_TRUE(g_TestResults.got_read);
1142 EXPECT_TRUE(g_TestResults.got_output);
1143 EXPECT_TRUE(g_TestResults.got_redirect);
1144
1145 ClearTestSchemes();
1146 }
1147
1148 // Test that a custom standard scheme can generate same origin XHR requests.
TEST(SchemeHandlerTest,CustomStandardXHRSameOriginSync)1149 TEST(SchemeHandlerTest, CustomStandardXHRSameOriginSync) {
1150 RegisterTestScheme("customstd", "test");
1151
1152 XHRTestSettings settings;
1153 settings.url = "customstd://test/run.html";
1154 settings.sub_url = "customstd://test/xhr.html";
1155 SetUpXHR(settings);
1156
1157 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1158 handler->ExecuteTest();
1159 ReleaseAndWaitForDestructor(handler);
1160
1161 EXPECT_TRUE(g_TestResults.got_request);
1162 EXPECT_TRUE(g_TestResults.got_read);
1163 EXPECT_TRUE(g_TestResults.got_output);
1164 EXPECT_TRUE(g_TestResults.got_sub_request);
1165 EXPECT_TRUE(g_TestResults.got_sub_read);
1166 EXPECT_TRUE(g_TestResults.got_sub_success);
1167
1168 ClearTestSchemes();
1169 }
1170
1171 // Test that a custom standard scheme can generate same origin XHR requests.
TEST(SchemeHandlerTest,CustomStandardXHRSameOriginAsync)1172 TEST(SchemeHandlerTest, CustomStandardXHRSameOriginAsync) {
1173 RegisterTestScheme("customstd", "test");
1174
1175 XHRTestSettings settings;
1176 settings.url = "customstd://test/run.html";
1177 settings.sub_url = "customstd://test/xhr.html";
1178 settings.synchronous = false;
1179 SetUpXHR(settings);
1180
1181 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1182 handler->ExecuteTest();
1183 ReleaseAndWaitForDestructor(handler);
1184
1185 EXPECT_TRUE(g_TestResults.got_request);
1186 EXPECT_TRUE(g_TestResults.got_read);
1187 EXPECT_TRUE(g_TestResults.got_output);
1188 EXPECT_TRUE(g_TestResults.got_sub_request);
1189 EXPECT_TRUE(g_TestResults.got_sub_read);
1190 EXPECT_TRUE(g_TestResults.got_sub_success);
1191
1192 ClearTestSchemes();
1193 }
1194
1195 // Test that custom nonstandard schemes are treated as unique origins that
1196 // cannot generate XHR requests.
TEST(SchemeHandlerTest,CustomNonStandardXHRSameOriginSync)1197 TEST(SchemeHandlerTest, CustomNonStandardXHRSameOriginSync) {
1198 RegisterTestScheme("customnonstd", std::string());
1199
1200 XHRTestSettings settings;
1201 settings.url = "customnonstd:some%20value";
1202 settings.sub_url = "customnonstd:xhr%20value";
1203 SetUpXHR(settings);
1204
1205 g_TestResults.console_messages.push_back(
1206 "Access to XMLHttpRequest at 'customnonstd:xhr%20value' from origin "
1207 "'null' has been blocked by CORS policy: Cross origin requests are only "
1208 "supported for protocol schemes:");
1209
1210 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1211 handler->ExecuteTest();
1212 ReleaseAndWaitForDestructor(handler);
1213
1214 EXPECT_TRUE(g_TestResults.got_request);
1215 EXPECT_TRUE(g_TestResults.got_read);
1216 EXPECT_TRUE(g_TestResults.got_output);
1217 EXPECT_FALSE(g_TestResults.got_sub_request);
1218 EXPECT_FALSE(g_TestResults.got_sub_read);
1219 EXPECT_FALSE(g_TestResults.got_sub_success);
1220
1221 ClearTestSchemes();
1222 }
1223
1224 // Test that custom nonstandard schemes are treated as unique origins that
1225 // cannot generate XHR requests.
TEST(SchemeHandlerTest,CustomNonStandardXHRSameOriginAsync)1226 TEST(SchemeHandlerTest, CustomNonStandardXHRSameOriginAsync) {
1227 RegisterTestScheme("customnonstd", std::string());
1228
1229 XHRTestSettings settings;
1230 settings.url = "customnonstd:some%20value";
1231 settings.sub_url = "customnonstd:xhr%20value";
1232 settings.synchronous = false;
1233 SetUpXHR(settings);
1234
1235 g_TestResults.console_messages.push_back(
1236 "Access to XMLHttpRequest at 'customnonstd:xhr%20value' from origin "
1237 "'null' has been blocked by CORS policy: Cross origin requests are only "
1238 "supported for protocol schemes:");
1239
1240 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1241 handler->ExecuteTest();
1242 ReleaseAndWaitForDestructor(handler);
1243
1244 EXPECT_TRUE(g_TestResults.got_request);
1245 EXPECT_TRUE(g_TestResults.got_read);
1246 EXPECT_TRUE(g_TestResults.got_output);
1247 EXPECT_FALSE(g_TestResults.got_sub_request);
1248 EXPECT_FALSE(g_TestResults.got_sub_read);
1249 EXPECT_FALSE(g_TestResults.got_sub_success);
1250
1251 ClearTestSchemes();
1252 }
1253
1254 // Test that a non fetch enabled custom standard scheme can't generate same
1255 // origin Fetch requests.
TEST(SchemeHandlerTest,CustomStandardFetchSameOrigin)1256 TEST(SchemeHandlerTest, CustomStandardFetchSameOrigin) {
1257 RegisterTestScheme("customstd", "test");
1258
1259 FetchTestSettings settings;
1260 settings.url = "customstd://test/run.html";
1261 settings.sub_url = "customstd://test/fetch.html";
1262 SetUpFetch(settings);
1263
1264 g_TestResults.console_messages.push_back(
1265 "Fetch API cannot load customstd://test/fetch.html. URL scheme "
1266 "\"customstd\" is not supported.");
1267
1268 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1269 handler->ExecuteTest();
1270 ReleaseAndWaitForDestructor(handler);
1271
1272 EXPECT_TRUE(g_TestResults.got_request);
1273 EXPECT_TRUE(g_TestResults.got_read);
1274 EXPECT_TRUE(g_TestResults.got_output);
1275 EXPECT_FALSE(g_TestResults.got_sub_request);
1276 EXPECT_FALSE(g_TestResults.got_sub_read);
1277 EXPECT_FALSE(g_TestResults.got_sub_success);
1278
1279 ClearTestSchemes();
1280 }
1281
1282 // Test that a fetch enabled custom standard scheme can generate same origin
1283 // Fetch requests.
TEST(SchemeHandlerTest,FetchCustomStandardFetchSameOrigin)1284 TEST(SchemeHandlerTest, FetchCustomStandardFetchSameOrigin) {
1285 RegisterTestScheme("customstdfetch", "test");
1286
1287 FetchTestSettings settings;
1288 settings.url = "customstdfetch://test/run.html";
1289 settings.sub_url = "customstdfetch://test/fetch.html";
1290 SetUpFetch(settings);
1291
1292 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1293 handler->ExecuteTest();
1294 ReleaseAndWaitForDestructor(handler);
1295
1296 EXPECT_TRUE(g_TestResults.got_request);
1297 EXPECT_TRUE(g_TestResults.got_read);
1298 EXPECT_TRUE(g_TestResults.got_output);
1299 EXPECT_TRUE(g_TestResults.got_sub_request);
1300 EXPECT_TRUE(g_TestResults.got_sub_read);
1301 EXPECT_TRUE(g_TestResults.got_sub_success);
1302
1303 ClearTestSchemes();
1304 }
1305
1306 // Test that custom nonstandard schemes are treated as unique origins that
1307 // cannot generate Fetch requests.
TEST(SchemeHandlerTest,CustomNonStandardFetchSameOrigin)1308 TEST(SchemeHandlerTest, CustomNonStandardFetchSameOrigin) {
1309 RegisterTestScheme("customnonstd", std::string());
1310
1311 FetchTestSettings settings;
1312 settings.url = "customnonstd:some%20value";
1313 settings.sub_url = "customnonstd:xhr%20value";
1314 SetUpFetch(settings);
1315
1316 g_TestResults.console_messages.push_back(
1317 "Fetch API cannot load customnonstd:xhr%20value. URL scheme "
1318 "\"customnonstd\" is not supported.");
1319
1320 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1321 handler->ExecuteTest();
1322 ReleaseAndWaitForDestructor(handler);
1323
1324 EXPECT_TRUE(g_TestResults.got_request);
1325 EXPECT_TRUE(g_TestResults.got_read);
1326 EXPECT_TRUE(g_TestResults.got_output);
1327 EXPECT_FALSE(g_TestResults.got_sub_request);
1328 EXPECT_FALSE(g_TestResults.got_sub_read);
1329 EXPECT_FALSE(g_TestResults.got_sub_success);
1330
1331 ClearTestSchemes();
1332 }
1333
1334 // Test that a custom standard scheme can generate same origin XSS requests.
TEST(SchemeHandlerTest,CustomStandardXSSSameOrigin)1335 TEST(SchemeHandlerTest, CustomStandardXSSSameOrigin) {
1336 RegisterTestScheme("customstd", "test");
1337 SetUpXSS("customstd://test/run.html", "customstd://test/iframe.html");
1338
1339 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1340 handler->ExecuteTest();
1341 ReleaseAndWaitForDestructor(handler);
1342
1343 EXPECT_TRUE(g_TestResults.got_request);
1344 EXPECT_TRUE(g_TestResults.got_read);
1345 EXPECT_TRUE(g_TestResults.got_output);
1346 EXPECT_TRUE(g_TestResults.got_sub_request);
1347 EXPECT_TRUE(g_TestResults.got_sub_read);
1348 EXPECT_TRUE(g_TestResults.got_sub_success);
1349
1350 ClearTestSchemes();
1351 }
1352
1353 // Test that custom nonstandard schemes are treated as unique origins that
1354 // cannot generate XSS requests.
TEST(SchemeHandlerTest,CustomNonStandardXSSSameOrigin)1355 TEST(SchemeHandlerTest, CustomNonStandardXSSSameOrigin) {
1356 RegisterTestScheme("customnonstd", std::string());
1357 SetUpXSS("customnonstd:some%20value", "customnonstd:xhr%20value");
1358
1359 g_TestResults.console_messages.push_back(
1360 "Error: Blocked a frame with origin \"null\" from accessing a "
1361 "cross-origin frame.");
1362
1363 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1364 handler->ExecuteTest();
1365 ReleaseAndWaitForDestructor(handler);
1366
1367 EXPECT_TRUE(g_TestResults.got_request);
1368 EXPECT_TRUE(g_TestResults.got_read);
1369 EXPECT_TRUE(g_TestResults.got_output);
1370 EXPECT_TRUE(g_TestResults.got_sub_request);
1371 EXPECT_TRUE(g_TestResults.got_sub_read);
1372 EXPECT_FALSE(g_TestResults.got_sub_success);
1373
1374 ClearTestSchemes();
1375 }
1376
1377 // Test that a custom standard scheme cannot generate cross-domain XHR requests
1378 // by default. Behavior should be the same as with HTTP.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginSync)1379 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginSync) {
1380 RegisterTestScheme("customstd", "test1");
1381 RegisterTestScheme("customstd", "test2");
1382
1383 XHRTestSettings settings;
1384 settings.url = "customstd://test1/run.html";
1385 settings.sub_url = "customstd://test2/xhr.html";
1386 SetUpXHR(settings);
1387
1388 g_TestResults.console_messages.push_back(
1389 "Access to XMLHttpRequest at 'customstd://test2/xhr.html' from origin "
1390 "'customstd://test1' has been blocked by CORS policy: No "
1391 "'Access-Control-Allow-Origin' header is present on the requested "
1392 "resource.");
1393
1394 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1395 handler->ExecuteTest();
1396 ReleaseAndWaitForDestructor(handler);
1397
1398 EXPECT_TRUE(g_TestResults.got_request);
1399 EXPECT_TRUE(g_TestResults.got_read);
1400 EXPECT_TRUE(g_TestResults.got_output);
1401 EXPECT_TRUE(g_TestResults.got_sub_request);
1402 EXPECT_FALSE(g_TestResults.got_sub_read);
1403 EXPECT_FALSE(g_TestResults.got_sub_success);
1404
1405 ClearTestSchemes();
1406 }
1407
1408 // Test that a custom standard scheme cannot generate cross-domain XHR requests
1409 // by default. Behavior should be the same as with HTTP.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginAsync)1410 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginAsync) {
1411 RegisterTestScheme("customstd", "test1");
1412 RegisterTestScheme("customstd", "test2");
1413
1414 XHRTestSettings settings;
1415 settings.url = "customstd://test1/run.html";
1416 settings.sub_url = "customstd://test2/xhr.html";
1417 settings.synchronous = false;
1418 SetUpXHR(settings);
1419
1420 g_TestResults.console_messages.push_back(
1421 "Access to XMLHttpRequest at 'customstd://test2/xhr.html' from origin "
1422 "'customstd://test1' has been blocked by CORS policy: No "
1423 "'Access-Control-Allow-Origin' header is present on the requested "
1424 "resource.");
1425
1426 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1427 handler->ExecuteTest();
1428 ReleaseAndWaitForDestructor(handler);
1429
1430 EXPECT_TRUE(g_TestResults.got_request);
1431 EXPECT_TRUE(g_TestResults.got_read);
1432 EXPECT_TRUE(g_TestResults.got_output);
1433 EXPECT_TRUE(g_TestResults.got_sub_request);
1434 EXPECT_FALSE(g_TestResults.got_sub_read);
1435 EXPECT_FALSE(g_TestResults.got_sub_success);
1436
1437 ClearTestSchemes();
1438 }
1439
1440 // Test that a custom standard scheme cannot generate cross-domain Fetch
1441 // requests by default. Behavior should be the same as with HTTP.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOrigin)1442 TEST(SchemeHandlerTest, CustomStandardFetchDifferentOrigin) {
1443 RegisterTestScheme("customstdfetch", "test1");
1444 RegisterTestScheme("customstdfetch", "test2");
1445
1446 FetchTestSettings settings;
1447 settings.url = "customstdfetch://test1/run.html";
1448 settings.sub_url = "customstdfetch://test2/fetch.html";
1449 SetUpFetch(settings);
1450
1451 g_TestResults.console_messages.push_back(
1452 "Access to fetch at 'customstdfetch://test2/fetch.html' from origin "
1453 "'customstdfetch://test1' has been blocked by CORS policy: No "
1454 "'Access-Control-Allow-Origin' header is present on the requested "
1455 "resource. If an opaque response serves your needs, set the request's "
1456 "mode to 'no-cors' to fetch the resource with CORS disabled.");
1457
1458 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1459 handler->ExecuteTest();
1460 ReleaseAndWaitForDestructor(handler);
1461
1462 EXPECT_TRUE(g_TestResults.got_request);
1463 EXPECT_TRUE(g_TestResults.got_read);
1464 EXPECT_TRUE(g_TestResults.got_output);
1465 EXPECT_TRUE(g_TestResults.got_sub_request);
1466 EXPECT_FALSE(g_TestResults.got_sub_read);
1467 EXPECT_FALSE(g_TestResults.got_sub_success);
1468
1469 ClearTestSchemes();
1470 }
1471
1472 // Test that a custom standard scheme cannot generate cross-domain XSS requests
1473 // by default.
TEST(SchemeHandlerTest,CustomStandardXSSDifferentOrigin)1474 TEST(SchemeHandlerTest, CustomStandardXSSDifferentOrigin) {
1475 RegisterTestScheme("customstd", "test1");
1476 RegisterTestScheme("customstd", "test2");
1477 SetUpXSS("customstd://test1/run.html", "customstd://test2/iframe.html");
1478
1479 g_TestResults.console_messages.push_back(
1480 "Error: Blocked a frame with origin \"customstd://test2\" from accessing "
1481 "a cross-origin frame.");
1482
1483 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1484 handler->ExecuteTest();
1485 ReleaseAndWaitForDestructor(handler);
1486
1487 EXPECT_TRUE(g_TestResults.got_request);
1488 EXPECT_TRUE(g_TestResults.got_read);
1489 EXPECT_TRUE(g_TestResults.got_output);
1490 EXPECT_TRUE(g_TestResults.got_sub_request);
1491 EXPECT_TRUE(g_TestResults.got_sub_read);
1492 EXPECT_FALSE(g_TestResults.got_sub_success);
1493
1494 ClearTestSchemes();
1495 }
1496
1497 // Test that a cross-protocol iframe load succeeds, and that the custom
1498 // standard scheme cannot generate XSS requests to the HTTP protocol by default.
TEST(SchemeHandlerTest,CustomStandardXSSDifferentProtocolHttp)1499 TEST(SchemeHandlerTest, CustomStandardXSSDifferentProtocolHttp) {
1500 RegisterTestScheme("customstd", "test1");
1501 RegisterTestScheme("http", "test2");
1502 SetUpXSS("customstd://test1/run.html", "http://test2/iframe.html");
1503
1504 g_TestResults.console_messages.push_back(
1505 "Error: Blocked a frame with origin \"http://test2\" from accessing a "
1506 "cross-origin frame.");
1507
1508 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1509 handler->ExecuteTest();
1510 ReleaseAndWaitForDestructor(handler);
1511
1512 EXPECT_TRUE(g_TestResults.got_request);
1513 EXPECT_TRUE(g_TestResults.got_read);
1514 EXPECT_TRUE(g_TestResults.got_output);
1515 EXPECT_TRUE(g_TestResults.got_sub_request);
1516 EXPECT_TRUE(g_TestResults.got_sub_read);
1517 EXPECT_FALSE(g_TestResults.got_sub_success);
1518
1519 ClearTestSchemes();
1520 }
1521
1522 // Test that a cross-protocol iframe load succeeds, and that the custom
1523 // standard scheme cannot generate XSS requests to a non-standard scheme by
1524 // default.
TEST(SchemeHandlerTest,CustomStandardXSSDifferentProtocolCustomNonStandard)1525 TEST(SchemeHandlerTest, CustomStandardXSSDifferentProtocolCustomNonStandard) {
1526 RegisterTestScheme("customstd", "test1");
1527 RegisterTestScheme("customnonstd", std::string());
1528 SetUpXSS("customstd://test1/run.html", "customnonstd:some%20value");
1529
1530 g_TestResults.console_messages.push_back(
1531 "Error: Blocked a frame with origin \"null\" from accessing a "
1532 "cross-origin frame.");
1533
1534 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1535 handler->ExecuteTest();
1536 ReleaseAndWaitForDestructor(handler);
1537
1538 EXPECT_TRUE(g_TestResults.got_request);
1539 EXPECT_TRUE(g_TestResults.got_read);
1540 EXPECT_TRUE(g_TestResults.got_output);
1541 EXPECT_TRUE(g_TestResults.got_sub_request);
1542 EXPECT_TRUE(g_TestResults.got_sub_read);
1543 EXPECT_FALSE(g_TestResults.got_sub_success);
1544
1545 ClearTestSchemes();
1546 }
1547
1548 // Test that a cross-protocol iframe load succeeds, and that the HTTP protocol
1549 // cannot generate XSS requests to the custom standard scheme by default.
TEST(SchemeHandlerTest,HttpXSSDifferentProtocolCustomStandard)1550 TEST(SchemeHandlerTest, HttpXSSDifferentProtocolCustomStandard) {
1551 RegisterTestScheme("http", "test1");
1552 RegisterTestScheme("customstd", "test2");
1553 SetUpXSS("http://test1/run.html", "customstd://test2/iframe.html");
1554
1555 g_TestResults.console_messages.push_back(
1556 "Error: Blocked a frame with origin \"customstd://test2\" from accessing "
1557 "a cross-origin frame.");
1558
1559 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1560 handler->ExecuteTest();
1561 ReleaseAndWaitForDestructor(handler);
1562
1563 EXPECT_TRUE(g_TestResults.got_request);
1564 EXPECT_TRUE(g_TestResults.got_read);
1565 EXPECT_TRUE(g_TestResults.got_output);
1566 EXPECT_TRUE(g_TestResults.got_sub_request);
1567 EXPECT_TRUE(g_TestResults.got_sub_read);
1568 EXPECT_FALSE(g_TestResults.got_sub_success);
1569
1570 ClearTestSchemes();
1571 }
1572
1573 // Test that a cross-protocol iframe load succeeds, and that the HTTP protocol
1574 // cannot generate XSS requests to the custom non-standard scheme by default.
TEST(SchemeHandlerTest,HttpXSSDifferentProtocolCustomNonStandard)1575 TEST(SchemeHandlerTest, HttpXSSDifferentProtocolCustomNonStandard) {
1576 RegisterTestScheme("http", "test1");
1577 RegisterTestScheme("customnonstd", std::string());
1578 SetUpXSS("http://test1/run.html", "customnonstd:some%20value");
1579
1580 g_TestResults.console_messages.push_back(
1581 "Error: Blocked a frame with origin \"null\" from accessing a "
1582 "cross-origin frame.");
1583
1584 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1585 handler->ExecuteTest();
1586 ReleaseAndWaitForDestructor(handler);
1587
1588 EXPECT_TRUE(g_TestResults.got_request);
1589 EXPECT_TRUE(g_TestResults.got_read);
1590 EXPECT_TRUE(g_TestResults.got_output);
1591 EXPECT_TRUE(g_TestResults.got_sub_request);
1592 EXPECT_TRUE(g_TestResults.got_sub_read);
1593 EXPECT_FALSE(g_TestResults.got_sub_success);
1594
1595 ClearTestSchemes();
1596 }
1597
1598 // Test that an HTTP scheme cannot generate cross-domain XHR requests by
1599 // default.
TEST(SchemeHandlerTest,HttpXHRDifferentOriginSync)1600 TEST(SchemeHandlerTest, HttpXHRDifferentOriginSync) {
1601 RegisterTestScheme("http", "test1");
1602 RegisterTestScheme("http", "test2");
1603
1604 XHRTestSettings settings;
1605 settings.url = "http://test1/run.html";
1606 settings.sub_url = "http://test2/xhr.html";
1607 SetUpXHR(settings);
1608
1609 g_TestResults.console_messages.push_back(
1610 "Access to XMLHttpRequest at 'http://test2/xhr.html' from origin "
1611 "'http://test1' has been blocked by CORS policy: No "
1612 "'Access-Control-Allow-Origin' header is present on the requested "
1613 "resource.");
1614
1615 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1616 handler->ExecuteTest();
1617 ReleaseAndWaitForDestructor(handler);
1618
1619 EXPECT_TRUE(g_TestResults.got_request);
1620 EXPECT_TRUE(g_TestResults.got_read);
1621 EXPECT_TRUE(g_TestResults.got_output);
1622 EXPECT_TRUE(g_TestResults.got_sub_request);
1623 EXPECT_FALSE(g_TestResults.got_sub_read);
1624 EXPECT_FALSE(g_TestResults.got_sub_success);
1625
1626 ClearTestSchemes();
1627 }
1628
1629 // Test that an HTTP scheme cannot generate cross-domain XHR requests by
1630 // default.
TEST(SchemeHandlerTest,HttpXHRDifferentOriginAsync)1631 TEST(SchemeHandlerTest, HttpXHRDifferentOriginAsync) {
1632 RegisterTestScheme("http", "test1");
1633 RegisterTestScheme("http", "test2");
1634
1635 XHRTestSettings settings;
1636 settings.url = "http://test1/run.html";
1637 settings.sub_url = "http://test2/xhr.html";
1638 settings.synchronous = false;
1639 SetUpXHR(settings);
1640
1641 g_TestResults.console_messages.push_back(
1642 "Access to XMLHttpRequest at 'http://test2/xhr.html' from origin "
1643 "'http://test1' has been blocked by CORS policy: No "
1644 "'Access-Control-Allow-Origin' header is present on the requested "
1645 "resource.");
1646
1647 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1648 handler->ExecuteTest();
1649 ReleaseAndWaitForDestructor(handler);
1650
1651 EXPECT_TRUE(g_TestResults.got_request);
1652 EXPECT_TRUE(g_TestResults.got_read);
1653 EXPECT_TRUE(g_TestResults.got_output);
1654 EXPECT_TRUE(g_TestResults.got_sub_request);
1655 EXPECT_FALSE(g_TestResults.got_sub_read);
1656 EXPECT_FALSE(g_TestResults.got_sub_success);
1657
1658 ClearTestSchemes();
1659 }
1660
1661 // Test that an HTTP scheme cannot generate cross-domain Fetch requests by
1662 // default.
TEST(SchemeHandlerTest,HttpFetchDifferentOriginAsync)1663 TEST(SchemeHandlerTest, HttpFetchDifferentOriginAsync) {
1664 RegisterTestScheme("http", "test1");
1665 RegisterTestScheme("http", "test2");
1666
1667 FetchTestSettings settings;
1668 settings.url = "http://test1/run.html";
1669 settings.sub_url = "http://test2/fetch.html";
1670 SetUpFetch(settings);
1671
1672 g_TestResults.console_messages.push_back(
1673 "Access to fetch at 'http://test2/fetch.html' from origin 'http://test1' "
1674 "has been blocked by CORS policy: No 'Access-Control-Allow-Origin' "
1675 "header is present on the requested resource. If an opaque response "
1676 "serves your needs, set the request's mode to 'no-cors' to fetch the "
1677 "resource with CORS disabled.");
1678
1679 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1680 handler->ExecuteTest();
1681 ReleaseAndWaitForDestructor(handler);
1682
1683 EXPECT_TRUE(g_TestResults.got_request);
1684 EXPECT_TRUE(g_TestResults.got_read);
1685 EXPECT_TRUE(g_TestResults.got_output);
1686 EXPECT_TRUE(g_TestResults.got_sub_request);
1687 EXPECT_FALSE(g_TestResults.got_sub_read);
1688 EXPECT_FALSE(g_TestResults.got_sub_success);
1689
1690 ClearTestSchemes();
1691 }
1692
1693 // Test that an HTTP scheme cannot generate cross-domain XSS requests by
1694 // default.
TEST(SchemeHandlerTest,HttpXSSDifferentOrigin)1695 TEST(SchemeHandlerTest, HttpXSSDifferentOrigin) {
1696 RegisterTestScheme("http", "test1");
1697 RegisterTestScheme("http", "test2");
1698 SetUpXSS("http://test1/run.html", "http://test2/xss.html");
1699
1700 g_TestResults.console_messages.push_back(
1701 "Error: Blocked a frame with origin \"http://test2\" from accessing a "
1702 "cross-origin frame.");
1703
1704 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1705 handler->ExecuteTest();
1706 ReleaseAndWaitForDestructor(handler);
1707
1708 EXPECT_TRUE(g_TestResults.got_request);
1709 EXPECT_TRUE(g_TestResults.got_read);
1710 EXPECT_TRUE(g_TestResults.got_output);
1711 EXPECT_TRUE(g_TestResults.got_sub_request);
1712 EXPECT_TRUE(g_TestResults.got_sub_read);
1713 EXPECT_FALSE(g_TestResults.got_sub_success);
1714
1715 ClearTestSchemes();
1716 }
1717
1718 // Test that a custom standard scheme can generate cross-domain XHR requests
1719 // when setting the Access-Control-Allow-Origin header. Should behave the same
1720 // as HTTP.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithHeaderSync)1721 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithHeaderSync) {
1722 RegisterTestScheme("customstd", "test1");
1723 RegisterTestScheme("customstd", "test2");
1724
1725 XHRTestSettings settings;
1726 settings.url = "customstd://test1/run.html";
1727 settings.sub_url = "customstd://test2/xhr.html";
1728 settings.sub_allow_origin = "customstd://test1";
1729 SetUpXHR(settings);
1730
1731 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1732 handler->ExecuteTest();
1733 ReleaseAndWaitForDestructor(handler);
1734
1735 EXPECT_TRUE(g_TestResults.got_request);
1736 EXPECT_TRUE(g_TestResults.got_read);
1737 EXPECT_TRUE(g_TestResults.got_output);
1738 EXPECT_TRUE(g_TestResults.got_sub_request);
1739 EXPECT_TRUE(g_TestResults.got_sub_read);
1740 EXPECT_TRUE(g_TestResults.got_sub_success);
1741
1742 ClearTestSchemes();
1743 }
1744
1745 // Test that a custom standard scheme can generate cross-domain XHR requests
1746 // when setting the Access-Control-Allow-Origin header. Should behave the same
1747 // as HTTP.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithHeaderAsync)1748 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithHeaderAsync) {
1749 RegisterTestScheme("customstd", "test1");
1750 RegisterTestScheme("customstd", "test2");
1751
1752 XHRTestSettings settings;
1753 settings.url = "customstd://test1/run.html";
1754 settings.sub_url = "customstd://test2/xhr.html";
1755 settings.sub_allow_origin = "customstd://test1";
1756 settings.synchronous = false;
1757 SetUpXHR(settings);
1758
1759 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1760 handler->ExecuteTest();
1761 ReleaseAndWaitForDestructor(handler);
1762
1763 EXPECT_TRUE(g_TestResults.got_request);
1764 EXPECT_TRUE(g_TestResults.got_read);
1765 EXPECT_TRUE(g_TestResults.got_output);
1766 EXPECT_TRUE(g_TestResults.got_sub_request);
1767 EXPECT_TRUE(g_TestResults.got_sub_read);
1768 EXPECT_TRUE(g_TestResults.got_sub_success);
1769
1770 ClearTestSchemes();
1771 }
1772
1773 // Test that a custom standard scheme can generate cross-domain Fetch requests
1774 // when setting the Access-Control-Allow-Origin header. Should behave the same
1775 // as HTTP.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginWithHeader)1776 TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithHeader) {
1777 RegisterTestScheme("customstdfetch", "test1");
1778 RegisterTestScheme("customstdfetch", "test2");
1779
1780 FetchTestSettings settings;
1781 settings.url = "customstdfetch://test1/run.html";
1782 settings.sub_url = "customstdfetch://test2/fetch.html";
1783 settings.sub_allow_origin = "customstdfetch://test1";
1784 SetUpFetch(settings);
1785
1786 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1787 handler->ExecuteTest();
1788 ReleaseAndWaitForDestructor(handler);
1789
1790 EXPECT_TRUE(g_TestResults.got_request);
1791 EXPECT_TRUE(g_TestResults.got_read);
1792 EXPECT_TRUE(g_TestResults.got_output);
1793 EXPECT_TRUE(g_TestResults.got_sub_request);
1794 EXPECT_TRUE(g_TestResults.got_sub_read);
1795 EXPECT_TRUE(g_TestResults.got_sub_success);
1796
1797 ClearTestSchemes();
1798 }
1799
1800 // Test that a custom standard scheme can generate cross-domain XHR requests
1801 // when using the cross-origin whitelist.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithWhitelistSync1)1802 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistSync1) {
1803 RegisterTestScheme("customstd", "test1");
1804 RegisterTestScheme("customstd", "test2");
1805
1806 XHRTestSettings settings;
1807 settings.url = "customstd://test1/run.html";
1808 settings.sub_url = "customstd://test2/xhr.html";
1809 SetUpXHR(settings);
1810
1811 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
1812 "test2", false));
1813 WaitForUIThread();
1814
1815 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1816 handler->ExecuteTest();
1817 ReleaseAndWaitForDestructor(handler);
1818
1819 EXPECT_TRUE(g_TestResults.got_request);
1820 EXPECT_TRUE(g_TestResults.got_read);
1821 EXPECT_TRUE(g_TestResults.got_output);
1822 EXPECT_TRUE(g_TestResults.got_sub_request);
1823 EXPECT_TRUE(g_TestResults.got_sub_read);
1824 EXPECT_TRUE(g_TestResults.got_sub_success);
1825
1826 EXPECT_TRUE(CefClearCrossOriginWhitelist());
1827 WaitForUIThread();
1828
1829 ClearTestSchemes();
1830 }
1831
1832 // Same as above but origin whitelist matches any domain.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithWhitelistSync2)1833 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistSync2) {
1834 RegisterTestScheme("customstd", "test1");
1835 RegisterTestScheme("customstd", "test2");
1836
1837 XHRTestSettings settings;
1838 settings.url = "customstd://test1/run.html";
1839 settings.sub_url = "customstd://test2/xhr.html";
1840 SetUpXHR(settings);
1841
1842 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
1843 CefString(), true));
1844 WaitForUIThread();
1845
1846 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1847 handler->ExecuteTest();
1848 ReleaseAndWaitForDestructor(handler);
1849
1850 EXPECT_TRUE(g_TestResults.got_request);
1851 EXPECT_TRUE(g_TestResults.got_read);
1852 EXPECT_TRUE(g_TestResults.got_output);
1853 EXPECT_TRUE(g_TestResults.got_sub_request);
1854 EXPECT_TRUE(g_TestResults.got_sub_read);
1855 EXPECT_TRUE(g_TestResults.got_sub_success);
1856
1857 EXPECT_TRUE(CefClearCrossOriginWhitelist());
1858 WaitForUIThread();
1859
1860 ClearTestSchemes();
1861 }
1862
1863 // Same as above but origin whitelist matches sub-domains.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithWhitelistSync3)1864 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistSync3) {
1865 RegisterTestScheme("customstd", "test1");
1866 RegisterTestScheme("customstd", "a.test2.foo");
1867
1868 XHRTestSettings settings;
1869 settings.url = "customstd://test1/run.html";
1870 settings.sub_url = "customstd://a.test2.foo/xhr.html";
1871 SetUpXHR(settings);
1872
1873 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
1874 "test2.foo", true));
1875 WaitForUIThread();
1876
1877 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1878 handler->ExecuteTest();
1879 ReleaseAndWaitForDestructor(handler);
1880
1881 EXPECT_TRUE(g_TestResults.got_request);
1882 EXPECT_TRUE(g_TestResults.got_read);
1883 EXPECT_TRUE(g_TestResults.got_output);
1884 EXPECT_TRUE(g_TestResults.got_sub_request);
1885 EXPECT_TRUE(g_TestResults.got_sub_read);
1886 EXPECT_TRUE(g_TestResults.got_sub_success);
1887
1888 EXPECT_TRUE(CefClearCrossOriginWhitelist());
1889 WaitForUIThread();
1890
1891 ClearTestSchemes();
1892 }
1893
1894 // Test that a custom standard scheme can generate cross-domain XHR requests
1895 // when using the cross-origin whitelist.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithWhitelistAsync1)1896 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistAsync1) {
1897 RegisterTestScheme("customstd", "test1");
1898 RegisterTestScheme("customstd", "test2");
1899
1900 XHRTestSettings settings;
1901 settings.url = "customstd://test1/run.html";
1902 settings.sub_url = "customstd://test2/xhr.html";
1903 settings.synchronous = false;
1904 SetUpXHR(settings);
1905
1906 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
1907 "test2", false));
1908 WaitForUIThread();
1909
1910 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1911 handler->ExecuteTest();
1912 ReleaseAndWaitForDestructor(handler);
1913
1914 EXPECT_TRUE(g_TestResults.got_request);
1915 EXPECT_TRUE(g_TestResults.got_read);
1916 EXPECT_TRUE(g_TestResults.got_output);
1917 EXPECT_TRUE(g_TestResults.got_sub_request);
1918 EXPECT_TRUE(g_TestResults.got_sub_read);
1919 EXPECT_TRUE(g_TestResults.got_sub_success);
1920
1921 EXPECT_TRUE(CefClearCrossOriginWhitelist());
1922 WaitForUIThread();
1923
1924 ClearTestSchemes();
1925 }
1926
1927 // Same as above but origin whitelist matches any domain.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithWhitelistAsync2)1928 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistAsync2) {
1929 RegisterTestScheme("customstd", "test1");
1930 RegisterTestScheme("customstd", "test2");
1931
1932 XHRTestSettings settings;
1933 settings.url = "customstd://test1/run.html";
1934 settings.sub_url = "customstd://test2/xhr.html";
1935 settings.synchronous = false;
1936 SetUpXHR(settings);
1937
1938 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
1939 CefString(), true));
1940 WaitForUIThread();
1941
1942 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1943 handler->ExecuteTest();
1944 ReleaseAndWaitForDestructor(handler);
1945
1946 EXPECT_TRUE(g_TestResults.got_request);
1947 EXPECT_TRUE(g_TestResults.got_read);
1948 EXPECT_TRUE(g_TestResults.got_output);
1949 EXPECT_TRUE(g_TestResults.got_sub_request);
1950 EXPECT_TRUE(g_TestResults.got_sub_read);
1951 EXPECT_TRUE(g_TestResults.got_sub_success);
1952
1953 EXPECT_TRUE(CefClearCrossOriginWhitelist());
1954 WaitForUIThread();
1955
1956 ClearTestSchemes();
1957 }
1958
1959 // Same as above but origin whitelist matches sub-domains.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginWithWhitelistAsync3)1960 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginWithWhitelistAsync3) {
1961 RegisterTestScheme("customstd", "test1");
1962 RegisterTestScheme("customstd", "a.test2.foo");
1963
1964 XHRTestSettings settings;
1965 settings.url = "customstd://test1/run.html";
1966 settings.sub_url = "customstd://a.test2.foo/xhr.html";
1967 settings.synchronous = false;
1968 SetUpXHR(settings);
1969
1970 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
1971 "test2.foo", true));
1972 WaitForUIThread();
1973
1974 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
1975 handler->ExecuteTest();
1976 ReleaseAndWaitForDestructor(handler);
1977
1978 EXPECT_TRUE(g_TestResults.got_request);
1979 EXPECT_TRUE(g_TestResults.got_read);
1980 EXPECT_TRUE(g_TestResults.got_output);
1981 EXPECT_TRUE(g_TestResults.got_sub_request);
1982 EXPECT_TRUE(g_TestResults.got_sub_read);
1983 EXPECT_TRUE(g_TestResults.got_sub_success);
1984
1985 EXPECT_TRUE(CefClearCrossOriginWhitelist());
1986 WaitForUIThread();
1987
1988 ClearTestSchemes();
1989 }
1990
1991 // Test that a custom standard scheme can generate cross-domain Fetch requests
1992 // when using the cross-origin whitelist.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginWithWhitelist1)1993 TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithWhitelist1) {
1994 RegisterTestScheme("customstdfetch", "test1");
1995 RegisterTestScheme("customstdfetch", "test2");
1996
1997 FetchTestSettings settings;
1998 settings.url = "customstdfetch://test1/run.html";
1999 settings.sub_url = "customstdfetch://test2/fetch.html";
2000 SetUpFetch(settings);
2001
2002 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
2003 "customstdfetch://test1", "customstdfetch", "test2", false));
2004 WaitForUIThread();
2005
2006 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2007 handler->ExecuteTest();
2008 ReleaseAndWaitForDestructor(handler);
2009
2010 EXPECT_TRUE(g_TestResults.got_request);
2011 EXPECT_TRUE(g_TestResults.got_read);
2012 EXPECT_TRUE(g_TestResults.got_output);
2013 EXPECT_TRUE(g_TestResults.got_sub_request);
2014 EXPECT_TRUE(g_TestResults.got_sub_read);
2015 EXPECT_TRUE(g_TestResults.got_sub_success);
2016
2017 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2018 WaitForUIThread();
2019
2020 ClearTestSchemes();
2021 }
2022
2023 // Same as above but origin whitelist matches any domain.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginWithWhitelist2)2024 TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithWhitelist2) {
2025 RegisterTestScheme("customstdfetch", "test1");
2026 RegisterTestScheme("customstdfetch", "test2");
2027
2028 FetchTestSettings settings;
2029 settings.url = "customstdfetch://test1/run.html";
2030 settings.sub_url = "customstdfetch://test2/fetch.html";
2031 SetUpFetch(settings);
2032
2033 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
2034 "customstdfetch://test1", "customstdfetch", CefString(), true));
2035 WaitForUIThread();
2036
2037 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2038 handler->ExecuteTest();
2039 ReleaseAndWaitForDestructor(handler);
2040
2041 EXPECT_TRUE(g_TestResults.got_request);
2042 EXPECT_TRUE(g_TestResults.got_read);
2043 EXPECT_TRUE(g_TestResults.got_output);
2044 EXPECT_TRUE(g_TestResults.got_sub_request);
2045 EXPECT_TRUE(g_TestResults.got_sub_read);
2046 EXPECT_TRUE(g_TestResults.got_sub_success);
2047
2048 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2049 WaitForUIThread();
2050
2051 ClearTestSchemes();
2052 }
2053
2054 // Same as above but origin whitelist matches sub-domains.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginWithWhitelist3)2055 TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginWithWhitelist3) {
2056 RegisterTestScheme("customstdfetch", "test1");
2057 RegisterTestScheme("customstdfetch", "a.test2.foo");
2058
2059 FetchTestSettings settings;
2060 settings.url = "customstdfetch://test1/run.html";
2061 settings.sub_url = "customstdfetch://a.test2.foo/fetch.html";
2062 SetUpFetch(settings);
2063
2064 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
2065 "customstdfetch://test1", "customstdfetch", "test2.foo", true));
2066 WaitForUIThread();
2067
2068 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2069 handler->ExecuteTest();
2070 ReleaseAndWaitForDestructor(handler);
2071
2072 EXPECT_TRUE(g_TestResults.got_request);
2073 EXPECT_TRUE(g_TestResults.got_read);
2074 EXPECT_TRUE(g_TestResults.got_output);
2075 EXPECT_TRUE(g_TestResults.got_sub_request);
2076 EXPECT_TRUE(g_TestResults.got_sub_read);
2077 EXPECT_TRUE(g_TestResults.got_sub_success);
2078
2079 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2080 WaitForUIThread();
2081
2082 ClearTestSchemes();
2083 }
2084
2085 // Test that an HTTP scheme can generate cross-domain XHR requests when setting
2086 // the Access-Control-Allow-Origin header.
TEST(SchemeHandlerTest,HttpXHRDifferentOriginWithHeaderSync)2087 TEST(SchemeHandlerTest, HttpXHRDifferentOriginWithHeaderSync) {
2088 RegisterTestScheme("http", "test1");
2089 RegisterTestScheme("http", "test2");
2090
2091 XHRTestSettings settings;
2092 settings.url = "http://test1/run.html";
2093 settings.sub_url = "http://test2/xhr.html";
2094 settings.sub_allow_origin = "http://test1";
2095 SetUpXHR(settings);
2096
2097 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2098 handler->ExecuteTest();
2099 ReleaseAndWaitForDestructor(handler);
2100
2101 EXPECT_TRUE(g_TestResults.got_request);
2102 EXPECT_TRUE(g_TestResults.got_read);
2103 EXPECT_TRUE(g_TestResults.got_output);
2104 EXPECT_TRUE(g_TestResults.got_sub_request);
2105 EXPECT_TRUE(g_TestResults.got_sub_read);
2106 EXPECT_TRUE(g_TestResults.got_sub_success);
2107
2108 ClearTestSchemes();
2109 }
2110
2111 // Test that an HTTP scheme can generate cross-domain XHR requests when setting
2112 // the Access-Control-Allow-Origin header.
TEST(SchemeHandlerTest,HttpXHRDifferentOriginWithHeaderAsync)2113 TEST(SchemeHandlerTest, HttpXHRDifferentOriginWithHeaderAsync) {
2114 RegisterTestScheme("http", "test1");
2115 RegisterTestScheme("http", "test2");
2116
2117 XHRTestSettings settings;
2118 settings.url = "http://test1/run.html";
2119 settings.sub_url = "http://test2/xhr.html";
2120 settings.sub_allow_origin = "http://test1";
2121 settings.synchronous = false;
2122 SetUpXHR(settings);
2123
2124 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2125 handler->ExecuteTest();
2126 ReleaseAndWaitForDestructor(handler);
2127
2128 EXPECT_TRUE(g_TestResults.got_request);
2129 EXPECT_TRUE(g_TestResults.got_read);
2130 EXPECT_TRUE(g_TestResults.got_output);
2131 EXPECT_TRUE(g_TestResults.got_sub_request);
2132 EXPECT_TRUE(g_TestResults.got_sub_read);
2133 EXPECT_TRUE(g_TestResults.got_sub_success);
2134
2135 ClearTestSchemes();
2136 }
2137
2138 // Test that an HTTP scheme can generate cross-domain XHR requests when setting
2139 // the Access-Control-Allow-Origin header.
TEST(SchemeHandlerTest,HttpFetchDifferentOriginWithHeader)2140 TEST(SchemeHandlerTest, HttpFetchDifferentOriginWithHeader) {
2141 RegisterTestScheme("http", "test1");
2142 RegisterTestScheme("http", "test2");
2143
2144 FetchTestSettings settings;
2145 settings.url = "http://test1/run.html";
2146 settings.sub_url = "http://test2/fetch.html";
2147 settings.sub_allow_origin = "http://test1";
2148 SetUpFetch(settings);
2149
2150 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2151 handler->ExecuteTest();
2152 ReleaseAndWaitForDestructor(handler);
2153
2154 EXPECT_TRUE(g_TestResults.got_request);
2155 EXPECT_TRUE(g_TestResults.got_read);
2156 EXPECT_TRUE(g_TestResults.got_output);
2157 EXPECT_TRUE(g_TestResults.got_sub_request);
2158 EXPECT_TRUE(g_TestResults.got_sub_read);
2159 EXPECT_TRUE(g_TestResults.got_sub_success);
2160
2161 ClearTestSchemes();
2162 }
2163
2164 // Test that a custom standard scheme can generate cross-domain XSS requests
2165 // when using document.domain.
TEST(SchemeHandlerTest,CustomStandardXSSDifferentOriginWithDomain)2166 TEST(SchemeHandlerTest, CustomStandardXSSDifferentOriginWithDomain) {
2167 RegisterTestScheme("customstd", "a.test.com");
2168 RegisterTestScheme("customstd", "b.test.com");
2169 SetUpXSS("customstd://a.test.com/run.html",
2170 "customstd://b.test.com/iframe.html", "test.com");
2171
2172 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2173 handler->ExecuteTest();
2174 ReleaseAndWaitForDestructor(handler);
2175
2176 EXPECT_TRUE(g_TestResults.got_request);
2177 EXPECT_TRUE(g_TestResults.got_read);
2178 EXPECT_TRUE(g_TestResults.got_output);
2179 EXPECT_TRUE(g_TestResults.got_sub_request);
2180 EXPECT_TRUE(g_TestResults.got_sub_read);
2181 EXPECT_TRUE(g_TestResults.got_sub_success);
2182
2183 ClearTestSchemes();
2184 }
2185
2186 // Test that an HTTP scheme can generate cross-domain XSS requests when using
2187 // document.domain.
TEST(SchemeHandlerTest,HttpXSSDifferentOriginWithDomain)2188 TEST(SchemeHandlerTest, HttpXSSDifferentOriginWithDomain) {
2189 RegisterTestScheme("http", "a.test.com");
2190 RegisterTestScheme("http", "b.test.com");
2191 SetUpXSS("http://a.test.com/run.html", "http://b.test.com/iframe.html",
2192 "test.com");
2193
2194 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2195 handler->ExecuteTest();
2196 ReleaseAndWaitForDestructor(handler);
2197
2198 EXPECT_TRUE(g_TestResults.got_request);
2199 EXPECT_TRUE(g_TestResults.got_read);
2200 EXPECT_TRUE(g_TestResults.got_output);
2201 EXPECT_TRUE(g_TestResults.got_sub_request);
2202 EXPECT_TRUE(g_TestResults.got_sub_read);
2203 EXPECT_TRUE(g_TestResults.got_sub_success);
2204
2205 ClearTestSchemes();
2206 }
2207
2208 // Test that a custom standard scheme cannot generate cross-domain XHR requests
2209 // that perform redirects.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginRedirectSync)2210 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginRedirectSync) {
2211 RegisterTestScheme("customstd", "test1");
2212 RegisterTestScheme("customstd", "test2");
2213
2214 XHRTestSettings settings;
2215 settings.url = "customstd://test1/run.html";
2216 settings.sub_url = "customstd://test2/xhr.html";
2217 settings.sub_redirect_url = "customstd://test1/xhr.html";
2218 SetUpXHR(settings);
2219
2220 g_TestResults.console_messages.push_back(
2221 "Access to XMLHttpRequest at 'customstd://test2/xhr.html' (redirected "
2222 "from 'customstd://test1/xhr.html') from origin 'customstd://test1' has "
2223 "been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is "
2224 "present on the requested resource.");
2225
2226 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2227 handler->ExecuteTest();
2228 ReleaseAndWaitForDestructor(handler);
2229
2230 EXPECT_TRUE(g_TestResults.got_request);
2231 EXPECT_TRUE(g_TestResults.got_read);
2232 EXPECT_TRUE(g_TestResults.got_output);
2233 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2234 EXPECT_TRUE(g_TestResults.got_sub_request);
2235 EXPECT_FALSE(g_TestResults.got_sub_read);
2236 EXPECT_FALSE(g_TestResults.got_sub_success);
2237
2238 ClearTestSchemes();
2239 }
2240
2241 // Test that a custom standard scheme cannot generate cross-domain XHR requests
2242 // that perform redirects.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginRedirectAsync)2243 TEST(SchemeHandlerTest, CustomStandardXHRDifferentOriginRedirectAsync) {
2244 RegisterTestScheme("customstd", "test1");
2245 RegisterTestScheme("customstd", "test2");
2246
2247 XHRTestSettings settings;
2248 settings.url = "customstd://test1/run.html";
2249 settings.sub_url = "customstd://test2/xhr.html";
2250 settings.sub_redirect_url = "customstd://test1/xhr.html";
2251 settings.synchronous = false;
2252 SetUpXHR(settings);
2253
2254 g_TestResults.console_messages.push_back(
2255 "Access to XMLHttpRequest at 'customstd://test2/xhr.html' (redirected "
2256 "from 'customstd://test1/xhr.html') from origin 'customstd://test1' has "
2257 "been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is "
2258 "present on the requested resource.");
2259
2260 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2261 handler->ExecuteTest();
2262 ReleaseAndWaitForDestructor(handler);
2263
2264 EXPECT_TRUE(g_TestResults.got_request);
2265 EXPECT_TRUE(g_TestResults.got_read);
2266 EXPECT_TRUE(g_TestResults.got_output);
2267 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2268 EXPECT_TRUE(g_TestResults.got_sub_request);
2269 EXPECT_FALSE(g_TestResults.got_sub_read);
2270 EXPECT_FALSE(g_TestResults.got_sub_success);
2271
2272 ClearTestSchemes();
2273 }
2274
2275 // Test that a custom standard scheme cannot generate cross-domain Fetch
2276 // requests that perform redirects.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginRedirect)2277 TEST(SchemeHandlerTest, CustomStandardFetchDifferentOriginRedirect) {
2278 RegisterTestScheme("customstdfetch", "test1");
2279 RegisterTestScheme("customstdfetch", "test2");
2280
2281 FetchTestSettings settings;
2282 settings.url = "customstdfetch://test1/run.html";
2283 settings.sub_url = "customstdfetch://test2/fetch.html";
2284 settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
2285 SetUpFetch(settings);
2286
2287 g_TestResults.console_messages.push_back(
2288 "Access to fetch at 'customstdfetch://test2/fetch.html' (redirected from "
2289 "'customstdfetch://test1/fetch.html') from origin "
2290 "'customstdfetch://test1' has been blocked by CORS policy: No "
2291 "'Access-Control-Allow-Origin' header is present on the requested "
2292 "resource. If an opaque response serves your needs, set the request's "
2293 "mode to 'no-cors' to fetch the resource with CORS disabled.");
2294
2295 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2296 handler->ExecuteTest();
2297 ReleaseAndWaitForDestructor(handler);
2298
2299 EXPECT_TRUE(g_TestResults.got_request);
2300 EXPECT_TRUE(g_TestResults.got_read);
2301 EXPECT_TRUE(g_TestResults.got_output);
2302 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2303 EXPECT_TRUE(g_TestResults.got_sub_request);
2304 EXPECT_FALSE(g_TestResults.got_sub_read);
2305 EXPECT_FALSE(g_TestResults.got_sub_success);
2306
2307 ClearTestSchemes();
2308 }
2309
2310 // Test that a custom standard scheme can generate cross-domain XHR requests
2311 // that perform redirects when using the cross-origin whitelist.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginRedirectWithWhitelistSync)2312 TEST(SchemeHandlerTest,
2313 CustomStandardXHRDifferentOriginRedirectWithWhitelistSync) {
2314 RegisterTestScheme("customstd", "test1");
2315 RegisterTestScheme("customstd", "test2");
2316
2317 XHRTestSettings settings;
2318 settings.url = "customstd://test1/run.html";
2319 settings.sub_url = "customstd://test2/xhr.html";
2320 settings.sub_redirect_url = "customstd://test1/xhr.html";
2321 SetUpXHR(settings);
2322
2323 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
2324 "test2", false));
2325 WaitForUIThread();
2326
2327 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2328 handler->ExecuteTest();
2329 ReleaseAndWaitForDestructor(handler);
2330
2331 EXPECT_TRUE(g_TestResults.got_request);
2332 EXPECT_TRUE(g_TestResults.got_read);
2333 EXPECT_TRUE(g_TestResults.got_output);
2334 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2335 EXPECT_TRUE(g_TestResults.got_sub_request);
2336 EXPECT_TRUE(g_TestResults.got_sub_read);
2337 EXPECT_TRUE(g_TestResults.got_sub_success);
2338
2339 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2340 WaitForUIThread();
2341
2342 ClearTestSchemes();
2343 }
2344
2345 // Test that a custom standard scheme can generate cross-domain XHR requests
2346 // that perform redirects when using the cross-origin whitelist.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync1)2347 TEST(SchemeHandlerTest,
2348 CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync1) {
2349 RegisterTestScheme("customstd", "test1");
2350 RegisterTestScheme("customstd", "test2");
2351
2352 XHRTestSettings settings;
2353 settings.url = "customstd://test1/run.html";
2354 settings.sub_url = "customstd://test2/xhr.html";
2355 settings.sub_redirect_url = "customstd://test1/xhr.html";
2356 settings.synchronous = false;
2357 SetUpXHR(settings);
2358
2359 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
2360 "test2", false));
2361 WaitForUIThread();
2362
2363 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2364 handler->ExecuteTest();
2365 ReleaseAndWaitForDestructor(handler);
2366
2367 EXPECT_TRUE(g_TestResults.got_request);
2368 EXPECT_TRUE(g_TestResults.got_read);
2369 EXPECT_TRUE(g_TestResults.got_output);
2370 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2371 EXPECT_TRUE(g_TestResults.got_sub_request);
2372 EXPECT_TRUE(g_TestResults.got_sub_read);
2373 EXPECT_TRUE(g_TestResults.got_sub_success);
2374
2375 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2376 WaitForUIThread();
2377
2378 ClearTestSchemes();
2379 }
2380
2381 // Same as above but origin whitelist matches any domain.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync2)2382 TEST(SchemeHandlerTest,
2383 CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync2) {
2384 RegisterTestScheme("customstd", "test1");
2385 RegisterTestScheme("customstd", "test2");
2386
2387 XHRTestSettings settings;
2388 settings.url = "customstd://test1/run.html";
2389 settings.sub_url = "customstd://test2/xhr.html";
2390 settings.sub_redirect_url = "customstd://test1/xhr.html";
2391 settings.synchronous = false;
2392 SetUpXHR(settings);
2393
2394 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
2395 CefString(), true));
2396 WaitForUIThread();
2397
2398 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2399 handler->ExecuteTest();
2400 ReleaseAndWaitForDestructor(handler);
2401
2402 EXPECT_TRUE(g_TestResults.got_request);
2403 EXPECT_TRUE(g_TestResults.got_read);
2404 EXPECT_TRUE(g_TestResults.got_output);
2405 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2406 EXPECT_TRUE(g_TestResults.got_sub_request);
2407 EXPECT_TRUE(g_TestResults.got_sub_read);
2408 EXPECT_TRUE(g_TestResults.got_sub_success);
2409
2410 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2411 WaitForUIThread();
2412
2413 ClearTestSchemes();
2414 }
2415
2416 // Same as above but origin whitelist matches sub-domains.
TEST(SchemeHandlerTest,CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync3)2417 TEST(SchemeHandlerTest,
2418 CustomStandardXHRDifferentOriginRedirectWithWhitelistAsync3) {
2419 RegisterTestScheme("customstd", "test1");
2420 RegisterTestScheme("customstd", "a.test2.foo");
2421
2422 XHRTestSettings settings;
2423 settings.url = "customstd://test1/run.html";
2424 settings.sub_url = "customstd://a.test2.foo/xhr.html";
2425 settings.sub_redirect_url = "customstd://test1/xhr.html";
2426 settings.synchronous = false;
2427 SetUpXHR(settings);
2428
2429 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry("customstd://test1", "customstd",
2430 "test2.foo", true));
2431 WaitForUIThread();
2432
2433 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2434 handler->ExecuteTest();
2435 ReleaseAndWaitForDestructor(handler);
2436
2437 EXPECT_TRUE(g_TestResults.got_request);
2438 EXPECT_TRUE(g_TestResults.got_read);
2439 EXPECT_TRUE(g_TestResults.got_output);
2440 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2441 EXPECT_TRUE(g_TestResults.got_sub_request);
2442 EXPECT_TRUE(g_TestResults.got_sub_read);
2443 EXPECT_TRUE(g_TestResults.got_sub_success);
2444
2445 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2446 WaitForUIThread();
2447
2448 ClearTestSchemes();
2449 }
2450
2451 // Test that a custom standard scheme can generate cross-domain Fetch requests
2452 // that perform redirects when using the cross-origin whitelist.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginRedirectWithWhitelist1)2453 TEST(SchemeHandlerTest,
2454 CustomStandardFetchDifferentOriginRedirectWithWhitelist1) {
2455 RegisterTestScheme("customstdfetch", "test1");
2456 RegisterTestScheme("customstdfetch", "test2");
2457
2458 FetchTestSettings settings;
2459 settings.url = "customstdfetch://test1/run.html";
2460 settings.sub_url = "customstdfetch://test2/fetch.html";
2461 settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
2462 SetUpFetch(settings);
2463
2464 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
2465 "customstdfetch://test1", "customstdfetch", "test2", false));
2466 WaitForUIThread();
2467
2468 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2469 handler->ExecuteTest();
2470 ReleaseAndWaitForDestructor(handler);
2471
2472 EXPECT_TRUE(g_TestResults.got_request);
2473 EXPECT_TRUE(g_TestResults.got_read);
2474 EXPECT_TRUE(g_TestResults.got_output);
2475 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2476 EXPECT_TRUE(g_TestResults.got_sub_request);
2477 EXPECT_TRUE(g_TestResults.got_sub_read);
2478 EXPECT_TRUE(g_TestResults.got_sub_success);
2479
2480 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2481 WaitForUIThread();
2482
2483 ClearTestSchemes();
2484 }
2485
2486 // Same as above but origin whitelist matches any domain.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginRedirectWithWhitelist2)2487 TEST(SchemeHandlerTest,
2488 CustomStandardFetchDifferentOriginRedirectWithWhitelist2) {
2489 RegisterTestScheme("customstdfetch", "test1");
2490 RegisterTestScheme("customstdfetch", "test2");
2491
2492 FetchTestSettings settings;
2493 settings.url = "customstdfetch://test1/run.html";
2494 settings.sub_url = "customstdfetch://test2/fetch.html";
2495 settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
2496 SetUpFetch(settings);
2497
2498 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
2499 "customstdfetch://test1", "customstdfetch", CefString(), true));
2500 WaitForUIThread();
2501
2502 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2503 handler->ExecuteTest();
2504 ReleaseAndWaitForDestructor(handler);
2505
2506 EXPECT_TRUE(g_TestResults.got_request);
2507 EXPECT_TRUE(g_TestResults.got_read);
2508 EXPECT_TRUE(g_TestResults.got_output);
2509 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2510 EXPECT_TRUE(g_TestResults.got_sub_request);
2511 EXPECT_TRUE(g_TestResults.got_sub_read);
2512 EXPECT_TRUE(g_TestResults.got_sub_success);
2513
2514 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2515 WaitForUIThread();
2516
2517 ClearTestSchemes();
2518 }
2519
2520 // Same as above but origin whitelist matches sub-domains.
TEST(SchemeHandlerTest,CustomStandardFetchDifferentOriginRedirectWithWhitelist3)2521 TEST(SchemeHandlerTest,
2522 CustomStandardFetchDifferentOriginRedirectWithWhitelist3) {
2523 RegisterTestScheme("customstdfetch", "test1");
2524 RegisterTestScheme("customstdfetch", "a.test2.foo");
2525
2526 FetchTestSettings settings;
2527 settings.url = "customstdfetch://test1/run.html";
2528 settings.sub_url = "customstdfetch://a.test2.foo/fetch.html";
2529 settings.sub_redirect_url = "customstdfetch://test1/fetch.html";
2530 SetUpFetch(settings);
2531
2532 EXPECT_TRUE(CefAddCrossOriginWhitelistEntry(
2533 "customstdfetch://test1", "customstdfetch", "test2.foo", true));
2534 WaitForUIThread();
2535
2536 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2537 handler->ExecuteTest();
2538 ReleaseAndWaitForDestructor(handler);
2539
2540 EXPECT_TRUE(g_TestResults.got_request);
2541 EXPECT_TRUE(g_TestResults.got_read);
2542 EXPECT_TRUE(g_TestResults.got_output);
2543 EXPECT_TRUE(g_TestResults.got_sub_redirect);
2544 EXPECT_TRUE(g_TestResults.got_sub_request);
2545 EXPECT_TRUE(g_TestResults.got_sub_read);
2546 EXPECT_TRUE(g_TestResults.got_sub_success);
2547
2548 EXPECT_TRUE(CefClearCrossOriginWhitelist());
2549 WaitForUIThread();
2550
2551 ClearTestSchemes();
2552 }
2553
2554 // Test per-browser setting of Accept-Language.
TEST(SchemeHandlerTest,AcceptLanguage)2555 TEST(SchemeHandlerTest, AcceptLanguage) {
2556 RegisterTestScheme("customstd", "test");
2557 g_TestResults.url = "customstd://test/run.html";
2558 g_TestResults.html =
2559 "<html><head></head><body><h1>Success!</h1></body></html>";
2560
2561 // Value that will be set via CefBrowserSettings.accept_language in
2562 // PopulateBrowserSettings().
2563 g_TestResults.accept_language = "uk";
2564
2565 CefRefPtr<TestSchemeHandler> handler = new TestSchemeHandler(&g_TestResults);
2566 handler->ExecuteTest();
2567 ReleaseAndWaitForDestructor(handler);
2568
2569 EXPECT_TRUE(g_TestResults.got_request);
2570 EXPECT_TRUE(g_TestResults.got_read);
2571 EXPECT_TRUE(g_TestResults.got_output);
2572
2573 ClearTestSchemes();
2574 }
2575
2576 // Entry point for registering custom schemes.
2577 // Called from client_app_delegates.cc.
RegisterSchemeHandlerCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar)2578 void RegisterSchemeHandlerCustomSchemes(
2579 CefRawPtr<CefSchemeRegistrar> registrar) {
2580 // Registering the custom standard schemes as secure because requests from
2581 // non-secure origins to the loopback address will be blocked by
2582 // https://chromestatus.com/feature/5436853517811712.
2583
2584 // Add a custom standard scheme.
2585 registrar->AddCustomScheme("customstd", CEF_SCHEME_OPTION_STANDARD |
2586 CEF_SCHEME_OPTION_SECURE |
2587 CEF_SCHEME_OPTION_CORS_ENABLED);
2588 // Also used in cors_unittest.cc.
2589 registrar->AddCustomScheme(
2590 "customstdfetch", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_SECURE |
2591 CEF_SCHEME_OPTION_CORS_ENABLED |
2592 CEF_SCHEME_OPTION_FETCH_ENABLED);
2593 // Add a custom non-standard scheme.
2594 registrar->AddCustomScheme("customnonstd", CEF_SCHEME_OPTION_NONE);
2595 registrar->AddCustomScheme("customnonstdfetch",
2596 CEF_SCHEME_OPTION_FETCH_ENABLED);
2597 }
2598
2599 // Entry point for registering cookieable schemes.
2600 // Called from client_app_delegates.cc.
RegisterSchemeHandlerCookieableSchemes(std::vector<std::string> & cookieable_schemes)2601 void RegisterSchemeHandlerCookieableSchemes(
2602 std::vector<std::string>& cookieable_schemes) {
2603 cookieable_schemes.push_back("customstd");
2604 // Also used in cors_unittest.cc.
2605 cookieable_schemes.push_back("customstdfetch");
2606 }
2607