Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(472)

Side by Side Diff: extensions/browser/api/web_request/web_request_api.cc

Issue 2449913002: Support WebSocket in WebRequest API. (Closed)
Patch Set: Fix unittest; add 'websocket' type to WebRequest API. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/api/web_request/web_request_api.h" 5 #include "extensions/browser/api/web_request/web_request_api.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 // Returns true if we're in a Public Session. 343 // Returns true if we're in a Public Session.
344 bool IsPublicSession() { 344 bool IsPublicSession() {
345 #if defined(OS_CHROMEOS) 345 #if defined(OS_CHROMEOS)
346 if (chromeos::LoginState::IsInitialized()) { 346 if (chromeos::LoginState::IsInitialized()) {
347 return chromeos::LoginState::Get()->IsPublicSessionUser(); 347 return chromeos::LoginState::Get()->IsPublicSessionUser();
348 } 348 }
349 #endif 349 #endif
350 return false; 350 return false;
351 } 351 }
352 352
353 // Returns event details for a given request.
354 std::unique_ptr<WebRequestEventDetails> CreateEventDetails(
355 const net::URLRequest* request,
356 int extra_info_spec) {
357 return base::MakeUnique<WebRequestEventDetails>(request, extra_info_spec);
358 }
359
353 } // namespace 360 } // namespace
354 361
355 WebRequestAPI::WebRequestAPI(content::BrowserContext* context) 362 WebRequestAPI::WebRequestAPI(content::BrowserContext* context)
356 : browser_context_(context) { 363 : browser_context_(context) {
357 EventRouter* event_router = EventRouter::Get(browser_context_); 364 EventRouter* event_router = EventRouter::Get(browser_context_);
358 for (size_t i = 0; i < arraysize(kWebRequestEvents); ++i) { 365 for (size_t i = 0; i < arraysize(kWebRequestEvents); ++i) {
359 // Observe the webRequest event. 366 // Observe the webRequest event.
360 std::string event_name = kWebRequestEvents[i]; 367 std::string event_name = kWebRequestEvents[i];
361 event_router->RegisterObserver(this, event_name); 368 event_router->RegisterObserver(this, event_name);
362 369
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (!value.HasKey("urls")) 491 if (!value.HasKey("urls"))
485 return false; 492 return false;
486 493
487 for (base::DictionaryValue::Iterator it(value); !it.IsAtEnd(); it.Advance()) { 494 for (base::DictionaryValue::Iterator it(value); !it.IsAtEnd(); it.Advance()) {
488 if (it.key() == "urls") { 495 if (it.key() == "urls") {
489 const base::ListValue* urls_value = NULL; 496 const base::ListValue* urls_value = NULL;
490 if (!it.value().GetAsList(&urls_value)) 497 if (!it.value().GetAsList(&urls_value))
491 return false; 498 return false;
492 for (size_t i = 0; i < urls_value->GetSize(); ++i) { 499 for (size_t i = 0; i < urls_value->GetSize(); ++i) {
493 std::string url; 500 std::string url;
494 URLPattern pattern( 501 URLPattern pattern(URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS |
495 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS | 502 URLPattern::SCHEME_FTP | URLPattern::SCHEME_FILE |
496 URLPattern::SCHEME_FTP | URLPattern::SCHEME_FILE | 503 URLPattern::SCHEME_EXTENSION |
497 URLPattern::SCHEME_EXTENSION); 504 URLPattern::SCHEME_WS | URLPattern::SCHEME_WSS);
498 if (!urls_value->GetString(i, &url) || 505 if (!urls_value->GetString(i, &url) ||
499 pattern.Parse(url) != URLPattern::PARSE_SUCCESS) { 506 pattern.Parse(url) != URLPattern::PARSE_SUCCESS) {
500 *error = ErrorUtils::FormatErrorMessage( 507 *error = ErrorUtils::FormatErrorMessage(
501 keys::kInvalidRequestFilterUrl, url); 508 keys::kInvalidRequestFilterUrl, url);
502 return false; 509 return false;
503 } 510 }
504 urls.AddPattern(pattern); 511 urls.AddPattern(pattern);
505 } 512 }
506 } else if (it.key() == "types") { 513 } else if (it.key() == "types") {
507 const base::ListValue* types_value = NULL; 514 const base::ListValue* types_value = NULL;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 void* browser_context, 575 void* browser_context,
569 int rules_registry_id, 576 int rules_registry_id,
570 scoped_refptr<WebRequestRulesRegistry> rules_registry) { 577 scoped_refptr<WebRequestRulesRegistry> rules_registry) {
571 RulesRegistryKey key(browser_context, rules_registry_id); 578 RulesRegistryKey key(browser_context, rules_registry_id);
572 if (rules_registry.get()) 579 if (rules_registry.get())
573 rules_registries_[key] = rules_registry; 580 rules_registries_[key] = rules_registry;
574 else 581 else
575 rules_registries_.erase(key); 582 rules_registries_.erase(key);
576 } 583 }
577 584
578 std::unique_ptr<WebRequestEventDetails>
579 ExtensionWebRequestEventRouter::CreateEventDetails(
580 const net::URLRequest* request,
581 int extra_info_spec) {
582 std::unique_ptr<WebRequestEventDetails> event_details(
583 new WebRequestEventDetails(request, extra_info_spec));
584
585 return event_details;
586 }
587
588 int ExtensionWebRequestEventRouter::OnBeforeRequest( 585 int ExtensionWebRequestEventRouter::OnBeforeRequest(
589 void* browser_context, 586 void* browser_context,
590 const InfoMap* extension_info_map, 587 const InfoMap* extension_info_map,
591 net::URLRequest* request, 588 net::URLRequest* request,
592 const net::CompletionCallback& callback, 589 const net::CompletionCallback& callback,
593 GURL* new_url) { 590 GURL* new_url) {
594 ExtensionNavigationUIData* navigation_ui_data = 591 ExtensionNavigationUIData* navigation_ui_data =
595 ExtensionsBrowserClient::Get()->GetExtensionNavigationUIData(request); 592 ExtensionsBrowserClient::Get()->GetExtensionNavigationUIData(request);
596 if (ShouldHideEvent(browser_context, extension_info_map, request, 593 if (ShouldHideEvent(browser_context, extension_info_map, request,
597 navigation_ui_data)) { 594 navigation_ui_data)) {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 if (!browser_context || 930 if (!browser_context ||
934 (WebRequestPermissions::HideRequest(extension_info_map, request, 931 (WebRequestPermissions::HideRequest(extension_info_map, request,
935 navigation_ui_data) && 932 navigation_ui_data) &&
936 !WasSignaled(*request))) { 933 !WasSignaled(*request))) {
937 return; 934 return;
938 } 935 }
939 936
940 request_time_tracker_->LogRequestEndTime(request->identifier(), 937 request_time_tracker_->LogRequestEndTime(request->identifier(),
941 base::Time::Now()); 938 base::Time::Now());
942 939
943 DCHECK_EQ(net::OK, net_error); 940 DCHECK(net_error == net::OK || net_error == net::ERR_WS_UPGRADE);
944 941
945 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 942 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted));
946 943
947 ClearPendingCallbacks(request); 944 ClearPendingCallbacks(request);
948 945
949 int extra_info_spec = 0; 946 int extra_info_spec = 0;
950 RawListeners listeners = GetMatchingListeners( 947 RawListeners listeners = GetMatchingListeners(
951 browser_context, extension_info_map, navigation_ui_data, 948 browser_context, extension_info_map, navigation_ui_data,
952 keys::kOnCompletedEvent, request, &extra_info_spec); 949 keys::kOnCompletedEvent, request, &extra_info_spec);
953 if (listeners.empty()) 950 if (listeners.empty())
(...skipping 17 matching lines...) Expand all
971 OnCompleted(browser_context, extension_info_map, request, 968 OnCompleted(browser_context, extension_info_map, request,
972 request->status().error()); 969 request->status().error());
973 } 970 }
974 971
975 void ExtensionWebRequestEventRouter::OnErrorOccurred( 972 void ExtensionWebRequestEventRouter::OnErrorOccurred(
976 void* browser_context, 973 void* browser_context,
977 const InfoMap* extension_info_map, 974 const InfoMap* extension_info_map,
978 net::URLRequest* request, 975 net::URLRequest* request,
979 bool started, 976 bool started,
980 int net_error) { 977 int net_error) {
978 // When WebSocket handshake request finishes, URLRequest is cancelled with an
979 // ERR_WS_UPGRADE code (see WebSocketStreamRequestImpl::PerformUpgrade).
980 // WebRequest API reports this as a completed request.
981 if (net_error == net::ERR_WS_UPGRADE) {
982 OnCompleted(browser_context, extension_info_map, request, net_error);
983 return;
984 }
985
981 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); 986 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get();
982 if (!client) { 987 if (!client) {
983 // |client| could be NULL during shutdown. 988 // |client| could be NULL during shutdown.
984 return; 989 return;
985 } 990 }
986 ExtensionNavigationUIData* navigation_ui_data = 991 ExtensionNavigationUIData* navigation_ui_data =
987 client->GetExtensionNavigationUIData(request); 992 client->GetExtensionNavigationUIData(request);
988 // We hide events from the system context as well as sensitive requests. 993 // We hide events from the system context as well as sensitive requests.
989 // However, if the request first became sensitive after redirecting we have 994 // However, if the request first became sensitive after redirecting we have
990 // already signaled it and thus we have to signal the end of it. This is 995 // already signaled it and thus we have to signal the end of it. This is
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 } 1331 }
1327 1332
1328 void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( 1333 void ExtensionWebRequestEventRouter::AddCallbackForPageLoad(
1329 const base::Closure& callback) { 1334 const base::Closure& callback) {
1330 callbacks_for_page_load_.push_back(callback); 1335 callbacks_for_page_load_.push_back(callback);
1331 } 1336 }
1332 1337
1333 bool ExtensionWebRequestEventRouter::IsPageLoad( 1338 bool ExtensionWebRequestEventRouter::IsPageLoad(
1334 const net::URLRequest* request) const { 1339 const net::URLRequest* request) const {
1335 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1340 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
1336 if (!info) 1341 return info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
1337 return false;
1338
1339 return info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
1340 } 1342 }
1341 1343
1342 void ExtensionWebRequestEventRouter::NotifyPageLoad() { 1344 void ExtensionWebRequestEventRouter::NotifyPageLoad() {
1343 for (const auto& callback : callbacks_for_page_load_) 1345 for (const auto& callback : callbacks_for_page_load_)
1344 callback.Run(); 1346 callback.Run();
1345 callbacks_for_page_load_.clear(); 1347 callbacks_for_page_load_.clear();
1346 } 1348 }
1347 1349
1348 void* ExtensionWebRequestEventRouter::GetCrossBrowserContext( 1350 void* ExtensionWebRequestEventRouter::GetCrossBrowserContext(
1349 void* browser_context) const { 1351 void* browser_context) const {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 const std::string& event_name, 1507 const std::string& event_name,
1506 const net::URLRequest* request, 1508 const net::URLRequest* request,
1507 int* extra_info_spec) { 1509 int* extra_info_spec) {
1508 // TODO(mpcomplete): handle browser_context == NULL (should collect all 1510 // TODO(mpcomplete): handle browser_context == NULL (should collect all
1509 // listeners). 1511 // listeners).
1510 *extra_info_spec = 0; 1512 *extra_info_spec = 0;
1511 1513
1512 const GURL& url = request->url(); 1514 const GURL& url = request->url();
1513 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID; 1515 int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID;
1514 int routing_id = MSG_ROUTING_NONE; 1516 int routing_id = MSG_ROUTING_NONE;
1515 ResourceTypeExt resource_type; 1517 ResourceTypeExt resource_type(request->url().SchemeIsWSOrWSS());
1516 // We are conservative here and assume requests are asynchronous in case 1518 // We are conservative here and assume requests are asynchronous in case
1517 // we don't have an info object. We don't want to risk a deadlock. 1519 // we don't have an info object. We don't want to risk a deadlock.
1518 bool is_async_request = false; 1520 bool is_async_request = false;
1519 bool is_request_from_extension = 1521 bool is_request_from_extension =
1520 IsRequestFromExtension(request, extension_info_map); 1522 IsRequestFromExtension(request, extension_info_map);
1521 1523
1522 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1524 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
1523 if (info) { 1525 if (info) {
1524 is_async_request = info->IsAsync(); 1526 is_async_request = info->IsAsync();
1525 if (helpers::IsRelevantResourceType(info->GetResourceType())) 1527 if (!resource_type.is_websocket &&
1528 helpers::IsRelevantResourceType(info->GetResourceType())) {
1526 resource_type.resource_type = info->GetResourceType(); 1529 resource_type.resource_type = info->GetResourceType();
1530 }
1527 render_process_host_id = info->GetChildID(); 1531 render_process_host_id = info->GetChildID();
1528 routing_id = info->GetRouteID(); 1532 routing_id = info->GetRouteID();
1529 } 1533 }
1530 1534
1531 RawListeners matching_listeners; 1535 RawListeners matching_listeners;
1532 GetMatchingListenersImpl(browser_context, request, extension_info_map, 1536 GetMatchingListenersImpl(browser_context, request, extension_info_map,
1533 navigation_ui_data, false, event_name, url, 1537 navigation_ui_data, false, event_name, url,
1534 render_process_host_id, routing_id, resource_type, 1538 render_process_host_id, routing_id, resource_type,
1535 is_async_request, is_request_from_extension, 1539 is_async_request, is_request_from_extension,
1536 extra_info_spec, &matching_listeners); 1540 extra_info_spec, &matching_listeners);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); 1805 deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder);
1802 1806
1803 bool canceled = false; 1807 bool canceled = false;
1804 helpers::MergeCancelOfResponses(blocked_request.response_deltas, &canceled, 1808 helpers::MergeCancelOfResponses(blocked_request.response_deltas, &canceled,
1805 blocked_request.net_log); 1809 blocked_request.net_log);
1806 1810
1807 WarningSet warnings; 1811 WarningSet warnings;
1808 if (blocked_request.event == kOnBeforeRequest) { 1812 if (blocked_request.event == kOnBeforeRequest) {
1809 CHECK(!blocked_request.callback.is_null()); 1813 CHECK(!blocked_request.callback.is_null());
1810 helpers::MergeOnBeforeRequestResponses( 1814 helpers::MergeOnBeforeRequestResponses(
1811 blocked_request.response_deltas, 1815 blocked_request.request->url(), blocked_request.response_deltas,
1812 blocked_request.new_url, 1816 blocked_request.new_url, &warnings, blocked_request.net_log);
1813 &warnings,
1814 blocked_request.net_log);
1815 } else if (blocked_request.event == kOnBeforeSendHeaders) { 1817 } else if (blocked_request.event == kOnBeforeSendHeaders) {
1816 CHECK(!blocked_request.callback.is_null()); 1818 CHECK(!blocked_request.callback.is_null());
1817 helpers::MergeOnBeforeSendHeadersResponses( 1819 helpers::MergeOnBeforeSendHeadersResponses(
1818 blocked_request.response_deltas, 1820 blocked_request.response_deltas,
1819 blocked_request.request_headers, 1821 blocked_request.request_headers,
1820 &warnings, 1822 &warnings,
1821 blocked_request.net_log); 1823 blocked_request.net_log);
1822 } else if (blocked_request.event == kOnHeadersReceived) { 1824 } else if (blocked_request.event == kOnHeadersReceived) {
1823 CHECK(!blocked_request.callback.is_null()); 1825 CHECK(!blocked_request.callback.is_null());
1824 helpers::MergeOnHeadersReceivedResponses( 1826 helpers::MergeOnHeadersReceivedResponses(
1825 blocked_request.response_deltas, 1827 blocked_request.request->url(), blocked_request.response_deltas,
1826 blocked_request.original_response_headers.get(), 1828 blocked_request.original_response_headers.get(),
1827 blocked_request.override_response_headers, 1829 blocked_request.override_response_headers, blocked_request.new_url,
1828 blocked_request.new_url, 1830 &warnings, blocked_request.net_log);
1829 &warnings,
1830 blocked_request.net_log);
1831 } else if (blocked_request.event == kOnAuthRequired) { 1831 } else if (blocked_request.event == kOnAuthRequired) {
1832 CHECK(blocked_request.callback.is_null()); 1832 CHECK(blocked_request.callback.is_null());
1833 CHECK(!blocked_request.auth_callback.is_null()); 1833 CHECK(!blocked_request.auth_callback.is_null());
1834 credentials_set = helpers::MergeOnAuthRequiredResponses( 1834 credentials_set = helpers::MergeOnAuthRequiredResponses(
1835 blocked_request.response_deltas, 1835 blocked_request.response_deltas,
1836 blocked_request.auth_credentials, 1836 blocked_request.auth_credentials,
1837 &warnings, 1837 &warnings,
1838 blocked_request.net_log); 1838 blocked_request.net_log);
1839 } else { 1839 } else {
1840 NOTREACHED(); 1840 NOTREACHED();
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 // Since EventListeners are segmented by browser_context, check that 2390 // Since EventListeners are segmented by browser_context, check that
2391 // last, as it is exceedingly unlikely to be different. 2391 // last, as it is exceedingly unlikely to be different.
2392 return extension_id == that.extension_id && 2392 return extension_id == that.extension_id &&
2393 sub_event_name == that.sub_event_name && 2393 sub_event_name == that.sub_event_name &&
2394 web_view_instance_id == that.web_view_instance_id && 2394 web_view_instance_id == that.web_view_instance_id &&
2395 embedder_process_id == that.embedder_process_id && 2395 embedder_process_id == that.embedder_process_id &&
2396 browser_context == that.browser_context; 2396 browser_context == that.browser_context;
2397 } 2397 }
2398 2398
2399 } // namespace extensions 2399 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698