15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/lazy_instance.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_message_filter.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/render_frame_host.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h" 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/activity_log/web_request_constants.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/request_stage.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_rules_registry.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/extensions_api_client.h" 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/upload_data_presenter.h" 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api_constants.h" 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api_helpers.h" 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_event_router_delegate.h" 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_time_tracker.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "extensions/browser/extension_message_filter.h" 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extensions_browser_client.h" 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_constants.h" 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/info_map.h" 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/runtime_data.h" 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/warning_service.h" 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/warning_set.h" 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/api/web_request.h" 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h" 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/event_filtering_info.h" 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/features/feature.h" 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/url_pattern.h" 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/strings/grit/extensions_strings.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/http/http_util.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::DictionaryValue; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::ListValue; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringValue; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserMessageFilter; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ResourceRequestInfo; 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing content::ResourceType; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ErrorUtils; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::InfoMap; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Feature; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::RulesRegistryService; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing extensions::Warning; 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing extensions::WarningService; 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing extensions::WarningSet; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace activitylog = activity_log_web_request_constants; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace helpers = extension_web_request_api_helpers; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extension_web_request_api_constants; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace web_request = extensions::core_api::web_request; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace declarative_keys = extensions::declarative_webrequest_constants; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kWebRequestEventPrefix[] = "webRequest."; 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// List of all the webRequest events. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kWebRequestEvents[] = { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRedirectEvent, 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_request::OnBeforeRequest::kEventName, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeSendHeadersEvent, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnCompletedEvent, 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_request::OnErrorOccurred::kEventName, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnSendHeadersEvent, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnAuthRequiredEvent, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnResponseStartedEvent, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnHeadersReceivedEvent, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst size_t kWebRequestEventsLength = arraysize(kWebRequestEvents); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetRequestStageAsString( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionWebRequestEventRouter::EventTypes type) { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kInvalidEvent: 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "Invalid"; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeRequest: 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnBeforeRequest; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeSendHeaders: 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnBeforeSendHeaders; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnSendHeaders: 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnSendHeaders; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnHeadersReceived: 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnHeadersReceived; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeRedirect: 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnBeforeRedirect; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnAuthRequired: 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnAuthRequired; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnResponseStarted: 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnResponseStarted; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnErrorOccurred: 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnErrorOccurred; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnCompleted: 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnCompleted; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "Not reached"; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int GetFrameId(bool is_main_frame, int frame_id) { 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return is_main_frame ? 0 : frame_id; 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsWebRequestEvent(const std::string& event_name) { 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string web_request_event_name(event_name); 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (StartsWithASCII( 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch web_request_event_name, webview::kWebViewEventPrefix, true)) { 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch web_request_event_name.replace( 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 0, strlen(webview::kWebViewEventPrefix), kWebRequestEventPrefix); 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return std::find( 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kWebRequestEvents, 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kWebRequestEvents + kWebRequestEventsLength, 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_request_event_name) != (kWebRequestEvents + kWebRequestEventsLength); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns whether |request| has been triggered by an extension in 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |extension_info_map|. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsRequestFromExtension(const net::URLRequest* request, 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const InfoMap* extension_info_map) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |extension_info_map| is NULL for system-level requests. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_info_map) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this request was not created by the ResourceDispatcher, |info| is NULL. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All requests from extensions are created by the ResourceDispatcher. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_info_map->process_map().Contains(info->GetChildID()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtractRequestRoutingInfo(net::URLRequest* request, 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int* render_process_host_id, 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int* routing_id) { 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!request->GetUserData(NULL)) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *render_process_host_id = info->GetChildID(); 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *routing_id = info->GetRouteID(); 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Given a |request|, this function determines whether it originated from 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// a <webview> guest process or not. If it is from a <webview> guest process, 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// then |web_view_info| is returned with information about the instance ID 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// that uniquely identifies the <webview> and its embedder. 1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool GetWebViewInfo( 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::URLRequest* request, 1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) extensions::WebViewRendererState::WebViewInfo* web_view_info) { 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int render_process_host_id = -1; 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int routing_id = -1; 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExtractRequestRoutingInfo(request, &render_process_host_id, &routing_id); 1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return extensions::WebViewRendererState::GetInstance()-> 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetInfo(render_process_host_id, routing_id, web_view_info); 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtractRequestInfoDetails(net::URLRequest* request, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* is_main_frame, 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int* frame_id, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* parent_is_main_frame, 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int* parent_frame_id, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* render_process_host_id, 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* routing_id, 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType* resource_type) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request->GetUserData(NULL)) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *frame_id = info->GetRenderFrameID(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *is_main_frame = info->IsMainFrame(); 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *parent_frame_id = info->GetParentRenderFrameID(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *parent_is_main_frame = info->ParentIsMainFrame(); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *render_process_host_id = info->GetChildID(); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *routing_id = info->GetRouteID(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restrict the resource type to the values we care about. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (helpers::IsRelevantResourceType(info->GetResourceType())) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resource_type = info->GetResourceType(); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *resource_type = content::RESOURCE_TYPE_LAST_TYPE; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extracts the body from |request| and writes the data into |out|. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtractRequestInfoBody(const net::URLRequest* request, 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* out) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::UploadDataStream* upload_data = request->get_upload(); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!upload_data || 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (request->method() != "POST" && request->method() != "PUT")) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" . 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* requestBody = new base::DictionaryValue(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->Set(keys::kRequestBodyKey, requestBody); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the data presenters, ordered by how specific they are. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ParsedDataPresenter parsed_data_presenter(*request); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::RawDataPresenter raw_data_presenter; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::UploadDataPresenter* const presenters[] = { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parsed_data_presenter, // 1: any parseable forms? (Specific to forms.) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_data_presenter // 2: any data at all? (Non-specific.) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keys for the results of the corresponding presenters. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* const kKeys[] = { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kRequestBodyFormDataKey, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kRequestBodyRawKey 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ScopedVector<net::UploadElementReader>& readers = 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_data->element_readers(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool some_succeeded = false; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; !some_succeeded && i < arraysize(presenters); ++i) { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<net::UploadElementReader>::const_iterator reader; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (reader = readers.begin(); reader != readers.end(); ++reader) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) presenters[i]->FeedNext(**reader); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (presenters[i]->Succeeded()) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requestBody->Set(kKeys[i], presenters[i]->Result().release()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) some_succeeded = true; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!some_succeeded) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requestBody->SetString(keys::kRequestBodyErrorKey, "Unknown error."); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true if successful. 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool FromHeaderDictionary(const base::DictionaryValue* header_value, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* name, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* value) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_value->GetString(keys::kHeaderNameKey, name)) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require either a "value" or a "binaryValue" entry. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(header_value->HasKey(keys::kHeaderValueKey) ^ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_value->HasKey(keys::kHeaderBinaryValueKey))) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_value->HasKey(keys::kHeaderValueKey)) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_value->GetString(keys::kHeaderValueKey, value)) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (header_value->HasKey(keys::kHeaderBinaryValueKey)) { 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* list = NULL; 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!header_value->HasKey(keys::kHeaderBinaryValueKey)) { 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *value = ""; 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (!header_value->GetList(keys::kHeaderBinaryValueKey, &list) || 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !helpers::CharListToString(list, value)) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a list of HttpHeaders (see the extension API JSON). If |headers| is 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NULL, the list is empty. Ownership is passed to the caller. 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::ListValue* GetResponseHeadersList( 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::HttpResponseHeaders* headers) { 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* headers_value = new base::ListValue(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeaderLines(&iter, &name, &value)) 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers_value->Append(helpers::CreateHeaderDictionary(name, value)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return headers_value; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::ListValue* GetRequestHeadersList(const net::HttpRequestHeaders& headers) { 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* headers_value = new base::ListValue(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext(); ) 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci headers_value->Append( 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci helpers::CreateHeaderDictionary(it.name(), it.value())); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return headers_value; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates a base::StringValue with the status line of |headers|. If |headers| 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// is NULL, an empty string is returned. Ownership is passed to the caller. 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::StringValue* GetStatusLine(net::HttpResponseHeaders* headers) { 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new base::StringValue( 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers ? headers->GetStatusLine() : std::string()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RemoveEventListenerOnUI( 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context_id, 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& event_name, 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int process_id, 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id) { 322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::BrowserContext* browser_context = 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reinterpret_cast<content::BrowserContext*>(browser_context_id); 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext( 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context)) 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::EventRouter* event_router = 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::EventRouter::Get(browser_context); 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!event_router) 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost* process = 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost::FromID(process_id); 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!process) 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_router->RemoveEventListener(event_name, process, extension_id); 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Sends an event to subscribers of chrome.declarativeWebRequest.onMessage or 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// to subscribers of webview.onMessage if the action is being operated upon 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// a <webview> guest renderer. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |extension_id| identifies the extension that sends and receives the event. 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |is_web_view_guest| indicates whether the action is for a <webview>. 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |web_view_info| is a struct containing information about the <webview> 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// embedder. 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |event_argument| is passed to the event listener. 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SendOnMessageEventOnUI( 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context_id, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_web_view_guest, 3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const extensions::WebViewRendererState::WebViewInfo& web_view_info, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> event_argument) { 357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::BrowserContext* browser_context = 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reinterpret_cast<content::BrowserContext*>(browser_context_id); 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext( 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context)) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> event_args(new base::ListValue); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_args->Append(event_argument.release()); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::EventRouter* event_router = 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::EventRouter::Get(browser_context); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::EventFilteringInfo event_filtering_info; 372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string event_name; 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The instance ID uniquely identifies a <webview> instance within an embedder 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // process. We use a filter here so that only event listeners for a particular 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // <webview> will fire. 377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (is_web_view_guest) { 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) event_filtering_info.SetInstanceID(web_view_info.instance_id); 379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event_name = webview::kEventMessage; 380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event_name = declarative_keys::kOnMessage; 382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<extensions::Event> event(new extensions::Event( 385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event_name, 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event_args.Pass(), browser_context, GURL(), 387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::EventRouter::USER_GESTURE_UNKNOWN, 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) event_filtering_info)); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_router->DispatchEventToExtension(extension_id, event.Pass()); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RemoveEventListenerOnIOThread( 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* browser_context, 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& extension_id, 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& sub_event_name) { 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context, extension_id, sub_event_name); 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebRequestAPI::WebRequestAPI(content::BrowserContext* context) 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : browser_context_(context) { 4060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter* event_router = EventRouter::Get(browser_context_); 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < arraysize(kWebRequestEvents); ++i) { 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Observe the webRequest event. 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string event_name = kWebRequestEvents[i]; 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_router->RegisterObserver(this, event_name); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Also observe the corresponding webview event. 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch event_name.replace( 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix); 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_router->RegisterObserver(this, event_name); 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebRequestAPI::~WebRequestAPI() { 4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(browser_context_)->UnregisterObserver(this); 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<WebRequestAPI> > 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<WebRequestAPI>* 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WebRequestAPI::GetFactoryInstance() { 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_factory.Pointer(); 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebRequestAPI::OnListenerRemoved(const EventListenerInfo& details) { 433effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Note that details.event_name includes the sub-event details (e.g. "/123"). 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&RemoveEventListenerOnIOThread, 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) details.browser_context, 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) details.extension_id, 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) details.event_name)); 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Represents a single unique listener to an event, along with whatever filter 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters and extra_info_spec were specified at the time the listener was 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// added. 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// not play well with event pages. See downloads.onDeterminingFilename and 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ExtensionDownloadsEventRouter for an alternative approach. 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionWebRequestEventRouter::EventListener { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_name; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sub_event_name; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestFilter filter; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec; 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id; 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Sender> ipc_sender; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable std::set<uint64> blocked_requests; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Comparator to work with std::set. 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator<(const EventListener& that) const { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id < that.extension_id) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id == that.extension_id && 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub_event_name < that.sub_event_name) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener() : extra_info_spec(0) {} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contains info about requests that are blocked waiting for a response from 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an extension. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionWebRequestEventRouter::BlockedRequest { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request that is being blocked. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Whether the request originates from an incognito tab. 4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_incognito; 4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event that we're currently blocked on. 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventTypes event; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The number of event handlers that we are awaiting a response from. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_handlers_blocking; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pointer to NetLog to report significant changes to the request for 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // debugging. 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog* net_log; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback to call when we get a response from all event handlers. 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If non-empty, this contains the new URL that the request will redirect to. 498effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Only valid for OnBeforeRequest and OnHeadersReceived. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* new_url; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request headers that will be issued along with this request. Only valid 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for OnBeforeSendHeaders. 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* request_headers; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The response headers that were received from the server. Only valid for 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnHeadersReceived. 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<const net::HttpResponseHeaders> original_response_headers; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location where to override response headers. Only valid for 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnHeadersReceived. 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::HttpResponseHeaders>* override_response_headers; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If non-empty, this contains the auth credentials that may be filled in. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only valid for OnAuthRequired. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::AuthCredentials* auth_credentials; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback to invoke for auth. If |auth_callback.is_null()| is false, 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |callback| must be NULL. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only valid for OnAuthRequired. 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AuthCallback auth_callback; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Time the request was paused. Used for logging purposes. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time blocking_time; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Changes requested by extensions. 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas response_deltas; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provider of meta data about extensions, only used and non-NULL for events 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that are delayed until the rules registry is ready. 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest() 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request(NULL), 5347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch is_incognito(false), 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event(kInvalidEvent), 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_handlers_blocking(0), 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log(NULL), 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_url(NULL), 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_headers(NULL), 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_response_headers(NULL), 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_credentials(NULL), 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map(NULL) {} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue& value, std::string* error) { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.HasKey("urls")) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (base::DictionaryValue::Iterator it(value); !it.IsAtEnd(); it.Advance()) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it.key() == "urls") { 5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* urls_value = NULL; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsList(&urls_value)) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < urls_value->GetSize(); ++i) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern pattern( 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS | 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern::SCHEME_FTP | URLPattern::SCHEME_FILE | 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern::SCHEME_EXTENSION); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!urls_value->GetString(i, &url) || 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern.Parse(url) != URLPattern::PARSE_SUCCESS) { 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *error = ErrorUtils::FormatErrorMessage( 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kInvalidRequestFilterUrl, url); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls.AddPattern(pattern); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (it.key() == "types") { 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* types_value = NULL; 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsList(&types_value)) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < types_value->GetSize(); ++i) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string type_str; 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType type; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!types_value->GetString(i, &type_str) || 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !helpers::ParseResourceType(type_str, &type)) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types.push_back(type); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (it.key() == "tabId") { 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsInteger(&tab_id)) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (it.key() == "windowId") { 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsInteger(&window_id)) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue& value, int* extra_info_spec) { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec = 0; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < value.GetSize(); ++i) { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.GetString(i, &str)) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == "requestHeaders") 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= REQUEST_HEADERS; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "responseHeaders") 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= RESPONSE_HEADERS; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "blocking") 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= BLOCKING; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "asyncBlocking") 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= ASYNC_BLOCKING; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "requestBody") 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *extra_info_spec |= REQUEST_BODY; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BLOCKING and ASYNC_BLOCKING are mutually exclusive. 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING)) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::EventResponse::EventResponse( 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, const base::Time& extension_install_time) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : extension_id(extension_id), 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_install_time(extension_install_time), 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel(false) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::EventResponse::~EventResponse() { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::RequestFilter::RequestFilter() 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : tab_id(-1), window_id(-1) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::RequestFilter::~RequestFilter() { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionWebRequestEventRouter 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter* ExtensionWebRequestEventRouter::GetInstance() { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<ExtensionWebRequestEventRouter>::get(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request_time_tracker_(new ExtensionWebRequestTimeTracker) { 6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_request_event_router_delegate_.reset( 6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::ExtensionsAPIClient::Get()-> 6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CreateWebRequestEventRouterDelegate()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::RegisterRulesRegistry( 6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const extensions::RulesRegistry::WebViewKey& webview_key, 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry) { 6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RulesRegistryKey key(browser_context, webview_key); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules_registry.get()) 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rules_registries_[key] = rules_registry; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rules_registries_.erase(key); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExtensionWebRequestEventRouter::ExtractRequestInfo( 6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequest* request, base::DictionaryValue* out) { 6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool is_main_frame = false; 6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int frame_id = -1; 6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool parent_is_main_frame = false; 6761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int parent_frame_id = -1; 6771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int frame_id_for_extension = -1; 6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int parent_frame_id_for_extension = -1; 6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int render_process_host_id = -1; 6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int routing_id = -1; 6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; 6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, 6831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &parent_is_main_frame, &parent_frame_id, 6841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &render_process_host_id, &routing_id, 6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &resource_type); 6861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci frame_id_for_extension = GetFrameId(is_main_frame, frame_id); 6871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci parent_frame_id_for_extension = GetFrameId(parent_is_main_frame, 6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci parent_frame_id); 6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetString(keys::kRequestIdKey, 6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Uint64ToString(request->identifier())); 6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetString(keys::kUrlKey, request->url().spec()); 6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetString(keys::kMethodKey, request->method()); 6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetInteger(keys::kFrameIdKey, frame_id_for_extension); 6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension); 6961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type)); 6971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); 6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (web_request_event_router_delegate_) { 6991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_request_event_router_delegate_->ExtractExtraRequestDetails( 7001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request, out); 7011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 7031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::OnBeforeRequest( 7051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* new_url) { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 7111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPageLoad(request)) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyPageLoad(); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestStartTime(request->identifier(), 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now(), 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->url(), 7211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether to initialized blocked_requests_. 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialize_blocked_requests = false; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 7271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ProcessDeclarativeRules(browser_context, extension_info_map, 7283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_request::OnBeforeRequest::kEventName, request, 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ON_BEFORE_REQUEST, NULL); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 7331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 7343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_request::OnBeforeRequest::kEventName, request, 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners.empty() && 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::REQUEST_BODY) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoBody(request, dict); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 7461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialize_blocked_requests) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; // Nobody saw a reason for modifying the request. 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnBeforeRequest; 7537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 7541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsIncognitoBrowserContext(browser_context); 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].callback = callback; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].new_url = new_url; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no blocking handlers, only the declarative rules tried 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to modify the request and we can respond synchronously. 7631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ExecuteDeltas(browser_context, request->identifier(), 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* call_callback*/); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::OnBeforeSendHeaders( 7711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* headers) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialize_blocked_requests = false; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 7841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ProcessDeclarativeRules(browser_context, extension_info_map, 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeSendHeadersEvent, request, 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ON_BEFORE_SEND_HEADERS, NULL); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeSendHeadersEvent, request, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extra_info_spec); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners.empty() && 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) { 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(*headers)); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialize_blocked_requests) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; // Nobody saw a reason for modifying the request. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnBeforeSendHeaders; 8107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsIncognitoBrowserContext(browser_context); 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].callback = callback; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].request_headers = headers; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no blocking handlers, only the declarative rules tried 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to modify the request and we can respond synchronously. 8201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ExecuteDeltas(browser_context, request->identifier(), 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* call_callback*/); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnSendHeaders( 8281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 8331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetAndSetSignaled(request->identifier(), kOnSendHeaders)) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnBeforeRedirect); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 8441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnSendHeadersEvent, request, 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(headers)); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::OnHeadersReceived( 8611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpResponseHeaders* original_response_headers, 866effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<net::HttpResponseHeaders>* override_response_headers, 867effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch GURL* allowed_unsafe_redirect_url) { 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 8691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialize_blocked_requests = false; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 8761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ProcessDeclarativeRules(browser_context, extension_info_map, 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnHeadersReceivedEvent, request, 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ON_HEADERS_RECEIVED, 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 8831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnHeadersReceivedEvent, request, 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extra_info_spec); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners.empty() && 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) { 8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kStatusLineKey, 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers->GetStatusLine()); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(original_response_headers)); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialize_blocked_requests) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; // Nobody saw a reason for modifying the request. 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnHeadersReceived; 9087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 9091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsIncognitoBrowserContext(browser_context); 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].callback = callback; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].override_response_headers = 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_response_headers; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].original_response_headers = 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers; 917effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocked_requests_[request->identifier()].new_url = 918effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch allowed_unsafe_redirect_url; 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no blocking handlers, only the declarative rules tried 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to modify the request and we can respond synchronously. 9231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ExecuteDeltas(browser_context, request->identifier(), 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* call_callback*/); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::NetworkDelegate::AuthRequiredResponse 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::OnAuthRequired( 9321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::AuthChallengeInfo& auth_info, 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::NetworkDelegate::AuthCallback& callback, 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::AuthCredentials* credentials) { 9381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // No browser_context means that this is for authentication challenges in the 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system context. Skip in that case. Also skip sensitive requests. 9401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 9461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnAuthRequiredEvent, request, 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kIsProxyKey, auth_info.is_proxy); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!auth_info.scheme.empty()) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kSchemeKey, auth_info.scheme); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!auth_info.realm.empty()) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kRealmKey, auth_info.realm); 9605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* challenger = new base::DictionaryValue(); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenger->SetString(keys::kHostKey, auth_info.challenger.host()); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenger->SetInteger(keys::kPortKey, auth_info.challenger.port()); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kChallengerKey, challenger); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (DispatchEvent(browser_context, request, listeners, args)) { 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnAuthRequired; 9737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 9741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsIncognitoBrowserContext(browser_context); 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].auth_callback = callback; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].auth_credentials = credentials; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnBeforeRedirect( 9851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_location) { 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 9901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect)) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnBeforeRequest); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnBeforeSendHeaders); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnSendHeaders); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnHeadersReceived); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 10041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRedirectEvent, request, 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int http_status_code = request->GetResponseCode(); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kRedirectUrlKey, new_location.spec()); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kStatusCodeKey, http_status_code); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnResponseStarted( 10331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 1034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) { 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 10371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnResponseStarted is even triggered, when the request was cancelled. 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->status().status() != net::URLRequestStatus::SUCCESS) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 10471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnResponseStartedEvent, request, 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UrlRequestFileJobs do not send headers, so we simulate their behavior. 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code = 200; 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->response_headers()) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code = request->response_headers()->response_code(); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kStatusCodeKey, response_code); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExtensionWebRequestEventRouter::OnCompleted(void* browser_context, 1078f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 1079f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) net::URLRequest* request) { 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, if the request first became sensitive after redirecting we have 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already signaled it and thus we have to signal the end of it. This is 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // risk-free because the handler cannot modify the request now. 10841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (WebRequestPermissions::HideRequest(extension_info_map, request) && 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !WasSignaled(*request))) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestEndTime(request->identifier(), 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPendingCallbacks(request); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 11001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnCompletedEvent, request, &extra_info_spec); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UrlRequestFileJobs do not send headers, so we simulate their behavior. 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code = 200; 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->response_headers()) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code = request->response_headers()->response_code(); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 11135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kStatusCodeKey, response_code); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnErrorOccurred( 11301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 1131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool started) { 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, if the request first became sensitive after redirecting we have 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already signaled it and thus we have to signal the end of it. This is 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // risk-free because the handler cannot modify the request now. 11381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!browser_context || 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (WebRequestPermissions::HideRequest(extension_info_map, request) && 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !WasSignaled(*request))) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestEndTime(request->identifier(), 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request->status().status() == net::URLRequestStatus::FAILED || 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->status().status() == net::URLRequestStatus::CANCELED); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPendingCallbacks(request); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 11551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetMatchingListeners(browser_context, extension_info_map, 11563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_request::OnErrorOccurred::kEventName, request, 11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue args; 11625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (started) { 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kErrorKey, 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ErrorToString(request->status().error())); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DispatchEvent(browser_context, request, listeners, args); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnURLRequestDestroyed( 11781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, net::URLRequest* request) { 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPendingCallbacks(request); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaled_requests_.erase(request->identifier()); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestEndTime(request->identifier(), 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::ClearPendingCallbacks( 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) { 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request->identifier()); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::DispatchEvent( 11931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<const EventListener*>& listeners, 11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue& args) { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pairs into a single message sent to a list of sub_event_names. 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_handlers_blocking = 0; 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<const EventListener*>::const_iterator it = listeners.begin(); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); ++it) { 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filter out the optional keys that this listener didn't request. 12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> args_filtered(args.DeepCopy()); 12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = NULL; 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args_filtered->GetDictionary(0, &dict) && dict); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!((*it)->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)) 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Remove(keys::kRequestHeadersKey, NULL); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!((*it)->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS)) 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Remove(keys::kResponseHeadersKey, NULL); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::EventRouter::DispatchEvent( 12121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (*it)->ipc_sender.get(), browser_context, 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*it)->extension_id, (*it)->sub_event_name, 1214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) args_filtered.Pass(), 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::EventRouter::USER_GESTURE_UNKNOWN, 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::EventFilteringInfo()); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->extra_info_spec & 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->blocked_requests.insert(request->identifier()); 12201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If this is the first delegate blocking the request, go ahead and log 12211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // it. 12221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (num_handlers_blocking == 0) { 12231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string delegate_info = 12241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, 12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16((*it)->extension_name)); 1226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // LobAndReport allows extensions that block requests to be displayed in 1227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the load status bar. 1228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request->LogAndReportBlockedBy(delegate_info.c_str()); 12291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_handlers_blocking; 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_handlers_blocking > 0) { 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].request = request; 12367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 12371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsIncognitoBrowserContext(browser_context); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].num_handlers_blocking += 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_handlers_blocking; 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnEventHandled( 12491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sub_event_name, 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventResponse* response) { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener listener; 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_id = extension_id; 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.sub_event_name = sub_event_name; 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The listener may have been removed (e.g. due to the process going away) 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before we got here. 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventListener>::iterator found = 12621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context][event_name].find(listener); 12631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (found != listeners_[browser_context][event_name].end()) 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found->blocked_requests.erase(request_id); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DecrementBlockCount( 12671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, extension_id, event_name, request_id, response); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::AddEventListener( 12711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_name, 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sub_event_name, 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RequestFilter& filter, 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec, 127890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id, 1279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id, 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Sender> ipc_sender) { 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsWebRequestEvent(event_name)) 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener listener; 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_id = extension_id; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_name = extension_name; 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.sub_event_name = sub_event_name; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.filter = filter; 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extra_info_spec = extra_info_spec; 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.ipc_sender = ipc_sender; 129190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listener.embedder_process_id = embedder_process_id; 1292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) listener.webview_instance_id = webview_instance_id; 12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (listener.webview_instance_id) { 12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RecordAction( 12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UserMetricsAction("WebView.WebRequest.AddListener")); 12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (listeners_[browser_context][event_name].count(listener) != 0u) { 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is likely an abuse of the API by a malicious extension. 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context][event_name].insert(listener); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::RemoveEventListener( 13071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sub_event_name) { 1310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string event_name = 1311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::EventRouter::GetBaseEventName(sub_event_name); 1312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(IsWebRequestEvent(event_name)); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener listener; 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_id = extension_id; 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.sub_event_name = sub_event_name; 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible for AddEventListener to fail asynchronously. In that case, 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the renderer believes the listener exists, while the browser does not. 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore a RemoveEventListener in that case. 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventListener>::iterator found = 13221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context][event_name].find(listener); 13231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (found == listeners_[browser_context][event_name].end()) 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK_EQ(listeners_[browser_context][event_name].count(listener), 1u) << 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extension=" << extension_id << " event=" << event_name; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unblock any request that this event listener may have been blocking. 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<uint64>::iterator it = found->blocked_requests.begin(); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != found->blocked_requests.end(); ++it) { 13321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DecrementBlockCount(browser_context, extension_id, event_name, *it, NULL); 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context][event_name].erase(listener); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ClearCacheOnNavigation(); 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 134090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( 13411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 134290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id, 134390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id, 1344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id) { 134590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Iterate over all listeners of all WebRequest events to delete 134690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // any listeners that belong to the provided <webview>. 13471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ListenerMapForBrowserContext& map_for_browser_context = 13481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context]; 13491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (ListenerMapForBrowserContext::iterator event_iter = 13501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci map_for_browser_context.begin(); 13511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event_iter != map_for_browser_context.end(); ++event_iter) { 135290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<EventListener> listeners_to_delete; 135390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<EventListener>& listeners = event_iter->second; 135490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::set<EventListener>::iterator listener_iter = listeners.begin(); 135590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listener_iter != listeners.end(); ++listener_iter) { 135690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const EventListener& listener = *listener_iter; 135790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (listener.embedder_process_id == embedder_process_id && 1358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) listener.webview_instance_id == webview_instance_id) 135990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listeners_to_delete.push_back(listener); 136090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 136190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < listeners_to_delete.size(); ++i) { 136290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EventListener& listener = listeners_to_delete[i]; 136390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserThread::PostTask( 136490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserThread::UI, 136590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 136690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&RemoveEventListenerOnUI, 13671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, 136890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listener.sub_event_name, 136990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) embedder_process_id, 137090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_id)); 137190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 137290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 137390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 137490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExtensionWebRequestEventRouter::OnOTRBrowserContextCreated( 13761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* original_browser_context, void* otr_browser_context) { 13771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context_map_[original_browser_context] = 13781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::make_pair(false, otr_browser_context); 13791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context_map_[otr_browser_context] = 13801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::make_pair(true, original_browser_context); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExtensionWebRequestEventRouter::OnOTRBrowserContextDestroyed( 13841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* original_browser_context, void* otr_browser_context) { 13851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context_map_.erase(otr_browser_context); 13861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context_map_.erase(original_browser_context); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks_for_page_load_.push_back(callback); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::IsPageLoad( 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) const { 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame = false; 13975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int frame_id = -1; 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parent_is_main_frame = false; 13995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int parent_frame_id = -1; 14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id = -1; 14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id = -1; 14025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parent_is_main_frame, &parent_frame_id, 14061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &render_process_host_id, 14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &routing_id, &resource_type); 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return resource_type == content::RESOURCE_TYPE_MAIN_FRAME; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::NotifyPageLoad() { 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CallbacksForPageLoad::const_iterator i = 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks_for_page_load_.begin(); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != callbacks_for_page_load_.end(); ++i) { 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->Run(); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks_for_page_load_.clear(); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid* ExtensionWebRequestEventRouter::GetCrossBrowserContext( 14221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context) const { 14231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CrossBrowserContextMap::const_iterator cross_browser_context = 14241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context_map_.find(browser_context); 14251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cross_browser_context == cross_browser_context_map_.end()) 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 14271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return cross_browser_context->second.second; 14287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 14297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 14301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ExtensionWebRequestEventRouter::IsIncognitoBrowserContext( 14311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context) const { 14321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CrossBrowserContextMap::const_iterator cross_browser_context = 14331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context_map_.find(browser_context); 14341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cross_browser_context == cross_browser_context_map_.end()) 14357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 14361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return cross_browser_context->second.first; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::WasSignaled( 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequest& request) const { 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignaledRequestMap::const_iterator flag = 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaled_requests_.find(request.identifier()); 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (flag != signaled_requests_.end()) && (flag->second != 0); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( 14471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 14481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequest* request, 1449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool crosses_incognito, 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id, 14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id, 14555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType resource_type, 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_async_request, 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_request_from_extension, 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* extra_info_spec, 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const ExtensionWebRequestEventRouter::EventListener*>* 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching_listeners) { 146190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string web_request_event_name(event_name); 14626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) extensions::WebViewRendererState::WebViewInfo web_view_info; 14636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool is_web_view_guest = extensions::WebViewRendererState::GetInstance()-> 1464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetInfo(render_process_host_id, routing_id, &web_view_info); 1465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_web_view_guest) { 1466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch web_request_event_name.replace( 1467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 0, sizeof(kWebRequestEventPrefix) - 1, webview::kWebViewEventPrefix); 1468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 146990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 147090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<EventListener>& listeners = 14711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context][web_request_event_name]; 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<EventListener>::iterator it = listeners.begin(); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); ++it) { 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->ipc_sender.get()) { 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The IPC sender has been deleted. This listener will be removed soon 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via a call to RemoveEventListener. For now, just skip it. 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_web_view_guest && 1481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (it->embedder_process_id != web_view_info.embedder_process_id || 1482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it->webview_instance_id != web_view_info.instance_id)) 14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 14871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (web_request_event_router_delegate_ && 14881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_request_event_router_delegate_->OnGetMatchingListenersImplCheck( 14891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it->filter.tab_id, it->filter.window_id, request)) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->filter.types.empty() && 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(it->filter.types.begin(), it->filter.types.end(), 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_type) == it->filter.types.end()) 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_web_view_guest && !WebRequestPermissions::CanExtensionAccessURL( 1497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_info_map, it->extension_id, url, crosses_incognito, 1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebRequestPermissions::REQUIRE_HOST_PERMISSION)) 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool blocking_listener = 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (it->extra_info_spec & 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not want to notify extensions about XHR requests that are 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // triggered by themselves. This is a workaround to prevent deadlocks 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in case of synchronous XHR requests that block the extension renderer 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and therefore prevent the extension from processing the request 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handler. This is only a problem for blocking listeners. 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/105656 15115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool synchronous_xhr_from_extension = 15125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !is_async_request && is_request_from_extension && 15135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resource_type == content::RESOURCE_TYPE_XHR; 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only send webRequest events for URLs the extension has access to. 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocking_listener && synchronous_xhr_from_extension) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching_listeners->push_back(&(*it)); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= it->extra_info_spec; 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<const ExtensionWebRequestEventRouter::EventListener*> 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::GetMatchingListeners( 15261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 1527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* extra_info_spec) { 15311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(mpcomplete): handle browser_context == NULL (should collect all 15321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // listeners). 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec = 0; 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame = false; 15365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int frame_id = -1; 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parent_is_main_frame = false; 15385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int parent_frame_id = -1; 15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id = -1; 15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id = -1; 15415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url = request->url(); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parent_is_main_frame, &parent_frame_id, 15461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &render_process_host_id, 15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &routing_id, &resource_type); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const ExtensionWebRequestEventRouter::EventListener*> 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching_listeners; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_request_from_extension = 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsRequestFromExtension(request, extension_info_map); 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are conservative here and assume requests are asynchronous in case 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we don't have an info object. We don't want to risk a deadlock. 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_async_request = !info || info->IsAsync(); 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListenersImpl( 15611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, request, extension_info_map, false, event_name, 15621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url, render_process_host_id, routing_id, resource_type, 15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_async_request, is_request_from_extension, extra_info_spec, 15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &matching_listeners); 15651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* cross_browser_context = GetCrossBrowserContext(browser_context); 15661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cross_browser_context) { 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListenersImpl( 15681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context, request, extension_info_map, true, event_name, 15691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url, render_process_host_id, routing_id, resource_type, 15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_async_request, is_request_from_extension, extra_info_spec, 15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &matching_listeners); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return matching_listeners; 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)helpers::EventResponseDelta* CalculateDelta( 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::BlockedRequest* blocked_request, 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::EventResponse* response) { 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (blocked_request->event) { 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeRequest: 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnBeforeRequestDelta( 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, response->new_url); 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeSendHeaders: { 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* old_headers = blocked_request->request_headers; 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* new_headers = response->request_headers.get(); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnBeforeSendHeadersDelta( 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, old_headers, new_headers); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnHeadersReceived: { 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpResponseHeaders* old_headers = 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request->original_response_headers.get(); 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ResponseHeaders* new_headers = 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->response_headers.get(); 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnHeadersReceivedDelta( 1600effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response->extension_id, 1601effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response->extension_install_time, 1602effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response->cancel, 1603effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response->new_url, 1604effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch old_headers, 1605effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new_headers); 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnAuthRequired: 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnAuthRequiredDelta( 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, &response->auth_credentials); 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Value* SerializeResponseHeaders(const helpers::ResponseHeaders& headers) { 16195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> serialized_headers(new base::ListValue()); 1620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (helpers::ResponseHeaders::const_iterator i = headers.begin(); 1621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i != headers.end(); ++i) { 16221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized_headers->Append( 16231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci helpers::CreateHeaderDictionary(i->first, i->second)); 1624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return serialized_headers.release(); 1626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Convert a RequestCookieModifications/ResponseCookieModifications object to a 16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// base::ListValue which summarizes the changes made. This is templated since 16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the two types (request/response) are different but contain essentially the 16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// same fields. 1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename CookieType> 16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::ListValue* SummarizeCookieModifications( 1634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<linked_ptr<CookieType> >& modifications) { 16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> cookie_modifications(new base::ListValue()); 1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (typename std::vector<linked_ptr<CookieType> >::const_iterator i = 1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) modifications.begin(); 1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i != modifications.end(); ++i) { 16395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> summary(new base::DictionaryValue()); 1640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CookieType& mod = *i->get(); 1641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (mod.type) { 1642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case helpers::ADD: 1643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModificationTypeKey, 1644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kCookieModificationAdd); 1645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case helpers::EDIT: 1647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModificationTypeKey, 1648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kCookieModificationEdit); 1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case helpers::REMOVE: 1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModificationTypeKey, 1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kCookieModificationRemove); 1653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.filter) { 1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.filter->name) 1657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieFilterNameKey, 1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.filter->domain) 1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieFilterDomainKey, 1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.modification) { 1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.modification->name) 1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModDomainKey, 1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.modification->domain) 1668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModDomainKey, 1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cookie_modifications->Append(summary.release()); 1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return cookie_modifications.release(); 1674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converts an EventResponseDelta object to a dictionary value suitable for the 16777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// activity log. 16785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<base::DictionaryValue> SummarizeResponseDelta( 1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& event_name, 1680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const helpers::EventResponseDelta& delta) { 16815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> details(new base::DictionaryValue()); 1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (delta.cancel) { 1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->SetBoolean(activitylog::kCancelKey, true); 1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.new_url.is_empty()) { 1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->SetString(activitylog::kNewUrlKey, delta.new_url.spec()); 1687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> modified_headers(new base::ListValue()); 1690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::HttpRequestHeaders::Iterator iter(delta.modified_request_headers); 1691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (iter.GetNext()) { 16921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci modified_headers->Append( 16931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci helpers::CreateHeaderDictionary(iter.name(), iter.value())); 1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!modified_headers->empty()) { 1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kModifiedRequestHeadersKey, 1697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) modified_headers.release()); 1698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> deleted_headers(new base::ListValue()); 1701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deleted_headers->AppendStrings(delta.deleted_request_headers); 1702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!deleted_headers->empty()) { 1703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kDeletedRequestHeadersKey, 1704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deleted_headers.release()); 1705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.added_response_headers.empty()) { 1708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kAddedRequestHeadersKey, 1709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SerializeResponseHeaders(delta.added_response_headers)); 1710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.deleted_response_headers.empty()) { 1712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kDeletedResponseHeadersKey, 1713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SerializeResponseHeaders(delta.deleted_response_headers)); 1714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (delta.auth_credentials) { 1716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->SetString(activitylog::kAuthCredentialsKey, 17175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF16ToUTF8( 17185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delta.auth_credentials->username()) + ":*"); 1719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.response_cookie_modifications.empty()) { 1722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set( 1723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kResponseCookieModificationsKey, 1724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SummarizeCookieModifications(delta.response_cookie_modifications)); 1725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return details.Pass(); 1728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 17311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 17321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExtensionWebRequestEventRouter::LogExtensionActivity( 17331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context_id, 17341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool is_incognito, 17351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& extension_id, 17361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& url, 17371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& api_call, 17381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::DictionaryValue> details) { 1739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 17401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::PostTask( 17411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::UI, 17421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 17431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ExtensionWebRequestEventRouter::LogExtensionActivity, 17441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this), 17451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context_id, 17461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_incognito, 17471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_id, 17481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url, 17491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci api_call, 17501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Passed(&details))); 1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 17521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (web_request_event_router_delegate_) { 17531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_request_event_router_delegate_->LogExtensionActivity( 17541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reinterpret_cast<content::BrowserContext*>(browser_context_id), 17551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_incognito, extension_id, url, api_call, details.Pass()); 17561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::DecrementBlockCount( 17611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventResponse* response) { 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<EventResponse> response_scoped(response); 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that this request was deleted, or cancelled by a previous 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event handler. If so, ignore this response. 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_.find(request_id) == blocked_requests_.end()) 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest& blocked_request = blocked_requests_[request_id]; 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_handlers_blocking = --blocked_request.num_handlers_blocking; 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(num_handlers_blocking, 0); 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response) { 1778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) helpers::EventResponseDelta* delta = 1779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CalculateDelta(&blocked_request, response); 1780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LogExtensionActivity(browser_context, 178258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blocked_request.is_incognito, 178358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) extension_id, 178458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blocked_request.request->url(), 178558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event_name, 178658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SummarizeResponseDelta(event_name, *delta)); 1787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas.push_back( 1789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) linked_ptr<helpers::EventResponseDelta>(delta)); 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta block_time = 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - blocked_request.blocking_time; 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_id.empty()) { 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->IncrementExtensionBlockTime( 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id, request_id, block_time); 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |extension_id| is empty for requests blocked on startup waiting for the 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // declarative rules to be read from disk. 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time); 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_handlers_blocking == 0) { 1804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) blocked_request.request->LogUnblocked(); 18051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExecuteDeltas(browser_context, request_id, true); 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Update the URLRequest to make sure it's tagged with an extension that's 18081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // still blocking it. This may end up being the same extension as before. 18091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::set<EventListener>& listeners = 18101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci listeners_[browser_context][event_name]; 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<EventListener>::iterator it = listeners.begin(); 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); ++it) { 18141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it->blocked_requests.count(request_id) == 0) 18151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) continue; 18161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string delegate_info = 18171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, 18185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(it->extension_name)); 1819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) blocked_request.request->LogAndReportBlockedBy(delegate_info.c_str()); 18201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionWebRequestEventRouter::SendMessages( 18261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BlockedRequest& blocked_request) { 18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (helpers::EventResponseDeltas::const_iterator delta = deltas.begin(); 18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delta != deltas.end(); ++delta) { 18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<std::string>& messages = (*delta)->messages_to_extension; 18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<std::string>::const_iterator message = messages.begin(); 18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message != messages.end(); ++message) { 18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> argument(new base::DictionaryValue); 18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtractRequestInfo(blocked_request.request, argument.get()); 18366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) extensions::WebViewRendererState::WebViewInfo web_view_info; 1837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_web_view_guest = GetWebViewInfo(blocked_request.request, 1838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &web_view_info); 18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) argument->SetString(keys::kMessageKey, *message); 18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) argument->SetString(keys::kStageKey, 18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestStageAsString(blocked_request.event)); 18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SendOnMessageEventOnUI, 18471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, 18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*delta)->extension_id, 1849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_web_view_guest, 1850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) web_view_info, 18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&argument))); 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::ExecuteDeltas( 18571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool call_callback) { 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest& blocked_request = blocked_requests_[request_id]; 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(blocked_request.num_handlers_blocking == 0); 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta block_time = 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - blocked_request.blocking_time; 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->IncrementTotalBlockTime(request_id, block_time); 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool credentials_set = false; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); 18701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WarningSet warnings; 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool canceled = false; 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeCancelOfResponses( 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &canceled, 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_request.event == kOnBeforeRequest) { 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.callback.is_null()); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeOnBeforeRequestResponses( 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.new_url, 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.event == kOnBeforeSendHeaders) { 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.callback.is_null()); 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeOnBeforeSendHeadersResponses( 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.request_headers, 18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.event == kOnHeadersReceived) { 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.callback.is_null()); 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeOnHeadersReceivedResponses( 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.original_response_headers.get(), 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.override_response_headers, 1898effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocked_request.new_url, 18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.event == kOnAuthRequired) { 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(blocked_request.callback.is_null()); 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.auth_callback.is_null()); 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials_set = helpers::MergeOnAuthRequiredResponses( 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.auth_credentials, 19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SendMessages(browser_context, blocked_request); 19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!warnings.empty()) { 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 19191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&WarningService::NotifyWarningsOnUI, 19201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, warnings)); 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (canceled) { 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->SetRequestCanceled(request_id); 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.new_url && 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !blocked_request.new_url->is_empty()) { 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->SetRequestRedirected(request_id); 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This triggers onErrorOccurred if canceled is true. 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = canceled ? net::ERR_BLOCKED_BY_CLIENT : net::OK; 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blocked_request.callback.is_null()) { 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback = blocked_request.callback; 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that request is removed before callback because the callback 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // might trigger the next event. 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request_id); 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (call_callback) 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(rv); 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!blocked_request.auth_callback.is_null()) { 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AuthRequiredResponse response = 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (canceled) { 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH; 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (credentials_set) { 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH; 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AuthCallback callback = blocked_request.auth_callback; 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request_id); 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (call_callback) 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(response); 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request_id); 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( 19591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 1960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InfoMap* extension_info_map, 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::RequestStage request_stage, 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpResponseHeaders* original_response_headers) { 19656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) extensions::WebViewRendererState::WebViewInfo web_view_info; 1966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_web_view_guest = GetWebViewInfo(request, &web_view_info); 1967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 19681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::RulesRegistry::WebViewKey webview_key( 1969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_web_view_guest ? web_view_info.embedder_process_id : 0, 1970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_web_view_guest ? web_view_info.instance_id : 0); 19711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RulesRegistryKey rules_key(browser_context, webview_key); 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this check fails, check that the active stages are up-to-date in 19731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // extensions/browser/api/declarative_webrequest/request_stage.h . 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_stage & extensions::kActiveStages); 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Rules of the current |browser_context| may apply but we need to check also 19771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // whether there are applicable rules from extensions whose background page 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // spans from regular to incognito mode. 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First parameter identifies the registry, the second indicates whether the 19811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // registry belongs to the cross browser_context. 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::pair<extensions::WebRequestRulesRegistry*, bool> 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelevantRegistry; 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<RelevantRegistry> RelevantRegistries; 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelevantRegistries relevant_registries; 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rules_registries_.find(rules_key) != rules_registries_.end()) { 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relevant_registries.push_back( 1989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::make_pair(rules_registries_[rules_key].get(), false)); 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* cross_browser_context = GetCrossBrowserContext(browser_context); 19931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RulesRegistryKey cross_browser_context_rules_key( 19941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cross_browser_context, webview_key); 19951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cross_browser_context && 19961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rules_registries_.find(cross_browser_context_rules_key) != 1997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rules_registries_.end()) { 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relevant_registries.push_back( 19991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::make_pair( 20001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rules_registries_[cross_browser_context_rules_key].get(), true)); 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The following block is experimentally enabled and its impact on load time 20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // logged with UMA Extensions.NetworkDelayRegistryLoad. crbug.com/175961 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RelevantRegistries::iterator i = relevant_registries.begin(); 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != relevant_registries.end(); ++i) { 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::WebRequestRulesRegistry* rules_registry = i->first; 200890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!rules_registry->ready().is_signaled()) { 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The rules registry is still loading. Block this request until it 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // finishes. 201190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rules_registry->ready().Post( 201290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ExtensionWebRequestEventRouter::OnRulesRegistryReady, 201490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr(), 20151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, 201690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_name, 201790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request->identifier(), 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_stage)); 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].num_handlers_blocking++; 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].request = request; 20217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 20221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsIncognitoBrowserContext(browser_context); 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].blocking_time = 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now(); 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].original_response_headers = 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers; 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].extension_info_map = 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map; 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start = base::Time::Now(); 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool deltas_created = false; 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RelevantRegistries::iterator i = relevant_registries.begin(); 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != relevant_registries.end(); ++i) { 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::WebRequestRulesRegistry* rules_registry = 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->first; 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas result = 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_registry->CreateDeltas( 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map, 20432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::WebRequestData( 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request, request_stage, original_response_headers), 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second); 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.empty()) { 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas& deltas = 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].response_deltas; 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.insert(deltas.end(), result.begin(), result.end()); 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas_created = true; 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta elapsed_time = start - base::Time::Now(); 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elapsed_time); 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return deltas_created; 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnRulesRegistryReady( 20631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* browser_context, 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::RequestStage request_stage) { 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that this request was deleted, or cancelled by a previous 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event handler. If so, ignore this response. 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_.find(request_id) == blocked_requests_.end()) 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest& blocked_request = blocked_requests_[request_id]; 20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta block_time = 20742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Now() - blocked_request.blocking_time; 20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayRegistryLoad", block_time); 20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ProcessDeclarativeRules(browser_context, 2078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) blocked_request.extension_info_map, 2079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) event_name, 2080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) blocked_request.request, 2081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_stage, 2082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) blocked_request.original_response_headers.get()); 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset to NULL so that nobody relies on this being set. 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.extension_info_map = NULL; 20851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DecrementBlockCount( 20861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_context, std::string(), event_name, request_id, NULL); 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventTypes event_type) { 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == signaled_requests_.end()) { 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaled_requests_[request_id] = event_type; 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_signaled_before = (iter->second & event_type) != 0; 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second |= event_type; 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_signaled_before; 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::ClearSignaled(uint64 request_id, 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventTypes event_type) { 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == signaled_requests_.end()) 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second &= ~event_type; 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Special QuotaLimitHeuristic for WebRequestHandlerBehaviorChangedFunction. 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Each call of webRequest.handlerBehaviorChanged() clears the in-memory cache 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of WebKit at the time of the next page load (top level navigation event). 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This quota heuristic is intended to limit the number of times the cache is 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cleared by an extension. 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As we want to account for the number of times the cache is really cleared 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (opposed to the number of times webRequest.handlerBehaviorChanged() is 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// called), we cannot decide whether a call of 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webRequest.handlerBehaviorChanged() should trigger a quota violation at the 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// time it is called. Instead we only decrement the bucket counter at the time 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when the cache is cleared (when page loads happen). 2122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ClearCacheQuotaHeuristic : public extensions::QuotaLimitHeuristic { 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearCacheQuotaHeuristic(const Config& config, BucketMapper* map) 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : QuotaLimitHeuristic( 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config, 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map, 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"), 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_registered_(false), 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_(this) {} 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ClearCacheQuotaHeuristic() {} 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Apply(Bucket* bucket, 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time) OVERRIDE; 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback that is triggered by the ExtensionWebRequestEventRouter on a page 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load. 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need to take care of the life time of |bucket|: It is owned by the 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BucketMapper of our base class in |QuotaLimitHeuristic::bucket_mapper_|. As 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // long as |this| exists, the respective BucketMapper and its bucket will 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exist as well. 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPageLoad(Bucket* bucket); 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag to prevent that we register more than one call back in-between 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clearing the cache. 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool callback_registered_; 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ClearCacheQuotaHeuristic> weak_ptr_factory_; 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ClearCacheQuotaHeuristic); 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ClearCacheQuotaHeuristic::Apply(Bucket* bucket, 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time) { 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_time > bucket->expiration()) 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket->Reset(config(), event_time); 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call bucket->DeductToken() on a new page load, this is when 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // webRequest.handlerBehaviorChanged() clears the cache. 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_registered_) { 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->AddCallbackForPageLoad( 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ClearCacheQuotaHeuristic::OnPageLoad, 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket)); 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_registered_ = true; 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only check whether tokens are left here. Deducting a token happens in 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnPageLoad(). 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bucket->has_tokens(); 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClearCacheQuotaHeuristic::OnPageLoad(Bucket* bucket) { 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_registered_ = false; 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket->DeductToken(); 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool WebRequestInternalAddEventListenerFunction::RunSync() { 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Argument 0 is the callback, which we don't use here. 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::RequestFilter filter; 21825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* value = NULL; 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.clear(); 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &value)); 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failure + an empty error string means a fatal error. 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(filter.InitFromValue(*value, &error_) || 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !error_.empty()); 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!error_.empty()) 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasOptionalArgument(2)) { 21935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* value = NULL; 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value)); 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value, &extra_info_spec)); 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name; 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sub_event_name; 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id = 0; 2207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &webview_instance_id)); 220890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2209e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::WeakPtr<extensions::ExtensionMessageFilter> ipc_sender = 2210e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ipc_sender_weak(); 221190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id = 221290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ipc_sender.get() ? ipc_sender->render_process_id() : -1; 221390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map()->extensions().GetByID(extension_id()); 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_name = extension ? extension->name() : extension_id(); 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_web_view_guest = webview_instance_id != 0; 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We check automatically whether the extension has the 'webRequest' 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // permission. For blocking calls we require the additional permission 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'webRequestBlocking'. 222246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((!is_web_view_guest && 222346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extra_info_spec & 222446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | 222546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && 222646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !extension->permissions_data()->HasAPIPermission( 222746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::APIPermission::kWebRequestBlocking)) { 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kBlockingPermissionRequired; 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We allow to subscribe to patterns that are broader than the host 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // permissions. E.g., we could subscribe to http://www.example.com/* 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // while having host permissions for http://www.example.com/foo/* and 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://www.example.com/bar/*. 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For this reason we do only a coarse check here to warn the extension 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // developer if he does something obviously wrong. 2238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_web_view_guest && 223946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->GetEffectiveHostPermissions().is_empty()) { 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kHostPermissionsRequired; 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_id(), extension_id(), extension_name, 224790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_name, sub_event_name, filter, extra_info_spec, 2248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) embedder_process_id, webview_instance_id, ipc_sender_weak()); 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(success); 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ClearCacheOnNavigation(); 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, 22545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 22555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&helpers::NotifyWebRequestAPIUsed, 22565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile_id(), 22575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) make_scoped_refptr(extension))); 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2262a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid WebRequestInternalEventHandledFunction::RespondWithError( 2263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& event_name, 2264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& sub_event_name, 2265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint64 request_id, 2266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response, 2267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error) { 2268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_ = error; 2269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( 2270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) profile_id(), 2271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_id(), 2272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_name, 2273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sub_event_name, 2274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_id, 2275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response.release()); 2276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 2277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 22785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool WebRequestInternalEventHandledFunction::RunSync() { 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name; 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sub_event_name; 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &sub_event_name)); 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string request_id_str; 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &request_id_str)); 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id; 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(base::StringToUint64(request_id_str, 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_id)); 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response; 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasOptionalArgument(3)) { 22935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* value = NULL; 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(3, &value)); 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value->empty()) { 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time install_time = 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map()->GetInstallTime(extension_id()); 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.reset(new ExtensionWebRequestEventRouter::EventResponse( 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id(), install_time)); 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("cancel")) { 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't allow cancel mixed with other keys. 2305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (value->size() != 1) { 2306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RespondWithError(event_name, 2307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sub_event_name, 2308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_id, 2309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response.Pass(), 2310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch keys::kInvalidBlockingResponse); 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool cancel = false; 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetBoolean("cancel", &cancel)); 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel = cancel; 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("redirectUrl")) { 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string new_url_str; 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetString("redirectUrl", 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &new_url_str)); 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->new_url = GURL(new_url_str); 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response->new_url.is_valid()) { 2325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RespondWithError(event_name, 2326effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sub_event_name, 2327effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_id, 2328effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response.Pass(), 2329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ErrorUtils::FormatErrorMessage( 2330effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch keys::kInvalidRedirectUrl, new_url_str)); 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const bool hasRequestHeaders = value->HasKey("requestHeaders"); 2336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const bool hasResponseHeaders = value->HasKey("responseHeaders"); 2337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (hasRequestHeaders || hasResponseHeaders) { 2338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (hasRequestHeaders && hasResponseHeaders) { 2339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Allow only one of the keys, not both. 2340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RespondWithError(event_name, 2341effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sub_event_name, 2342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_id, 2343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response.Pass(), 2344effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch keys::kInvalidHeaderKeyCombination); 2345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 2346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ListValue* headers_value = NULL; 2349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<net::HttpRequestHeaders> request_headers; 2350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<helpers::ResponseHeaders> response_headers; 2351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (hasRequestHeaders) { 2352effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_headers.reset(new net::HttpRequestHeaders()); 2353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetList(keys::kRequestHeadersKey, 2354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &headers_value)); 2355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 2356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response_headers.reset(new helpers::ResponseHeaders()); 2357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetList(keys::kResponseHeadersKey, 2358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &headers_value)); 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < headers_value->GetSize(); ++i) { 23625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* header_value = NULL; 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 2366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) headers_value->GetDictionary(i, &header_value)); 2367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!FromHeaderDictionary(header_value, &name, &value)) { 2368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string serialized_header; 2369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::JSONWriter::Write(header_value, &serialized_header); 2370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RespondWithError(event_name, 2371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sub_event_name, 2372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_id, 2373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response.Pass(), 2374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ErrorUtils::FormatErrorMessage(keys::kInvalidHeader, 2375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch serialized_header)); 2376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 2377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 23781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!net::HttpUtil::IsValidHeaderName(name)) { 2379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RespondWithError(event_name, 2380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sub_event_name, 2381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_id, 2382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response.Pass(), 2383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch keys::kInvalidHeaderName); 2384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 2385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 23861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!net::HttpUtil::IsValidHeaderValue(value)) { 2387effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RespondWithError(event_name, 2388effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sub_event_name, 2389effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_id, 2390effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response.Pass(), 2391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ErrorUtils::FormatErrorMessage( 2392effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch keys::kInvalidHeaderValue, name)); 2393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 2394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (hasRequestHeaders) 2396effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_headers->SetHeader(name, value); 2397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 2398effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response_headers->push_back(helpers::ResponseHeader(name, value)); 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2400effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (hasRequestHeaders) 2401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response->request_headers.reset(request_headers.release()); 2402effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else 2403effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response->response_headers.reset(response_headers.release()); 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey(keys::kAuthCredentialsKey)) { 24075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* credentials_value = NULL; 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetDictionary( 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kAuthCredentialsKey, 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &credentials_value)); 2411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 username; 2412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 password; 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials_value->GetString(keys::kUsernameKey, &username)); 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials_value->GetString(keys::kPasswordKey, &password)); 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->auth_credentials.reset( 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::AuthCredentials(username, password)); 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_id(), extension_id(), event_name, sub_event_name, request_id, 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.release()); 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebRequestHandlerBehaviorChangedFunction::GetQuotaLimitHeuristics( 2430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::QuotaLimitHeuristics* heuristics) const { 2431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::QuotaLimitHeuristic::Config config = { 2432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // See web_request.json for current value. 2433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_request::MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES, 2434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromMinutes(10)}; 2435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::QuotaLimitHeuristic::BucketMapper* bucket_mapper = 2436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new extensions::QuotaLimitHeuristic::SingletonBucketMapper(); 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearCacheQuotaHeuristic* heuristic = 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ClearCacheQuotaHeuristic(config, bucket_mapper); 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) heuristics->push_back(heuristic); 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebRequestHandlerBehaviorChangedFunction::OnQuotaExceeded( 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& violation_error) { 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post warning message. 24451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WarningSet warnings; 24462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) warnings.insert( 24471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Warning::CreateRepeatedCacheFlushesWarning(extension_id())); 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 24511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&WarningService::NotifyWarningsOnUI, profile_id(), warnings)); 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Continue gracefully. 2454010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunSync(); 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool WebRequestHandlerBehaviorChangedFunction::RunSync() { 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ClearCacheOnNavigation(); 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2461