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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/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" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chrome_content_browser_client.h" 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_action_constants.h" 21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_actions.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_log.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/activity_log/web_request_constants.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_request/upload_data_presenter.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/event_router.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_info_map.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_renderer_state.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_warning_service.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_warning_set.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/renderer_host/chrome_render_message_filter.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/web_request.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_messages.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/features/feature.h" 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/permissions/permissions_data.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_message_filter.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h" 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h" 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/event_filtering_info.h" 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/url_pattern.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::DictionaryValue; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::ListValue; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringValue; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using chrome::VersionInfo; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserMessageFilter; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ResourceRequestInfo; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ErrorUtils; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ExtensionWarning; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ExtensionWarningService; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ExtensionWarningSet; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Feature; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::web_navigation_api_helpers::GetFrameId; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace helpers = extension_web_request_api_helpers; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extension_web_request_api_constants; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace web_request = extensions::api::web_request; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace declarative_keys = extensions::declarative_webrequest_constants; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace activitylog = activity_log_web_request_constants; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kWebRequest[] = "webRequest"; 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kWebView[] = "webview"; 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// List of all the webRequest events. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kWebRequestEvents[] = { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRedirectEvent, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRequestEvent, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeSendHeadersEvent, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnCompletedEvent, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnErrorOccurredEvent, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnSendHeadersEvent, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnAuthRequiredEvent, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnResponseStartedEvent, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnHeadersReceivedEvent, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ARRAYEND(array) (array + arraysize(array)) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetRequestStageAsString( 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionWebRequestEventRouter::EventTypes type) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kInvalidEvent: 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "Invalid"; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeRequest: 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnBeforeRequest; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeSendHeaders: 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnBeforeSendHeaders; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnSendHeaders: 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnSendHeaders; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnHeadersReceived: 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnHeadersReceived; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeRedirect: 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnBeforeRedirect; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnAuthRequired: 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnAuthRequired; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnResponseStarted: 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnResponseStarted; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnErrorOccurred: 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnErrorOccurred; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ExtensionWebRequestEventRouter::kOnCompleted: 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return keys::kOnCompleted; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "Not reached"; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsWebRequestEvent(const std::string& event_name) { 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string web_request_event_name(event_name); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (web_request_event_name.find(kWebView) != std::string::npos) 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_request_event_name.replace(0, sizeof(kWebView) - 1, kWebRequest); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_request_event_name) != ARRAYEND(kWebRequestEvents); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns whether |request| has been triggered by an extension in 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |extension_info_map|. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsRequestFromExtension(const net::URLRequest* request, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionInfoMap* extension_info_map) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |extension_info_map| is NULL for system-level requests. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_info_map) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this request was not created by the ResourceDispatcher, |info| is NULL. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All requests from extensions are created by the ResourceDispatcher. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_info_map->process_map().Contains(info->GetChildID()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtractRequestInfoDetails(net::URLRequest* request, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* is_main_frame, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* frame_id, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* parent_is_main_frame, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* parent_frame_id, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_id, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* window_id, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* render_process_host_id, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* routing_id, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::Type* resource_type) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request->GetUserData(NULL)) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionRendererState::GetInstance()->GetTabAndWindowId( 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->GetChildID(), info->GetRouteID(), tab_id, window_id); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *frame_id = info->GetFrameID(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *is_main_frame = info->IsMainFrame(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *parent_frame_id = info->GetParentFrameID(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *parent_is_main_frame = info->ParentIsMainFrame(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *render_process_host_id = info->GetChildID(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *routing_id = info->GetRouteID(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restrict the resource type to the values we care about. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (helpers::IsRelevantResourceType(info->GetResourceType())) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resource_type = info->GetResourceType(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *resource_type = ResourceType::LAST_TYPE; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extracts from |request| information for the keys requestId, url, method, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// frameId, tabId, type, and timeStamp and writes these into |out| to be passed 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on to extensions. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtractRequestInfo(net::URLRequest* request, DictionaryValue* out) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame = false; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 frame_id = -1; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parent_is_main_frame = false; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 parent_frame_id = -1; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frame_id_for_extension = -1; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int parent_frame_id_for_extension = -1; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_id = -1; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_id = -1; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id = -1; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id = -1; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::Type resource_type = ResourceType::LAST_TYPE; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parent_is_main_frame, &parent_frame_id, &tab_id, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &window_id, &render_process_host_id, &routing_id, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &resource_type); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_id_for_extension = GetFrameId(is_main_frame, frame_id); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_id_for_extension = GetFrameId(parent_is_main_frame, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_id); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetString(keys::kRequestIdKey, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Uint64ToString(request->identifier())); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetString(keys::kUrlKey, request->url().spec()); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetString(keys::kMethodKey, request->method()); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetInteger(keys::kFrameIdKey, frame_id_for_extension); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetInteger(keys::kTabIdKey, tab_id); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type)); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extracts the body from |request| and writes the data into |out|. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtractRequestInfoBody(const net::URLRequest* request, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* out) { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const net::UploadDataStream* upload_data = request->get_upload(); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!upload_data || 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (request->method() != "POST" && request->method() != "PUT")) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" . 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* requestBody = new DictionaryValue(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->Set(keys::kRequestBodyKey, requestBody); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the data presenters, ordered by how specific they are. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ParsedDataPresenter parsed_data_presenter(*request); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::RawDataPresenter raw_data_presenter; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::UploadDataPresenter* const presenters[] = { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parsed_data_presenter, // 1: any parseable forms? (Specific to forms.) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &raw_data_presenter // 2: any data at all? (Non-specific.) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keys for the results of the corresponding presenters. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* const kKeys[] = { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kRequestBodyFormDataKey, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kRequestBodyRawKey 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ScopedVector<net::UploadElementReader>& readers = 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_data->element_readers(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool some_succeeded = false; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; !some_succeeded && i < arraysize(presenters); ++i) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<net::UploadElementReader>::const_iterator reader; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (reader = readers.begin(); reader != readers.end(); ++reader) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) presenters[i]->FeedNext(**reader); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (presenters[i]->Succeeded()) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requestBody->Set(kKeys[i], presenters[i]->Result().release()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) some_succeeded = true; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!some_succeeded) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requestBody->SetString(keys::kRequestBodyErrorKey, "Unknown error."); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true if successful. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FromHeaderDictionary(const DictionaryValue* header_value, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* name, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* value) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_value->GetString(keys::kHeaderNameKey, name)) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We require either a "value" or a "binaryValue" entry. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(header_value->HasKey(keys::kHeaderValueKey) ^ 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_value->HasKey(keys::kHeaderBinaryValueKey))) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_value->HasKey(keys::kHeaderValueKey)) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_value->GetString(keys::kHeaderValueKey, value)) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (header_value->HasKey(keys::kHeaderBinaryValueKey)) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue* list = NULL; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_value->GetList(keys::kHeaderBinaryValueKey, &list) || 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !helpers::CharListToString(list, value)) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts the |name|, |value| pair of a http header to a HttpHeaders 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dictionary. Ownership is passed to the caller. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* ToHeaderDictionary(const std::string& name, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* header = new DictionaryValue(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->SetString(keys::kHeaderNameKey, name); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsStringUTF8(value)) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->SetString(keys::kHeaderValueKey, value); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->Set(keys::kHeaderBinaryValueKey, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::StringToCharList(value)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return header; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a list of HttpHeaders (see the extension API JSON). If |headers| is 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NULL, the list is empty. Ownership is passed to the caller. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ListValue* GetResponseHeadersList(const net::HttpResponseHeaders* headers) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* headers_value = new ListValue(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* iter = NULL; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (headers->EnumerateHeaderLines(&iter, &name, &value)) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_value->Append(ToHeaderDictionary(name, value)); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return headers_value; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ListValue* GetRequestHeadersList(const net::HttpRequestHeaders& headers) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* headers_value = new ListValue(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext(); ) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_value->Append(ToHeaderDictionary(it.name(), it.value())); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return headers_value; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a StringValue with the status line of |headers|. If |headers| is 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NULL, an empty string is returned. Ownership is passed to the caller. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringValue* GetStatusLine(net::HttpResponseHeaders* headers) { 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new StringValue(headers ? headers->GetStatusLine() : std::string()); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RemoveEventListenerOnUI( 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void* profile_id, 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& event_name, 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int process_id, 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id) { 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Profile* profile = reinterpret_cast<Profile*>(profile_id); 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!g_browser_process->profile_manager()->IsValidProfile(profile)) 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extensions::EventRouter* event_router = 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extensions::ExtensionSystem::Get(profile)->event_router(); 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!event_router) 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost* process = 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost::FromID(process_id); 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!process) 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_router->RemoveEventListener(event_name, process, extension_id); 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Sends an event to subscribers of chrome.declarativeWebRequest.onMessage. 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |extension_id| identifies the extension that sends and receives the event. 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |event_argument| is passed to the event listener. 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SendOnMessageEventOnUI( 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* profile_id, 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> event_argument) { 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = reinterpret_cast<Profile*>(profile_id); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!g_browser_process->profile_manager()->IsValidProfile(profile)) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> event_args(new ListValue); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_args->Append(event_argument.release()); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::EventRouter* event_router = 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem::Get(profile)->event_router(); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<extensions::Event> event(new extensions::Event( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) declarative_keys::kOnMessage, event_args.Pass(), profile, 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(), extensions::EventRouter::USER_GESTURE_UNKNOWN, 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::EventFilteringInfo())); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_router->DispatchEventToExtension(extension_id, event.Pass()); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Represents a single unique listener to an event, along with whatever filter 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters and extra_info_spec were specified at the time the listener was 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// added. 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// not play well with event pages. See downloads.onDeterminingFilename and 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ExtensionDownloadsEventRouter for an alternative approach. 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionWebRequestEventRouter::EventListener { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_name; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sub_event_name; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestFilter filter; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec; 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id; 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int embedder_routing_id; 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Sender> ipc_sender; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable std::set<uint64> blocked_requests; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Comparator to work with std::set. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator<(const EventListener& that) const { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id < that.extension_id) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id == that.extension_id && 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub_event_name < that.sub_event_name) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener() : extra_info_spec(0) {} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contains info about requests that are blocked waiting for a response from 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an extension. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionWebRequestEventRouter::BlockedRequest { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request that is being blocked. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Whether the request originates from an incognito tab. 4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_incognito; 4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event that we're currently blocked on. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventTypes event; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The number of event handlers that we are awaiting a response from. 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_handlers_blocking; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pointer to NetLog to report significant changes to the request for 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // debugging. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog* net_log; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback to call when we get a response from all event handlers. 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If non-empty, this contains the new URL that the request will redirect to. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only valid for OnBeforeRequest. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* new_url; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request headers that will be issued along with this request. Only valid 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for OnBeforeSendHeaders. 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* request_headers; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The response headers that were received from the server. Only valid for 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnHeadersReceived. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<const net::HttpResponseHeaders> original_response_headers; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location where to override response headers. Only valid for 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnHeadersReceived. 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::HttpResponseHeaders>* override_response_headers; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If non-empty, this contains the auth credentials that may be filled in. 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only valid for OnAuthRequired. 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::AuthCredentials* auth_credentials; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback to invoke for auth. If |auth_callback.is_null()| is false, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |callback| must be NULL. 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only valid for OnAuthRequired. 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AuthCallback auth_callback; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Time the request was paused. Used for logging purposes. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time blocking_time; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Changes requested by extensions. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas response_deltas; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provider of meta data about extensions, only used and non-NULL for events 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that are delayed until the rules registry is ready. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest() 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request(NULL), 4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch is_incognito(false), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event(kInvalidEvent), 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_handlers_blocking(0), 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log(NULL), 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_url(NULL), 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_headers(NULL), 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_response_headers(NULL), 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_credentials(NULL), 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map(NULL) {} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DictionaryValue& value, std::string* error) { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.HasKey("urls")) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DictionaryValue::Iterator it(value); !it.IsAtEnd(); it.Advance()) { 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it.key() == "urls") { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue* urls_value = NULL; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsList(&urls_value)) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < urls_value->GetSize(); ++i) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern pattern( 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS | 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern::SCHEME_FTP | URLPattern::SCHEME_FILE | 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLPattern::SCHEME_EXTENSION); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!urls_value->GetString(i, &url) || 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern.Parse(url) != URLPattern::PARSE_SUCCESS) { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *error = ErrorUtils::FormatErrorMessage( 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kInvalidRequestFilterUrl, url); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls.AddPattern(pattern); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (it.key() == "types") { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue* types_value = NULL; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsList(&types_value)) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < types_value->GetSize(); ++i) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string type_str; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::Type type; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!types_value->GetString(i, &type_str) || 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !helpers::ParseResourceType(type_str, &type)) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types.push_back(type); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (it.key() == "tabId") { 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsInteger(&tab_id)) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (it.key() == "windowId") { 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!it.value().GetAsInteger(&window_id)) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue& value, int* extra_info_spec) { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec = 0; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < value.GetSize(); ++i) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.GetString(i, &str)) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == "requestHeaders") 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= REQUEST_HEADERS; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "responseHeaders") 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= RESPONSE_HEADERS; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "blocking") 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= BLOCKING; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "asyncBlocking") 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= ASYNC_BLOCKING; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (str == "requestBody") 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *extra_info_spec |= REQUEST_BODY; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BLOCKING and ASYNC_BLOCKING are mutually exclusive. 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING)) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::EventResponse::EventResponse( 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, const base::Time& extension_install_time) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : extension_id(extension_id), 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_install_time(extension_install_time), 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel(false) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::EventResponse::~EventResponse() { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::RequestFilter::RequestFilter() 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : tab_id(-1), window_id(-1) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::RequestFilter::~RequestFilter() { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionWebRequestEventRouter 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter* ExtensionWebRequestEventRouter::GetInstance() { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<ExtensionWebRequestEventRouter>::get(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request_time_tracker_(new ExtensionWebRequestTimeTracker) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::RegisterRulesRegistry( 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry) { 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules_registry.get()) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_registries_[profile] = rules_registry; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_registries_.erase(profile); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::OnBeforeRequest( 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* new_url) { 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPageLoad(request)) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyPageLoad(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestStartTime(request->identifier(), 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now(), 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->url(), 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether to initialized blocked_requests_. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialize_blocked_requests = false; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessDeclarativeRules(profile, extension_info_map, 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRequestEvent, request, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ON_BEFORE_REQUEST, NULL); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRequestEvent, request, 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners.empty() && 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::REQUEST_BODY) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoBody(request, dict); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialize_blocked_requests) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; // Nobody saw a reason for modifying the request. 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnBeforeRequest; 6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 6607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IsIncognitoProfile(profile); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].callback = callback; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].new_url = new_url; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no blocking handlers, only the declarative rules tried 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to modify the request and we can respond synchronously. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExecuteDeltas(profile, request->identifier(), 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* call_callback*/); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::OnBeforeSendHeaders( 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* headers) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialize_blocked_requests = false; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessDeclarativeRules(profile, extension_info_map, 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeSendHeadersEvent, request, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ON_BEFORE_SEND_HEADERS, NULL); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeSendHeadersEvent, request, 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extra_info_spec); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners.empty() && 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) { 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(*headers)); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialize_blocked_requests) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; // Nobody saw a reason for modifying the request. 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnBeforeSendHeaders; 7167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 7177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IsIncognitoProfile(profile); 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].callback = callback; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].request_headers = headers; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no blocking handlers, only the declarative rules tried 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to modify the request and we can respond synchronously. 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExecuteDeltas(profile, request->identifier(), 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* call_callback*/); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnSendHeaders( 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetAndSetSignaled(request->identifier(), kOnSendHeaders)) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnBeforeRedirect); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnSendHeadersEvent, request, 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(headers)); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::OnHeadersReceived( 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback, 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpResponseHeaders* original_response_headers, 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::HttpResponseHeaders>* override_response_headers) { 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialize_blocked_requests = false; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessDeclarativeRules(profile, extension_info_map, 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnHeadersReceivedEvent, request, 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ON_HEADERS_RECEIVED, 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnHeadersReceivedEvent, request, 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extra_info_spec); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listeners.empty() && 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kStatusLineKey, 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers->GetStatusLine()); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(original_response_headers)); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_blocked_requests |= 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!initialize_blocked_requests) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; // Nobody saw a reason for modifying the request. 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnHeadersReceived; 8137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 8147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IsIncognitoProfile(profile); 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].callback = callback; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].override_response_headers = 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) override_response_headers; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].original_response_headers = 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) { 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no blocking handlers, only the declarative rules tried 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to modify the request and we can respond synchronously. 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExecuteDeltas(profile, request->identifier(), 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /* call_callback*/); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::NetworkDelegate::AuthRequiredResponse 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::OnAuthRequired( 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::AuthChallengeInfo& auth_info, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::NetworkDelegate::AuthCallback& callback, 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::AuthCredentials* credentials) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No profile means that this is for authentication challenges in the 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system context. Skip in that case. Also skip sensitive requests. 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnAuthRequiredEvent, request, 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kIsProxyKey, auth_info.is_proxy); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!auth_info.scheme.empty()) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kSchemeKey, auth_info.scheme); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!auth_info.realm.empty()) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kRealmKey, auth_info.realm); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* challenger = new DictionaryValue(); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenger->SetString(keys::kHostKey, auth_info.challenger.host()); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) challenger->SetInteger(keys::kPortKey, auth_info.challenger.port()); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kChallengerKey, challenger); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DispatchEvent(profile, request, listeners, args)) { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].event = kOnAuthRequired; 8767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 8777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IsIncognitoProfile(profile); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blocked_requests_[request->identifier()].request = request; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].auth_callback = callback; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].auth_credentials = credentials; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].net_log = &request->net_log(); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnBeforeRedirect( 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& new_location) { 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect)) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnBeforeRequest); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnBeforeSendHeaders); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnSendHeaders); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearSignaled(request->identifier(), kOnHeadersReceived); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnBeforeRedirectEvent, request, 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int http_status_code = request->GetResponseCode(); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kRedirectUrlKey, new_location.spec()); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kStatusCodeKey, http_status_code); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnResponseStarted( 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) { 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebRequestPermissions::HideRequest(extension_info_map, request)) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnResponseStarted is even triggered, when the request was cancelled. 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->status().status() != net::URLRequestStatus::SUCCESS) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnResponseStartedEvent, request, 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UrlRequestFileJobs do not send headers, so we simulate their behavior. 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code = 200; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->response_headers()) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code = request->response_headers()->response_code(); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kStatusCodeKey, response_code); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnCompleted( 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) { 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, if the request first became sensitive after redirecting we have 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already signaled it and thus we have to signal the end of it. This is 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // risk-free because the handler cannot modify the request now. 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (WebRequestPermissions::HideRequest(extension_info_map, request) && 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !WasSignaled(*request))) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestEndTime(request->identifier(), 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPendingCallbacks(request); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnCompletedEvent, request, &extra_info_spec); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UrlRequestFileJobs do not send headers, so we simulate their behavior. 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_code = 200; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->response_headers()) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code = request->response_headers()->response_code(); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kStatusCodeKey, response_code); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kResponseHeadersKey, 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetResponseHeadersList(request->response_headers())); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnErrorOccurred( 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool started) { 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hide events from the system context as well as sensitive requests. 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, if the request first became sensitive after redirecting we have 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already signaled it and thus we have to signal the end of it. This is 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // risk-free because the handler cannot modify the request now. 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (WebRequestPermissions::HideRequest(extension_info_map, request) && 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !WasSignaled(*request))) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestEndTime(request->identifier(), 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request->status().status() == net::URLRequestStatus::FAILED || 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->status().status() == net::URLRequestStatus::CANCELED); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPendingCallbacks(request); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const EventListener*> listeners = 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListeners(profile, extension_info_map, 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kOnErrorOccurredEvent, request, 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &extra_info_spec); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners.empty()) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue(); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfo(request, dict); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (started) { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_ip = request->GetSocketAddress().host(); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_ip.empty()) 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kIpKey, response_ip); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kFromCache, request->was_cached()); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kErrorKey, 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ErrorToString(request->status().error())); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(profile, request, listeners, args); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnURLRequestDestroyed( 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, net::URLRequest* request) { 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearPendingCallbacks(request); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaled_requests_.erase(request->identifier()); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->LogRequestEndTime(request->identifier(), 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::ClearPendingCallbacks( 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) { 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request->identifier()); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::DispatchEvent( 10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* profile_id, 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<const EventListener*>& listeners, 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue& args) { 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pairs into a single message sent to a list of sub_event_names. 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_handlers_blocking = 0; 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<const EventListener*>::const_iterator it = listeners.begin(); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); ++it) { 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filter out the optional keys that this listener didn't request. 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ListValue> args_filtered(args.DeepCopy()); 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = NULL; 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(args_filtered->GetDictionary(0, &dict) && dict); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!((*it)->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)) 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Remove(keys::kRequestHeadersKey, NULL); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!((*it)->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS)) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Remove(keys::kResponseHeadersKey, NULL); 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::EventRouter::DispatchEvent( 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*it)->ipc_sender.get(), profile_id, 11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*it)->extension_id, (*it)->sub_event_name, 1118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) args_filtered.Pass(), 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::EventRouter::USER_GESTURE_UNKNOWN, 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::EventFilteringInfo()); 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->extra_info_spec & 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->blocked_requests.insert(request->identifier()); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_handlers_blocking; 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->SetLoadStateParam( 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16(IDS_LOAD_STATE_PARAMETER_EXTENSION, 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16((*it)->extension_name))); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_handlers_blocking > 0) { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].request = request; 11347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 11357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IsIncognitoProfile(profile_id); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].num_handlers_blocking += 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_handlers_blocking; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnEventHandled( 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sub_event_name, 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventResponse* response) { 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener listener; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_id = extension_id; 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.sub_event_name = sub_event_name; 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The listener may have been removed (e.g. due to the process going away) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before we got here. 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventListener>::iterator found = 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[profile][event_name].find(listener); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != listeners_[profile][event_name].end()) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found->blocked_requests.erase(request_id); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecrementBlockCount(profile, extension_id, event_name, request_id, response); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::AddEventListener( 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_name, 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sub_event_name, 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RequestFilter& filter, 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec, 117590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id, 1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int embedder_routing_id, 1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id, 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Sender> ipc_sender) { 117990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsWebRequestEvent(event_name)) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener listener; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_id = extension_id; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_name = extension_name; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.sub_event_name = sub_event_name; 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.filter = filter; 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extra_info_spec = extra_info_spec; 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.ipc_sender = ipc_sender; 119090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listener.embedder_process_id = embedder_process_id; 1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) listener.embedder_routing_id = embedder_routing_id; 1192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) listener.webview_instance_id = webview_instance_id; 11937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (listener.webview_instance_id) 11947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RecordAction(content::UserMetricsAction("WebView.WebRequest.AddListener")); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners_[profile][event_name].count(listener) != 0u) { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is likely an abuse of the API by a malicious extension. 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[profile][event_name].insert(listener); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::RemoveEventListener( 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sub_event_name) { 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t slash_sep = sub_event_name.find('/'); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name = sub_event_name.substr(0, slash_sep); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsWebRequestEvent(event_name)) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListener listener; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.extension_id = extension_id; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener.sub_event_name = sub_event_name; 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible for AddEventListener to fail asynchronously. In that case, 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the renderer believes the listener exists, while the browser does not. 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore a RemoveEventListener in that case. 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventListener>::iterator found = 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[profile][event_name].find(listener); 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == listeners_[profile][event_name].end()) 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) << 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extension=" << extension_id << " event=" << event_name; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unblock any request that this event listener may have been blocking. 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<uint64>::iterator it = found->blocked_requests.begin(); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != found->blocked_requests.end(); ++it) { 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecrementBlockCount(profile, extension_id, event_name, *it, NULL); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[profile][event_name].erase(listener); 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ClearCacheOnNavigation(); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 124090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( 124190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void* profile, 124290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id, 124390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id, 1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id) { 124590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Iterate over all listeners of all WebRequest events to delete 124690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // any listeners that belong to the provided <webview>. 124790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ListenerMapForProfile& map_for_profile = listeners_[profile]; 124890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (ListenerMapForProfile::iterator event_iter = map_for_profile.begin(); 124990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_iter != map_for_profile.end(); ++event_iter) { 125090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<EventListener> listeners_to_delete; 125190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<EventListener>& listeners = event_iter->second; 125290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::set<EventListener>::iterator listener_iter = listeners.begin(); 125390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listener_iter != listeners.end(); ++listener_iter) { 125490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const EventListener& listener = *listener_iter; 125590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (listener.embedder_process_id == embedder_process_id && 1256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) listener.webview_instance_id == webview_instance_id) 125790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listeners_to_delete.push_back(listener); 125890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 125990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < listeners_to_delete.size(); ++i) { 126090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EventListener& listener = listeners_to_delete[i]; 126190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserThread::PostTask( 126290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserThread::UI, 126390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 126490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&RemoveEventListenerOnUI, 126590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile, 126690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listener.sub_event_name, 126790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) embedder_process_id, 126890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_id)); 126990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 127090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 127190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 127290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnOTRProfileCreated( 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* original_profile, void* otr_profile) { 12757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cross_profile_map_[original_profile] = std::make_pair(false, otr_profile); 12767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cross_profile_map_[otr_profile] = std::make_pair(true, original_profile); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed( 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* original_profile, void* otr_profile) { 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cross_profile_map_.erase(otr_profile); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cross_profile_map_.erase(original_profile); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks_for_page_load_.push_back(callback); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::IsPageLoad( 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request) const { 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame = false; 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 frame_id = -1; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parent_is_main_frame = false; 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 parent_frame_id = -1; 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_id = -1; 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_id = -1; 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id = -1; 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id = -1; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::Type resource_type = ResourceType::LAST_TYPE; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parent_is_main_frame, &parent_frame_id, 13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &tab_id, &window_id, &render_process_host_id, 13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &routing_id, &resource_type); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resource_type == ResourceType::MAIN_FRAME; 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::NotifyPageLoad() { 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CallbacksForPageLoad::const_iterator i = 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks_for_page_load_.begin(); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != callbacks_for_page_load_.end(); ++i) { 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->Run(); 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks_for_page_load_.clear(); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ExtensionWebRequestEventRouter::GetCrossProfile(void* profile) const { 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossProfileMap::const_iterator cross_profile = 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cross_profile_map_.find(profile); 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cross_profile == cross_profile_map_.end()) 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 13247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return cross_profile->second.second; 13257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 13267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 13277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool ExtensionWebRequestEventRouter::IsIncognitoProfile(void* profile) const { 13287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CrossProfileMap::const_iterator cross_profile = 13297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cross_profile_map_.find(profile); 13307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (cross_profile == cross_profile_map_.end()) 13317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 13327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return cross_profile->second.first; 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::WasSignaled( 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequest& request) const { 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignaledRequestMap::const_iterator flag = 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaled_requests_.find(request.identifier()); 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (flag != signaled_requests_.end()) && (flag->second != 0); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool crosses_incognito, 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_id, 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_id, 13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id, 13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id, 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::Type resource_type, 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_async_request, 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_request_from_extension, 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* extra_info_spec, 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const ExtensionWebRequestEventRouter::EventListener*>* 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching_listeners) { 135890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string web_request_event_name(event_name); 1359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionRendererState::WebViewInfo webview_info; 13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_guest = ExtensionRendererState::GetInstance()-> 1361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetWebViewInfo(render_process_host_id, routing_id, &webview_info); 136290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_guest) 136390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_request_event_name.replace(0, sizeof(kWebRequest) - 1, kWebView); 136490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 136590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<EventListener>& listeners = 136690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listeners_[profile][web_request_event_name]; 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<EventListener>::iterator it = listeners.begin(); 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); ++it) { 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->ipc_sender.get()) { 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The IPC sender has been deleted. This listener will be removed soon 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via a call to RemoveEventListener. For now, just skip it. 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_guest && 1376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (it->embedder_process_id != webview_info.embedder_process_id || 1377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->embedder_routing_id != webview_info.embedder_routing_id || 1378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) it->webview_instance_id != webview_info.instance_id)) 13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->filter.window_id != -1 && window_id != it->filter.window_id) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!it->filter.types.empty() && 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(it->filter.types.begin(), it->filter.types.end(), 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_type) == it->filter.types.end()) 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!is_guest && !WebRequestPermissions::CanExtensionAccessURL( 1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_info_map, it->extension_id, url, crosses_incognito, 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebRequestPermissions::REQUIRE_HOST_PERMISSION)) 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool blocking_listener = 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (it->extra_info_spec & 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not want to notify extensions about XHR requests that are 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // triggered by themselves. This is a workaround to prevent deadlocks 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in case of synchronous XHR requests that block the extension renderer 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and therefore prevent the extension from processing the request 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handler. This is only a problem for blocking listeners. 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/105656 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool synchronous_xhr_from_extension = !is_async_request && 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_request_from_extension && resource_type == ResourceType::XHR; 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only send webRequest events for URLs the extension has access to. 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocking_listener && synchronous_xhr_from_extension) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching_listeners->push_back(&(*it)); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec |= it->extra_info_spec; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<const ExtensionWebRequestEventRouter::EventListener*> 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionWebRequestEventRouter::GetMatchingListeners( 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* extra_info_spec) { 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): handle profile == NULL (should collect all listeners). 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extra_info_spec = 0; 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame = false; 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 frame_id = -1; 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parent_is_main_frame = false; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 parent_frame_id = -1; 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_id = -1; 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int window_id = -1; 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_host_id = -1; 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int routing_id = -1; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::Type resource_type = ResourceType::LAST_TYPE; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url = request->url(); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parent_is_main_frame, &parent_frame_id, 14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &tab_id, &window_id, &render_process_host_id, 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &routing_id, &resource_type); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const ExtensionWebRequestEventRouter::EventListener*> 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matching_listeners; 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_request_from_extension = 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsRequestFromExtension(request, extension_info_map); 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are conservative here and assume requests are asynchronous in case 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we don't have an info object. We don't want to risk a deadlock. 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_async_request = !info || info->IsAsync(); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListenersImpl( 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile, extension_info_map, false, event_name, url, 14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_id, window_id, render_process_host_id, routing_id, resource_type, 14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_async_request, is_request_from_extension, extra_info_spec, 14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &matching_listeners); 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* cross_profile = GetCrossProfile(profile); 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cross_profile) { 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMatchingListenersImpl( 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cross_profile, extension_info_map, true, event_name, url, tab_id, 14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_id, render_process_host_id, routing_id, resource_type, 14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_async_request, is_request_from_extension, extra_info_spec, 14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &matching_listeners); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return matching_listeners; 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)helpers::EventResponseDelta* CalculateDelta( 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::BlockedRequest* blocked_request, 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::EventResponse* response) { 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (blocked_request->event) { 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeRequest: 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnBeforeRequestDelta( 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, response->new_url); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnBeforeSendHeaders: { 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* old_headers = blocked_request->request_headers; 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::HttpRequestHeaders* new_headers = response->request_headers.get(); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnBeforeSendHeadersDelta( 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, old_headers, new_headers); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnHeadersReceived: { 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpResponseHeaders* old_headers = 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request->original_response_headers.get(); 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ResponseHeaders* new_headers = 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->response_headers.get(); 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnHeadersReceivedDelta( 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, old_headers, new_headers); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ExtensionWebRequestEventRouter::kOnAuthRequired: 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helpers::CalculateOnAuthRequiredDelta( 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->extension_id, response->extension_install_time, 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel, &response->auth_credentials); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Value* SerializeResponseHeaders(const helpers::ResponseHeaders& headers) { 1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ListValue> serialized_headers(new ListValue()); 1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (helpers::ResponseHeaders::const_iterator i = headers.begin(); 1513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i != headers.end(); ++i) { 1514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) serialized_headers->Append(ToHeaderDictionary(i->first, i->second)); 1515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return serialized_headers.release(); 1517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Convert a RequestCookieModifications/ResponseCookieModifications object to a 1520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ListValue which summarizes the changes made. This is templated since the 1521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// two types (request/response) are different but contain essentially the same 1522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// fields. 1523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename CookieType> 1524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ListValue* SummarizeCookieModifications( 1525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<linked_ptr<CookieType> >& modifications) { 1526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ListValue> cookie_modifications(new ListValue()); 1527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (typename std::vector<linked_ptr<CookieType> >::const_iterator i = 1528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) modifications.begin(); 1529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i != modifications.end(); ++i) { 1530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<DictionaryValue> summary(new DictionaryValue()); 1531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CookieType& mod = *i->get(); 1532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (mod.type) { 1533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case helpers::ADD: 1534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModificationTypeKey, 1535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kCookieModificationAdd); 1536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case helpers::EDIT: 1538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModificationTypeKey, 1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kCookieModificationEdit); 1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case helpers::REMOVE: 1542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModificationTypeKey, 1543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kCookieModificationRemove); 1544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.filter) { 1547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.filter->name) 1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieFilterNameKey, 1549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.filter->domain) 1551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieFilterDomainKey, 1552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.modification) { 1555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.modification->name) 1556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModDomainKey, 1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mod.modification->domain) 1559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) summary->SetString(activitylog::kCookieModDomainKey, 1560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *mod.modification->name); 1561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cookie_modifications->Append(summary.release()); 1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return cookie_modifications.release(); 1565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converts an EventResponseDelta object to a dictionary value suitable for the 15687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// activity log. 15697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<DictionaryValue> SummarizeResponseDelta( 1570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& event_name, 1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const helpers::EventResponseDelta& delta) { 1572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<DictionaryValue> details(new DictionaryValue()); 1573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (delta.cancel) { 1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->SetBoolean(activitylog::kCancelKey, true); 1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.new_url.is_empty()) { 1577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->SetString(activitylog::kNewUrlKey, delta.new_url.spec()); 1578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ListValue> modified_headers(new ListValue()); 1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::HttpRequestHeaders::Iterator iter(delta.modified_request_headers); 1582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (iter.GetNext()) { 1583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) modified_headers->Append(ToHeaderDictionary(iter.name(), iter.value())); 1584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!modified_headers->empty()) { 1586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kModifiedRequestHeadersKey, 1587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) modified_headers.release()); 1588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ListValue> deleted_headers(new ListValue()); 1591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deleted_headers->AppendStrings(delta.deleted_request_headers); 1592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!deleted_headers->empty()) { 1593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kDeletedRequestHeadersKey, 1594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) deleted_headers.release()); 1595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.added_response_headers.empty()) { 1598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kAddedRequestHeadersKey, 1599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SerializeResponseHeaders(delta.added_response_headers)); 1600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.deleted_response_headers.empty()) { 1602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set(activitylog::kDeletedResponseHeadersKey, 1603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SerializeResponseHeaders(delta.deleted_response_headers)); 1604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (delta.auth_credentials) { 1606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->SetString(activitylog::kAuthCredentialsKey, 1607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UTF16ToUTF8(delta.auth_credentials->username()) + ":*"); 1608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!delta.response_cookie_modifications.empty()) { 1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) details->Set( 1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activitylog::kResponseCookieModificationsKey, 1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SummarizeCookieModifications(delta.response_cookie_modifications)); 1614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return details.Pass(); 1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid LogExtensionActivity(void* profile_id, 16207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_incognito, 1621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id, 1622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& url, 1623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& api_call, 16247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<DictionaryValue> details) { 1625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 1626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, 1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&LogExtensionActivity, 16297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch profile_id, 16307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch is_incognito, 1631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_id, 1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url, 1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) api_call, 16347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Passed(&details))); 1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 16367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Profile* profile = static_cast<Profile*>(profile_id); 16377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!g_browser_process->profile_manager()->IsValidProfile(profile)) 16387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1639a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<extensions::Action> action = 1640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new extensions::Action(extension_id, 1641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Time::Now(), 1642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extensions::Action::ACTION_WEB_REQUEST, 1643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) api_call); 1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_page_url(url); 1645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->set_page_incognito(is_incognito); 1646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) action->mutable_other()->Set(activity_log_constants::kActionWebRequest, 1647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) details.release()); 1648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extensions::ActivityLog::GetInstance(profile)->LogAction(action); 1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::DecrementBlockCount( 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventResponse* response) { 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<EventResponse> response_scoped(response); 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that this request was deleted, or cancelled by a previous 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event handler. If so, ignore this response. 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_.find(request_id) == blocked_requests_.end()) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest& blocked_request = blocked_requests_[request_id]; 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_handlers_blocking = --blocked_request.num_handlers_blocking; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(num_handlers_blocking, 0); 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response) { 1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) helpers::EventResponseDelta* delta = 1673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CalculateDelta(&blocked_request, response); 1674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (extensions::ActivityLog::IsLogEnabledOnAnyProfile()) { 16767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LogExtensionActivity(profile, 16777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_request.is_incognito, 1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_id, 1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_request.request->url(), 1680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_name, 1681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SummarizeResponseDelta(event_name, *delta)); 1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas.push_back( 1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) linked_ptr<helpers::EventResponseDelta>(delta)); 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta block_time = 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - blocked_request.blocking_time; 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_id.empty()) { 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->IncrementExtensionBlockTime( 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id, request_id, block_time); 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |extension_id| is empty for requests blocked on startup waiting for the 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // declarative rules to be read from disk. 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayStartup", block_time); 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_handlers_blocking == 0) { 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExecuteDeltas(profile, request_id, true); 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the URLRequest to indicate it is now blocked on a different 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension. 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventListener>& listeners = listeners_[profile][event_name]; 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<EventListener>::iterator it = listeners.begin(); 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); ++it) { 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->blocked_requests.count(request_id)) { 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.request->SetLoadStateParam( 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16(IDS_LOAD_STATE_PARAMETER_EXTENSION, 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16(it->extension_name))); 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionWebRequestEventRouter::SendMessages( 17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* profile, 17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BlockedRequest& blocked_request) { 17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (helpers::EventResponseDeltas::const_iterator delta = deltas.begin(); 17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delta != deltas.end(); ++delta) { 17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<std::string>& messages = (*delta)->messages_to_extension; 17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<std::string>::const_iterator message = messages.begin(); 17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message != messages.end(); ++message) { 17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> argument(new base::DictionaryValue); 17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtractRequestInfo(blocked_request.request, argument.get()); 17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) argument->SetString(keys::kMessageKey, *message); 17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) argument->SetString(keys::kStageKey, 17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestStageAsString(blocked_request.event)); 17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SendOnMessageEventOnUI, 17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile, 17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*delta)->extension_id, 17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&argument))); 17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionWebRequestEventRouter::ExecuteDeltas( 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool call_callback) { 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest& blocked_request = blocked_requests_[request_id]; 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(blocked_request.num_handlers_blocking == 0); 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas& deltas = blocked_request.response_deltas; 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta block_time = 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - blocked_request.blocking_time; 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->IncrementTotalBlockTime(request_id, block_time); 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool credentials_set = false; 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.sort(&helpers::InDecreasingExtensionInstallationTimeOrder); 17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionWarningSet warnings; 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool canceled = false; 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeCancelOfResponses( 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &canceled, 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_request.event == kOnBeforeRequest) { 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.callback.is_null()); 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeOnBeforeRequestResponses( 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.new_url, 17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.event == kOnBeforeSendHeaders) { 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.callback.is_null()); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeOnBeforeSendHeadersResponses( 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.request_headers, 17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.event == kOnHeadersReceived) { 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.callback.is_null()); 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::MergeOnHeadersReceivedResponses( 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.original_response_headers.get(), 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.override_response_headers, 17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.event == kOnAuthRequired) { 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(blocked_request.callback.is_null()); 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!blocked_request.auth_callback.is_null()); 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials_set = helpers::MergeOnAuthRequiredResponses( 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.response_deltas, 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.auth_credentials, 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &warnings, 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.net_log); 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendMessages(profile, blocked_request); 18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!warnings.empty()) { 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionWarningService::NotifyWarningsOnUI, 18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile, warnings)); 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (canceled) { 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->SetRequestCanceled(request_id); 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (blocked_request.new_url && 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !blocked_request.new_url->is_empty()) { 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_time_tracker_->SetRequestRedirected(request_id); 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This triggers onErrorOccurred if canceled is true. 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = canceled ? net::ERR_BLOCKED_BY_CLIENT : net::OK; 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!blocked_request.callback.is_null()) { 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback callback = blocked_request.callback; 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that request is removed before callback because the callback 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // might trigger the next event. 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request_id); 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (call_callback) 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(rv); 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!blocked_request.auth_callback.is_null()) { 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AuthRequiredResponse response = 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (canceled) { 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH; 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (credentials_set) { 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response = net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate::AuthCallback callback = blocked_request.auth_callback; 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request_id); 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (call_callback) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(response); 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_.erase(request_id); 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfoMap* extension_info_map, 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::RequestStage request_stage, 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpResponseHeaders* original_response_headers) { 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this check fails, check that the active stages are up-to-date in 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // browser/extensions/api/declarative_webrequest/request_stage.h . 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_stage & extensions::kActiveStages); 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rules of the current |profile| may apply but we need to check also whether 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there are applicable rules from extensions whose background page 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // spans from regular to incognito mode. 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First parameter identifies the registry, the second indicates whether the 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registry belongs to the cross profile. 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::pair<extensions::WebRequestRulesRegistry*, bool> 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelevantRegistry; 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<RelevantRegistry> RelevantRegistries; 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RelevantRegistries relevant_registries; 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules_registries_.find(profile) != rules_registries_.end()) { 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relevant_registries.push_back( 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(rules_registries_[profile].get(), false)); 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* cross_profile = GetCrossProfile(profile); 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cross_profile && 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_registries_.find(cross_profile) != rules_registries_.end()) { 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) relevant_registries.push_back( 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(rules_registries_[cross_profile].get(), true)); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The following block is experimentally enabled and its impact on load time 18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // logged with UMA Extensions.NetworkDelayRegistryLoad. crbug.com/175961 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RelevantRegistries::iterator i = relevant_registries.begin(); 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != relevant_registries.end(); ++i) { 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::WebRequestRulesRegistry* rules_registry = i->first; 188490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!rules_registry->ready().is_signaled()) { 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The rules registry is still loading. Block this request until it 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // finishes. 188790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) rules_registry->ready().Post( 188890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ExtensionWebRequestEventRouter::OnRulesRegistryReady, 189090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr(), 189190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile, 189290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_name, 189390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request->identifier(), 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_stage)); 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].num_handlers_blocking++; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].request = request; 18977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocked_requests_[request->identifier()].is_incognito |= 18987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IsIncognitoProfile(profile); 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].blocking_time = 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now(); 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].original_response_headers = 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_response_headers; 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].extension_info_map = 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map; 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start = base::Time::Now(); 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool deltas_created = false; 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (RelevantRegistries::iterator i = relevant_registries.begin(); 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != relevant_registries.end(); ++i) { 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::WebRequestRulesRegistry* rules_registry = 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->first; 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas result = 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules_registry->CreateDeltas( 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map, 19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::WebRequestData( 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request, request_stage, original_response_headers), 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second); 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.empty()) { 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::EventResponseDeltas& deltas = 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_requests_[request->identifier()].response_deltas; 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas.insert(deltas.end(), result.begin(), result.end()); 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deltas_created = true; 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta elapsed_time = start - base::Time::Now(); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elapsed_time); 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return deltas_created; 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::OnRulesRegistryReady( 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id, 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::RequestStage request_stage) { 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that this request was deleted, or cancelled by a previous 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event handler. If so, ignore this response. 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_requests_.find(request_id) == blocked_requests_.end()) 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockedRequest& blocked_request = blocked_requests_[request_id]; 19492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta block_time = 19502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Now() - blocked_request.blocking_time; 19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.NetworkDelayRegistryLoad", block_time); 19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProcessDeclarativeRules(profile, 1954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) blocked_request.extension_info_map, 1955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) event_name, 1956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) blocked_request.request, 1957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_stage, 1958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) blocked_request.original_response_headers.get()); 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset to NULL so that nobody relies on this being set. 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_request.extension_info_map = NULL; 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecrementBlockCount(profile, std::string(), event_name, request_id, NULL); 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventTypes event_type) { 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == signaled_requests_.end()) { 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaled_requests_[request_id] = event_type; 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_signaled_before = (iter->second & event_type) != 0; 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second |= event_type; 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_signaled_before; 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionWebRequestEventRouter::ClearSignaled(uint64 request_id, 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventTypes event_type) { 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == signaled_requests_.end()) 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second &= ~event_type; 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Special QuotaLimitHeuristic for WebRequestHandlerBehaviorChangedFunction. 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Each call of webRequest.handlerBehaviorChanged() clears the in-memory cache 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of WebKit at the time of the next page load (top level navigation event). 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This quota heuristic is intended to limit the number of times the cache is 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cleared by an extension. 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As we want to account for the number of times the cache is really cleared 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (opposed to the number of times webRequest.handlerBehaviorChanged() is 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// called), we cannot decide whether a call of 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webRequest.handlerBehaviorChanged() should trigger a quota violation at the 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// time it is called. Instead we only decrement the bucket counter at the time 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when the cache is cleared (when page loads happen). 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClearCacheQuotaHeuristic : public QuotaLimitHeuristic { 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearCacheQuotaHeuristic(const Config& config, BucketMapper* map) 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : QuotaLimitHeuristic( 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config, 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map, 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"), 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_registered_(false), 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_(this) {} 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ClearCacheQuotaHeuristic() {} 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Apply(Bucket* bucket, 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time) OVERRIDE; 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback that is triggered by the ExtensionWebRequestEventRouter on a page 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load. 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't need to take care of the life time of |bucket|: It is owned by the 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BucketMapper of our base class in |QuotaLimitHeuristic::bucket_mapper_|. As 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // long as |this| exists, the respective BucketMapper and its bucket will 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exist as well. 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPageLoad(Bucket* bucket); 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag to prevent that we register more than one call back in-between 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clearing the cache. 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool callback_registered_; 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ClearCacheQuotaHeuristic> weak_ptr_factory_; 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ClearCacheQuotaHeuristic); 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ClearCacheQuotaHeuristic::Apply(Bucket* bucket, 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time) { 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_time > bucket->expiration()) 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket->Reset(config(), event_time); 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call bucket->DeductToken() on a new page load, this is when 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // webRequest.handlerBehaviorChanged() clears the cache. 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_registered_) { 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->AddCallbackForPageLoad( 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ClearCacheQuotaHeuristic::OnPageLoad, 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket)); 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_registered_ = true; 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only check whether tokens are left here. Deducting a token happens in 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnPageLoad(). 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bucket->has_tokens(); 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClearCacheQuotaHeuristic::OnPageLoad(Bucket* bucket) { 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_registered_ = false; 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket->DeductToken(); 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebRequestAddEventListener::RunImpl() { 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Argument 0 is the callback, which we don't use here. 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::RequestFilter filter; 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* value = NULL; 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.clear(); 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &value)); 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failure + an empty error string means a fatal error. 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(filter.InitFromValue(*value, &error_) || 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !error_.empty()); 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!error_.empty()) 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_info_spec = 0; 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasOptionalArgument(2)) { 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* value = NULL; 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value)); 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value, &extra_info_spec)); 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name; 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sub_event_name; 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int webview_instance_id = 0; 2082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &webview_instance_id)); 208390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 208490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WeakPtr<ChromeRenderMessageFilter> ipc_sender = ipc_sender_weak(); 208590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 208690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int embedder_process_id = 208790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ipc_sender.get() ? ipc_sender->render_process_id() : -1; 2088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int embedder_routing_id = routing_id(); 208990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map()->extensions().GetByID(extension_id()); 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_name = extension ? extension->name() : extension_id(); 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2094868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool is_guest = webview_instance_id != 0; 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We check automatically whether the extension has the 'webRequest' 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // permission. For blocking calls we require the additional permission 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'webRequestBlocking'. 209890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if ((!is_guest && extra_info_spec & 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !extension->HasAPIPermission( 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::APIPermission::kWebRequestBlocking)) { 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kBlockingPermissionRequired; 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We allow to subscribe to patterns that are broader than the host 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // permissions. E.g., we could subscribe to http://www.example.com/* 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // while having host permissions for http://www.example.com/foo/* and 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://www.example.com/bar/*. 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For this reason we do only a coarse check here to warn the extension 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // developer if he does something obviously wrong. 211390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!is_guest && extensions::PermissionsData::GetEffectiveHostPermissions( 211490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension).is_empty()) { 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kHostPermissionsRequired; 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_id(), extension_id(), extension_name, 212290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) event_name, sub_event_name, filter, extra_info_spec, 2123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) embedder_process_id, embedder_routing_id, webview_instance_id, 2124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ipc_sender_weak()); 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(success); 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ClearCacheOnNavigation(); 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( 2130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &helpers::NotifyWebRequestAPIUsed, 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_id(), make_scoped_refptr(GetExtension()))); 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebRequestEventHandled::RunImpl() { 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name; 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sub_event_name; 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &sub_event_name)); 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string request_id_str; 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &request_id_str)); 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 request_id; 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(base::StringToUint64(request_id_str, 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_id)); 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response; 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasOptionalArgument(3)) { 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* value = NULL; 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(3, &value)); 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value->empty()) { 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time install_time = 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map()->GetInstallTime(extension_id()); 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.reset(new ExtensionWebRequestEventRouter::EventResponse( 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id(), install_time)); 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("cancel")) { 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't allow cancel mixed with other keys. 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("redirectUrl") || value->HasKey("requestHeaders")) { 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kInvalidBlockingResponse; 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool cancel = false; 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetBoolean("cancel", &cancel)); 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->cancel = cancel; 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("redirectUrl")) { 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string new_url_str; 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetString("redirectUrl", 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &new_url_str)); 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->new_url = GURL(new_url_str); 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response->new_url.is_valid()) { 21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_ = ErrorUtils::FormatErrorMessage( 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kInvalidRedirectUrl, new_url_str); 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("requestHeaders")) { 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* request_headers_value = NULL; 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->request_headers.reset(new net::HttpRequestHeaders()); 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetList(keys::kRequestHeadersKey, 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &request_headers_value)); 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < request_headers_value->GetSize(); ++i) { 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* header_value = NULL; 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_headers_value->GetDictionary(i, &header_value)); 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FromHeaderDictionary(header_value, &name, &value)); 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->request_headers->SetHeader(name, value); 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey("responseHeaders")) { 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<helpers::ResponseHeaders> response_headers( 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new helpers::ResponseHeaders()); 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* response_headers_value = NULL; 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetList(keys::kResponseHeadersKey, 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &response_headers_value)); 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < response_headers_value->GetSize(); ++i) { 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* header_value = NULL; 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_headers_value->GetDictionary(i, &header_value)); 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FromHeaderDictionary(header_value, &name, &value)); 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_headers->push_back(helpers::ResponseHeader(name, value)); 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->response_headers.reset(response_headers.release()); 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value->HasKey(keys::kAuthCredentialsKey)) { 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* credentials_value = NULL; 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(value->GetDictionary( 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kAuthCredentialsKey, 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &credentials_value)); 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 username; 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 password; 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials_value->GetString(keys::kUsernameKey, &username)); 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credentials_value->GetString(keys::kPasswordKey, &password)); 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response->auth_credentials.reset( 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::AuthCredentials(username, password)); 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_id(), extension_id(), event_name, sub_event_name, request_id, 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.release()); 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebRequestHandlerBehaviorChangedFunction::GetQuotaLimitHeuristics( 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristics* heuristics) const { 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristic::Config config = { 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See web_request.json for current value. 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_request::MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES, 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMinutes(10) 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristic::BucketMapper* bucket_mapper = 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new QuotaLimitHeuristic::SingletonBucketMapper(); 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearCacheQuotaHeuristic* heuristic = 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ClearCacheQuotaHeuristic(config, bucket_mapper); 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) heuristics->push_back(heuristic); 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebRequestHandlerBehaviorChangedFunction::OnQuotaExceeded( 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& violation_error) { 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post warning message. 22612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionWarningSet warnings; 22622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) warnings.insert( 22632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionWarning::CreateRepeatedCacheFlushesWarning(extension_id())); 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 22672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionWarningService::NotifyWarningsOnUI, 22682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_id(), warnings)); 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Continue gracefully. 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Run(); 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebRequestHandlerBehaviorChangedFunction::RunImpl() { 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::ClearCacheOnNavigation(); 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SendExtensionWebRequestStatusToHost(content::RenderProcessHost* host) { 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile || !profile->GetExtensionService()) 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool adblock = false; 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool adblock_plus = false; 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool other = false; 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionSet* extensions = 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetExtensionService()->extensions(); 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator it = extensions->begin(); 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != extensions->end(); ++it) { 22917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (profile->GetExtensionService()->HasUsedWebRequest(it->get())) { 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->name().find("Adblock Plus") != std::string::npos) { 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adblock_plus = true; 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((*it)->name().find("AdBlock") != std::string::npos) { 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) adblock = true; 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other = true; 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2304