OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |