summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-21 19:01:52 +0000
committerbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-21 19:01:52 +0000
commit418da61f84250c962fa0509e53f8f4213505fcac (patch)
treeb98ce1e8ca8ece82e3cea5ae8beb1dab1e11f6db
parentf81f5950b78f7c0161d757d91ff3a3baa96e089b (diff)
downloadchromium_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
-rw-r--r--chrome/browser/extensions/extension_webnavigation_api.cc5
-rw-r--r--chrome/browser/extensions/extension_webrequest_api.cc39
-rw-r--r--chrome/browser/extensions/extension_webrequest_api_constants.cc1
-rw-r--r--chrome/browser/extensions/extension_webrequest_api_constants.h1
-rw-r--r--chrome/browser/extensions/user_script_listener_unittest.cc2
-rw-r--r--chrome/common/extensions/api/extension_api.json14
-rw-r--r--chrome/common/extensions/docs/experimental.webRequest.html272
-rw-r--r--chrome/test/data/extensions/api_test/webrequest/events/test.html60
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host.cc4
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_request_info.cc6
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host_request_info.h12
-rw-r--r--content/browser/renderer_host/resource_queue_unittest.cc2
-rw-r--r--content/common/resource_dispatcher.cc2
-rw-r--r--content/common/resource_messages.h7
-rw-r--r--content/renderer/render_view.cc4
-rw-r--r--webkit/glue/request_extra_data.cc13
-rw-r--r--webkit/glue/request_extra_data.h29
-rw-r--r--webkit/glue/resource_loader_bridge.h7
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/glue/weburlloader_impl.cc9
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()) {