diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-21 19:01:52 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-21 19:01:52 +0000 |
commit | 418da61f84250c962fa0509e53f8f4213505fcac (patch) | |
tree | b98ce1e8ca8ece82e3cea5ae8beb1dab1e11f6db | |
parent | f81f5950b78f7c0161d757d91ff3a3baa96e089b (diff) | |
download | chromium_src-418da61f84250c962fa0509e53f8f4213505fcac.zip chromium_src-418da61f84250c962fa0509e53f8f4213505fcac.tar.gz chromium_src-418da61f84250c962fa0509e53f8f4213505fcac.tar.bz2 |
Provide ID of the frame that triggered an event to the webrequest extension.
BUG=79734
TEST=no
Review URL: http://codereview.chromium.org/7387012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93450 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 466 insertions, 25 deletions
diff --git a/chrome/browser/extensions/extension_webnavigation_api.cc b/chrome/browser/extensions/extension_webnavigation_api.cc index 28ee146..16894407 100644 --- a/chrome/browser/extensions/extension_webnavigation_api.cc +++ b/chrome/browser/extensions/extension_webnavigation_api.cc @@ -32,8 +32,11 @@ const char* kValidSchemes[] = { chrome::kFtpScheme, }; -// Returns 0 if the navigation happens in the main frame, or the frame ID +// Returns the frame ID as it will be passed to the extension: +// 0 if the navigation happens in the main frame, or the frame ID // modulo 32 bits otherwise. +// Keep this in sync with the GetFrameId() function in +// extension_webrequest_api.cc. int GetFrameId(bool is_main_frame, int64 frame_id) { return is_main_frame ? 0 : static_cast<int>(frame_id); } diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc index 1cae4f8..01a9d1f 100644 --- a/chrome/browser/extensions/extension_webrequest_api.cc +++ b/chrome/browser/extensions/extension_webrequest_api.cc @@ -72,6 +72,15 @@ COMPILE_ASSERT( #define ARRAYEND(array) (array + arraysize(array)) +// Returns the frame ID as it will be passed to the extension: +// 0 if the navigation happens in the main frame, or the frame ID +// modulo 32 bits otherwise. +// Keep this in sync with the GetFrameId() function in +// extension_webnavigation_api.cc. +int GetFrameId(bool is_main_frame, int64 frame_id) { + return is_main_frame ? 0 : static_cast<int>(frame_id); +} + bool IsWebRequestEvent(const std::string& event_name) { return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), event_name) != ARRAYEND(kWebRequestEvents); @@ -108,6 +117,8 @@ bool ParseResourceType(const std::string& type_str, } void ExtractRequestInfo(net::URLRequest* request, + bool* is_main_frame, + int64* frame_id, int* tab_id, int* window_id, ResourceType::Type* resource_type) { @@ -118,6 +129,8 @@ void ExtractRequestInfo(net::URLRequest* request, ResourceDispatcherHost::InfoForRequest(request); ExtensionTabIdMap::GetInstance()->GetTabAndWindowId( info->child_id(), info->route_id(), tab_id, window_id); + *frame_id = info->frame_id(); + *is_main_frame = info->is_main_frame(); // Restrict the resource type to the values we care about. ResourceType::Type* iter = @@ -346,10 +359,15 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest( if (!HasWebRequestScheme(request->url())) return net::OK; + bool is_main_frame = false; + int64 frame_id = -1; + int frame_id_for_extension = -1; int tab_id = -1; int window_id = -1; ResourceType::Type resource_type = ResourceType::LAST_TYPE; - ExtractRequestInfo(request, &tab_id, &window_id, &resource_type); + ExtractRequestInfo(request, &is_main_frame, &frame_id, &tab_id, &window_id, + &resource_type); + frame_id_for_extension = GetFrameId(is_main_frame, frame_id); int extra_info_spec = 0; std::vector<const EventListener*> listeners = @@ -368,6 +386,7 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest( base::Uint64ToString(request->identifier())); dict->SetString(keys::kUrlKey, request->url().spec()); dict->SetString(keys::kMethodKey, request->method()); + dict->SetInteger(keys::kFrameIdKey, frame_id_for_extension); dict->SetInteger(keys::kTabIdKey, tab_id); dict->SetString(keys::kTypeKey, ResourceTypeToString(resource_type)); dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); @@ -494,6 +513,16 @@ void ExtensionWebRequestEventRouter::OnBeforeRedirect( if (listeners.empty()) return; + bool is_main_frame = false; + int64 frame_id = -1; + int frame_id_for_extension = -1; + int tab_id = -1; + int window_id = -1; + ResourceType::Type resource_type = ResourceType::LAST_TYPE; + ExtractRequestInfo(request, &is_main_frame, &frame_id, &tab_id, + &window_id, &resource_type); + frame_id_for_extension = GetFrameId(is_main_frame, frame_id); + int http_status_code = request->GetResponseCode(); std::string response_ip = request->GetSocketAddress().host(); @@ -505,6 +534,9 @@ void ExtensionWebRequestEventRouter::OnBeforeRedirect( dict->SetString(keys::kUrlKey, request->url().spec()); dict->SetString(keys::kRedirectUrlKey, new_location.spec()); dict->SetInteger(keys::kStatusCodeKey, http_status_code); + dict->SetInteger(keys::kFrameIdKey, frame_id_for_extension); + dict->SetInteger(keys::kTabIdKey, tab_id); + dict->SetString(keys::kTypeKey, ResourceTypeToString(resource_type)); if (!response_ip.empty()) dict->SetString(keys::kIpKey, response_ip); dict->SetBoolean(keys::kFromCache, request->was_cached()); @@ -892,10 +924,13 @@ ExtensionWebRequestEventRouter::GetMatchingListeners( const std::string& event_name, net::URLRequest* request, int* extra_info_spec) { + bool is_main_frame = false; + int64 frame_id = -1; int tab_id = -1; int window_id = -1; ResourceType::Type resource_type = ResourceType::LAST_TYPE; - ExtractRequestInfo(request, &tab_id, &window_id, &resource_type); + ExtractRequestInfo(request, &is_main_frame, &frame_id, &tab_id, &window_id, + &resource_type); return GetMatchingListeners( profile, extension_info_map, event_name, request->url(), diff --git a/chrome/browser/extensions/extension_webrequest_api_constants.cc b/chrome/browser/extensions/extension_webrequest_api_constants.cc index 2f49d37..efa5b2f 100644 --- a/chrome/browser/extensions/extension_webrequest_api_constants.cc +++ b/chrome/browser/extensions/extension_webrequest_api_constants.cc @@ -7,6 +7,7 @@ namespace extension_webrequest_api_constants { const char kErrorKey[] = "error"; +const char kFrameIdKey[] = "frameId"; const char kFromCache[] = "fromCache"; const char kIpKey[] = "ip"; const char kMethodKey[] = "method"; diff --git a/chrome/browser/extensions/extension_webrequest_api_constants.h b/chrome/browser/extensions/extension_webrequest_api_constants.h index 6715cd7..964c9bf 100644 --- a/chrome/browser/extensions/extension_webrequest_api_constants.h +++ b/chrome/browser/extensions/extension_webrequest_api_constants.h @@ -12,6 +12,7 @@ namespace extension_webrequest_api_constants { // Keys. extern const char kErrorKey[]; +extern const char kFrameIdKey[]; extern const char kFromCache[]; extern const char kIpKey[]; extern const char kMethodKey[]; diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc index 99b39cd..9d8064d 100644 --- a/chrome/browser/extensions/user_script_listener_unittest.cc +++ b/chrome/browser/extensions/user_script_listener_unittest.cc @@ -90,7 +90,7 @@ class DummyResourceHandler : public ResourceHandler { ResourceDispatcherHostRequestInfo* CreateRequestInfo(int request_id) { return new ResourceDispatcherHostRequestInfo( new DummyResourceHandler(), ChildProcessInfo::RENDER_PROCESS, 0, 0, 0, - request_id, ResourceType::MAIN_FRAME, 0, false, false, false, + request_id, false, -1, ResourceType::MAIN_FRAME, 0, false, false, false, content::MockResourceContext::GetInstance()); } diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index 6db418e..d341192 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -3852,7 +3852,7 @@ "properties": { "tabId": {"type": "integer", "description": "The ID of the tab in which the navigation is about to occur."}, "url": {"type": "string"}, - "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; positive value indicates navigation in a subframe. Frame IDs are unique within a tab."}, + "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; a positive value indicates navigation in a subframe. Frame IDs are unique within a tab."}, "timeStamp": {"type": "number", "description": "The time when the browser was about to start the navigation, in milliseconds since the epoch."} } } @@ -3869,7 +3869,7 @@ "properties": { "tabId": {"type": "integer", "description": "The ID of the tab in which the navigation occurs."}, "url": {"type": "string"}, - "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; positive value indicates navigation in a subframe."}, + "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; a positive value indicates navigation in a subframe. Frame IDs are unique within a tab."}, "transitionType": {"type": "string", "enum": ["link", "typed", "auto_bookmark", "auto_subframe", "manual_subframe", "generated", "start_page", "form_submit", "reload", "keyword", "keyword_generated"], "description": "Cause of the navigation. The same transition types as defined in the history API are used."}, "transitionQualifiers": {"type": "array", "description": "A list of transition qualifiers.", "items:": {"type": "string", "enum": ["client_redirect", "server_redirect", "forward_back"]}}, "timeStamp": {"type": "number", "description": "The time when the navigation was committed, in milliseconds since the epoch."} @@ -3888,7 +3888,7 @@ "properties": { "tabId": {"type": "integer", "description": "The ID of the tab in which the navigation occurs."}, "url": {"type": "string"}, - "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; positive value indicates navigation in a subframe."}, + "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; a positive value indicates navigation in a subframe. Frame IDs are unique within a tab."}, "timeStamp": {"type": "number", "description": "The time when the page's DOM was fully constructed, in milliseconds since the epoch."} } } @@ -3905,7 +3905,7 @@ "properties": { "tabId": {"type": "integer", "description": "The ID of the tab in which the navigation occurs."}, "url": {"type": "string"}, - "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; positive value indicates navigation in a subframe."}, + "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; a positive value indicates navigation in a subframe. Frame IDs are unique within a tab."}, "timeStamp": {"type": "number", "description": "The time when the document finished loading, in milliseconds since the epoch."} } } @@ -3922,7 +3922,7 @@ "properties": { "tabId": {"type": "integer", "description": "The ID of the tab in which the navigation occurs."}, "url": {"type": "string"}, - "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; positive value indicates navigation in a subframe."}, + "frameId": {"type": "integer", "description": "0 indicates the navigation happens in the tab content window; a positive value indicates navigation in a subframe. Frame IDs are unique within a tab."}, "error": {"type": "string", "description": "The error description."}, "timeStamp": {"type": "number", "description": "The time when the error occurred, in milliseconds since the epoch."} } @@ -4065,6 +4065,7 @@ "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."}, "url": {"type": "string"}, "method": {"type": "string", "description": "Standard HTTP method."}, + "frameId": {"type": "integer", "description": "0 indicates the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. Frame IDs are unique within a tab."}, "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to null if the request isn't related to a tab."}, "type": {"type": "string", "enum": ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "other"], "description": "How the requested resource will be used."}, "timeStamp": {"type": "number", "description": "The time when the browser was about to make the request, in milliseconds since the epoch."} @@ -4221,6 +4222,9 @@ "requestId": {"type": "string", "description": "The ID of the request."}, "url": {"type": "string", "description": "The URL of the current request."}, "ip": {"type": "string", "optional": true, "description": "The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address."}, + "frameId": {"type": "integer", "description": "0 indicates the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. Frame IDs are unique within a tab."}, + "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to null if the request isn't related to a tab."}, + "type": {"type": "string", "enum": ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "other"], "description": "How the requested resource will be used."}, "fromCache": {"type": "boolean", "description": "Indicates if this response was fetched from disk cache."}, "statusCode": {"type": "integer", "description": "Standard HTTP status code returned by the server."}, "redirectUrl": {"type": "string", "description": "The new URL."}, diff --git a/chrome/common/extensions/docs/experimental.webRequest.html b/chrome/common/extensions/docs/experimental.webRequest.html index 7b8b063..f0db1be 100644 --- a/chrome/common/extensions/docs/experimental.webRequest.html +++ b/chrome/common/extensions/docs/experimental.webRequest.html @@ -795,6 +795,210 @@ unexpected results. </div><div> <div> <dt> + <var>frameId</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>integer</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>0 indicates the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. Frame IDs are unique within a tab.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>tabId</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>integer</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The ID of the tab in which the request takes place. Set to null if the request isn't related to a tab.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>type</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>string</span> + <span>["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "other"]</span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>How the requested resource will be used.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> <var>fromCache</var> <em> @@ -1662,6 +1866,74 @@ unexpected results. </div><div> <div> <dt> + <var>frameId</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>integer</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>0 indicates the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. Frame IDs are unique within a tab.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> <var>tabId</var> <em> diff --git a/chrome/test/data/extensions/api_test/webrequest/events/test.html b/chrome/test/data/extensions/api_test/webrequest/events/test.html index 3548fd8..b391938 100644 --- a/chrome/test/data/extensions/api_test/webrequest/events/test.html +++ b/chrome/test/data/extensions/api_test/webrequest/events/test.html @@ -62,6 +62,7 @@ function expect(data, order, filter, extraInfoSpec) { capturedEventData = []; expectedEventOrder = order; eventsCaptured = chrome.test.callbackAdded(); + tabAndFrameUrls = {}; // Maps "{tabId}-{frameId}" to the URL of the frame. removeListeners(); initListeners(filter || {}, extraInfoSpec || []); } @@ -130,6 +131,22 @@ function captureEvent(name, details) { retval = expectedEventData[currentIndex].retval; } + // Check that the frameId can be used to reliably determine the URL of the + // frame that caused requests. + if (name == "onBeforeRequest" || name == "onBeforeRedirect") { + chrome.test.assertTrue('frameId' in details && + typeof details.frameId === 'number'); + chrome.test.assertTrue('tabId' in details && + typeof details.tabId === 'number'); + var key = details.tabId + "-" + details.frameId; + if (details.type == "main_frame" || details.type == "sub_frame") { + tabAndFrameUrls[key] = + name == "onBeforeRedirect" ? details.redirectUrl : details.url; + } + details.frameUrl = tabAndFrameUrls[key] || "unknown frame URL"; + } + delete details.frameId; + delete details.requestId; delete details.timeStamp; if (details.requestHeaders) { @@ -232,7 +249,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("simpleLoad/a.html") + url: getURL("simpleLoad/a.html"), + frameUrl: getURL("simpleLoad/a.html") } }, { label: "a-onResponseStarted", @@ -270,7 +288,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: URL_HTTP_SIMPLE_LOAD_REDIRECT + url: URL_HTTP_SIMPLE_LOAD_REDIRECT, + frameUrl: URL_HTTP_SIMPLE_LOAD_REDIRECT } }, { label: "onBeforeSendHeaders-1", @@ -294,6 +313,9 @@ runTests([ redirectUrl: URL_HTTP_SIMPLE_LOAD, statusCode: 301, responseHeadersExist: true, + tabId: tabId, + type: "main_frame", + frameUrl: URL_HTTP_SIMPLE_LOAD, ip: "127.0.0.1", fromCache: false, statusLine: "HTTP/1.0 301 Moved Permanently" @@ -305,7 +327,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: URL_HTTP_SIMPLE_LOAD + url: URL_HTTP_SIMPLE_LOAD, + frameUrl: URL_HTTP_SIMPLE_LOAD } }, { label: "onBeforeSendHeaders-2", @@ -367,7 +390,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("complexLoad/a.html") + url: getURL("complexLoad/a.html"), + frameUrl: getURL("complexLoad/a.html") } }, { label: "b.html-onBeforeRequest", @@ -376,7 +400,8 @@ runTests([ method: "GET", tabId: tabId, type: "sub_frame", - url: getURL("complexLoad/b.html") + url: getURL("complexLoad/b.html"), + frameUrl: getURL("complexLoad/b.html") } }, { label: "b.jpg-onBeforeRequest", @@ -385,7 +410,8 @@ runTests([ method: "GET", tabId: tabId, type: "image", - url: getURL("complexLoad/b.jpg") + url: getURL("complexLoad/b.jpg"), + frameUrl: getURL("complexLoad/b.html") } }, { label: "a.html-onResponseStarted", @@ -466,7 +492,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("complexLoad/a.html") + url: getURL("complexLoad/a.html"), + frameUrl: getURL("complexLoad/a.html") }, retval: {cancel: true} }, @@ -503,7 +530,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("complexLoad/a.html") + url: getURL("complexLoad/a.html"), + frameUrl: getURL("complexLoad/a.html") }, retval: {redirectUrl: getURL("simpleLoad/a.html")} }, @@ -522,7 +550,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("simpleLoad/a.html") + url: getURL("simpleLoad/a.html"), + frameUrl: getURL("simpleLoad/a.html"), }, }, { label: "onResponseStarted", @@ -564,7 +593,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("complexLoad/a.html") + url: getURL("complexLoad/a.html"), + frameUrl: getURL("complexLoad/a.html") } }, { label: "b-onBeforeRequest", @@ -573,7 +603,9 @@ runTests([ method: "GET", tabId: tabId, type: "image", - url: getURL("complexLoad/b.jpg") + url: getURL("complexLoad/b.jpg"), + // As we do not listed to sub-frames we do not know the frameUrl. + frameUrl: "unknown frame URL" } }, { label: "a-onResponseStarted", @@ -640,7 +672,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: getURL("does_not_exist.html") + url: getURL("does_not_exist.html"), + frameUrl: getURL("does_not_exist.html") } }, { label: "onErrorOccurred", @@ -670,7 +703,8 @@ runTests([ method: "GET", tabId: tabId, type: "main_frame", - url: URL_ECHO_USER_AGENT + url: URL_ECHO_USER_AGENT, + frameUrl: URL_ECHO_USER_AGENT } }, { label: "onBeforeSendHeaders", diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc index 28ef467..7030b10 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.cc +++ b/content/browser/renderer_host/resource_dispatcher_host.cc @@ -506,6 +506,8 @@ void ResourceDispatcherHost::BeginRequest( route_id, request_data.origin_pid, request_id, + request_data.is_main_frame, + request_data.frame_id, request_data.resource_type, upload_size, false, // is download @@ -643,6 +645,8 @@ ResourceDispatcherHost::CreateRequestInfoForBrowserRequest( route_id, 0, request_id_, + false, // is_main_frame + -1, // frame_id ResourceType::SUB_RESOURCE, 0, // upload_size download, // is_download diff --git a/content/browser/renderer_host/resource_dispatcher_host_request_info.cc b/content/browser/renderer_host/resource_dispatcher_host_request_info.cc index ec5211d..9ae935f 100644 --- a/content/browser/renderer_host/resource_dispatcher_host_request_info.cc +++ b/content/browser/renderer_host/resource_dispatcher_host_request_info.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,6 +16,8 @@ ResourceDispatcherHostRequestInfo::ResourceDispatcherHostRequestInfo( int route_id, int origin_pid, int request_id, + bool is_main_frame, + int64 frame_id, ResourceType::Type resource_type, uint64 upload_size, bool is_download, @@ -29,6 +31,8 @@ ResourceDispatcherHostRequestInfo::ResourceDispatcherHostRequestInfo( route_id_(route_id), origin_pid_(origin_pid), request_id_(request_id), + is_main_frame_(is_main_frame), + frame_id_(frame_id), pending_data_count_(0), is_download_(is_download), allow_download_(allow_download), diff --git a/content/browser/renderer_host/resource_dispatcher_host_request_info.h b/content/browser/renderer_host/resource_dispatcher_host_request_info.h index e6ca1c3..b785e72 100644 --- a/content/browser/renderer_host/resource_dispatcher_host_request_info.h +++ b/content/browser/renderer_host/resource_dispatcher_host_request_info.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -42,6 +42,8 @@ class ResourceDispatcherHostRequestInfo : public net::URLRequest::UserData { int route_id, int origin_pid, int request_id, + bool is_main_frame, + int64 frame_id, ResourceType::Type resource_type, uint64 upload_size, bool is_download, @@ -96,6 +98,12 @@ class ResourceDispatcherHostRequestInfo : public net::URLRequest::UserData { // Unique identifier for this resource request. int request_id() const { return request_id_; } + // True if |frame_id_| represents a main frame in the RenderView. + bool is_main_frame() const { return is_main_frame_; } + + // Frame ID that sent this resource request. -1 if unknown / invalid. + int64 frame_id() const { return frame_id_; } + // Number of messages we've sent to the renderer that we haven't gotten an // ACK for. This allows us to avoid having too many messages in flight. int pending_data_count() const { return pending_data_count_; } @@ -206,6 +214,8 @@ class ResourceDispatcherHostRequestInfo : public net::URLRequest::UserData { int route_id_; int origin_pid_; int request_id_; + bool is_main_frame_; + int64 frame_id_; int pending_data_count_; bool is_download_; bool allow_download_; diff --git a/content/browser/renderer_host/resource_queue_unittest.cc b/content/browser/renderer_host/resource_queue_unittest.cc index 8bc08da..cd47ffe 100644 --- a/content/browser/renderer_host/resource_queue_unittest.cc +++ b/content/browser/renderer_host/resource_queue_unittest.cc @@ -76,7 +76,7 @@ class DummyResourceHandler : public ResourceHandler { ResourceDispatcherHostRequestInfo* GetRequestInfo(int request_id) { return new ResourceDispatcherHostRequestInfo( new DummyResourceHandler(), ChildProcessInfo::RENDER_PROCESS, 0, 0, 0, - request_id, ResourceType::MAIN_FRAME, 0, false, false, false, + request_id, false, -1, ResourceType::MAIN_FRAME, 0, false, false, false, content::MockResourceContext::GetInstance()); } diff --git a/content/common/resource_dispatcher.cc b/content/common/resource_dispatcher.cc index 0ea306e..c16d92f 100644 --- a/content/common/resource_dispatcher.cc +++ b/content/common/resource_dispatcher.cc @@ -92,6 +92,8 @@ IPCResourceLoaderBridge::IPCResourceLoaderBridge( request_.appcache_host_id = request_info.appcache_host_id; request_.download_to_file = request_info.download_to_file; request_.has_user_gesture = request_info.has_user_gesture; + request_.is_main_frame = request_info.is_main_frame; + request_.frame_id = request_info.frame_id; } IPCResourceLoaderBridge::~IPCResourceLoaderBridge() { diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h index 1d1d51b..bd2251a 100644 --- a/content/common/resource_messages.h +++ b/content/common/resource_messages.h @@ -92,6 +92,13 @@ IPC_STRUCT_BEGIN(ResourceHostMsg_Request) // True if the request was user initiated. IPC_STRUCT_MEMBER(bool, has_user_gesture) + + // True if |frame_id| is the main frame of a RenderView. + IPC_STRUCT_MEMBER(bool, is_main_frame) + + // Identifies the frame within the RenderView that sent the request. + // -1 if unknown / invalid. + IPC_STRUCT_MEMBER(int64, frame_id) IPC_STRUCT_END() // Resource messages sent from the browser to the renderer. diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc index e2d4e2f..762a637 100644 --- a/content/renderer/render_view.cc +++ b/content/renderer/render_view.cc @@ -130,6 +130,7 @@ #include "webkit/glue/glue_serialize.h" #include "webkit/glue/media/video_renderer_impl.h" #include "webkit/glue/password_form_dom_manager.h" +#include "webkit/glue/request_extra_data.h" #include "webkit/glue/site_isolation_metrics.h" #include "webkit/glue/webaccessibility.h" #include "webkit/glue/webdropdata.h" @@ -2596,6 +2597,9 @@ void RenderView::willSendRequest( WebDataSource* data_source = provisional_data_source ? provisional_data_source : top_data_source; + bool is_top_frame = (frame == top_frame); + request.setExtraData( + new RequestExtraData(is_top_frame, frame->identifier())); GURL request_url(request.url()); GURL new_url; diff --git a/webkit/glue/request_extra_data.cc b/webkit/glue/request_extra_data.cc new file mode 100644 index 0000000..8870fed --- /dev/null +++ b/webkit/glue/request_extra_data.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/glue/request_extra_data.h" + +RequestExtraData::~RequestExtraData() {} + +RequestExtraData::RequestExtraData(bool is_main_frame, + int64 frame_identifier) + : is_main_frame_(is_main_frame), + frame_identifier_(frame_identifier) { +} diff --git a/webkit/glue/request_extra_data.h b/webkit/glue/request_extra_data.h new file mode 100644 index 0000000..1dd6103 --- /dev/null +++ b/webkit/glue/request_extra_data.h @@ -0,0 +1,29 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_GLUE_REQUEST_EXTRA_DATA_H_ +#define WEBKIT_GLUE_REQUEST_EXTRA_DATA_H_ +#pragma once + +#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" + +// The RenderView stores an instance of this class in the "extra data" of each +// ResourceRequest (see RenderView::willSendRequest). +class RequestExtraData : public WebKit::WebURLRequest::ExtraData { + public: + RequestExtraData(bool is_main_frame, int64 frame_identifier); + virtual ~RequestExtraData(); + + bool is_main_frame() const { return is_main_frame_; } + + int64 frame_identifier() const { return frame_identifier_; } + + private: + bool is_main_frame_; + int64 frame_identifier_; + + DISALLOW_COPY_AND_ASSIGN(RequestExtraData); +}; + +#endif // WEBKIT_GLUE_REQUEST_EXTRA_DATA_H_ diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h index 9b2fd09..dcc86f4 100644 --- a/webkit/glue/resource_loader_bridge.h +++ b/webkit/glue/resource_loader_bridge.h @@ -246,6 +246,13 @@ class ResourceLoaderBridge { // True if the request was user initiated. bool has_user_gesture; + + // True if |frame_id| represents a main frame of a RenderView. + bool is_main_frame; + + // Identifies the frame within the RenderView that sent the request. + // -1 if unknown / invalid. + int64 frame_id; }; // See the SyncLoad method declared below. (The name of this struct is not diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index ae8319d..e2ac88a 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -379,6 +379,8 @@ 'resource_loader_bridge.cc', 'resource_loader_bridge.h', 'resource_type.h', + 'request_extra_data.cc', + 'request_extra_data.h', 'scoped_clipboard_writer_glue.h', 'simple_webmimeregistry_impl.cc', 'simple_webmimeregistry_impl.h', diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc index cbdf18d..116ea0f 100644 --- a/webkit/glue/weburlloader_impl.cc +++ b/webkit/glue/weburlloader_impl.cc @@ -30,6 +30,7 @@ #include "webkit/glue/ftp_directory_listing_response_delegate.h" #include "webkit/glue/multipart_response_delegate.h" #include "webkit/glue/resource_loader_bridge.h" +#include "webkit/glue/request_extra_data.h" #include "webkit/glue/site_isolation_metrics.h" #include "webkit/glue/webkit_glue.h" @@ -442,6 +443,14 @@ void WebURLLoaderImpl::Context::Start( request_info.routing_id = request.requestorID(); request_info.download_to_file = request.downloadToFile(); request_info.has_user_gesture = request.hasUserGesture(); + request_info.frame_id = -1; + request_info.is_main_frame = false; + if (request.extraData()) { + RequestExtraData* extra_data = + static_cast<RequestExtraData*>(request.extraData()); + request_info.frame_id = extra_data->frame_identifier(); + request_info.is_main_frame = extra_data->is_main_frame(); + } bridge_.reset(ResourceLoaderBridge::Create(request_info)); if (!request.httpBody().isNull()) { |