summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-03 20:46:35 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-03 20:46:35 +0000
commit7efc582d60227aa473c77c3309a96b2dfed52351 (patch)
tree4431c6c5355dcb71aba481c52a799acbfaaa66e4
parentab3c20b28bf4712dffb4ae38d0d7762f71842a69 (diff)
downloadchromium_src-7efc582d60227aa473c77c3309a96b2dfed52351.zip
chromium_src-7efc582d60227aa473c77c3309a96b2dfed52351.tar.gz
chromium_src-7efc582d60227aa473c77c3309a96b2dfed52351.tar.bz2
Add onAuthRequired signal to the webRequest API
BUG=none TEST=api test Review URL: http://codereview.chromium.org/7538024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95308 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_webrequest_api.cc46
-rw-r--r--chrome/browser/extensions/extension_webrequest_api.h14
-rw-r--r--chrome/browser/extensions/extension_webrequest_api_constants.cc5
-rw-r--r--chrome/browser/extensions/extension_webrequest_api_constants.h4
-rw-r--r--chrome/browser/extensions/extension_webrequest_apitest.cc34
-rw-r--r--chrome/browser/net/chrome_network_delegate.cc7
-rw-r--r--chrome/browser/net/chrome_network_delegate.h2
-rw-r--r--chrome/common/extensions/api/extension_api.json39
-rw-r--r--chrome/common/extensions/docs/experimental.webRequest.html801
-rw-r--r--chrome/common/extensions/docs/samples.json1
-rw-r--r--chrome/test/data/extensions/api_test/webrequest/events/test.html71
-rw-r--r--net/base/network_delegate.cc6
-rw-r--r--net/base/network_delegate.h7
-rw-r--r--net/proxy/network_delegate_error_observer_unittest.cc2
-rw-r--r--net/url_request/url_request.cc2
-rw-r--r--net/url_request/url_request_test_util.cc5
-rw-r--r--net/url_request/url_request_test_util.h2
17 files changed, 1044 insertions, 4 deletions
diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc
index f619f61..bc978a7 100644
--- a/chrome/browser/extensions/extension_webrequest_api.cc
+++ b/chrome/browser/extensions/extension_webrequest_api.cc
@@ -9,6 +9,7 @@
#include "base/json/json_writer.h"
#include "base/metrics/histogram.h"
#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_info_map.h"
@@ -26,6 +27,7 @@
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
+#include "net/base/auth.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/http/http_response_headers.h"
@@ -44,7 +46,8 @@ static const char* const kWebRequestEvents[] = {
keys::kOnCompleted,
keys::kOnErrorOccurred,
keys::kOnSendHeaders,
- keys::kOnResponseStarted
+ keys::kOnAuthRequired,
+ keys::kOnResponseStarted,
};
static const char* kResourceTypeStrings[] = {
@@ -560,6 +563,47 @@ void ExtensionWebRequestEventRouter::OnSendHeaders(
DispatchEvent(profile, request, listeners, args);
}
+void ExtensionWebRequestEventRouter::OnAuthRequired(
+ void* profile,
+ ExtensionInfoMap* extension_info_map,
+ net::URLRequest* request,
+ const net::AuthChallengeInfo& auth_info) {
+ if (!profile)
+ return;
+
+ base::Time time(base::Time::Now());
+
+ if (!HasWebRequestScheme(request->url()))
+ return;
+
+ int extra_info_spec = 0;
+ std::vector<const EventListener*> listeners =
+ GetMatchingListeners(profile, extension_info_map,
+ keys::kOnAuthRequired, request, &extra_info_spec);
+ if (listeners.empty())
+ return;
+
+ ListValue args;
+ DictionaryValue* dict = new DictionaryValue();
+ dict->SetString(keys::kRequestIdKey,
+ base::Uint64ToString(request->identifier()));
+ dict->SetString(keys::kUrlKey, request->url().spec());
+ dict->SetBoolean(keys::kIsProxyKey, auth_info.is_proxy);
+ dict->SetString(keys::kSchemeKey, WideToUTF8(auth_info.scheme));
+ if (!auth_info.realm.empty())
+ dict->SetString(keys::kRealmKey, WideToUTF8(auth_info.realm));
+ dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
+ if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) {
+ dict->Set(keys::kResponseHeadersKey,
+ GetResponseHeadersList(request->response_headers()));
+ }
+ if (extra_info_spec & ExtraInfoSpec::STATUS_LINE)
+ dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
+ args.Append(dict);
+
+ DispatchEvent(profile, request, listeners, args);
+}
+
void ExtensionWebRequestEventRouter::OnBeforeRedirect(
void* profile,
ExtensionInfoMap* extension_info_map,
diff --git a/chrome/browser/extensions/extension_webrequest_api.h b/chrome/browser/extensions/extension_webrequest_api.h
index 5790c7e..7492bc9 100644
--- a/chrome/browser/extensions/extension_webrequest_api.h
+++ b/chrome/browser/extensions/extension_webrequest_api.h
@@ -31,6 +31,7 @@ class StringValue;
}
namespace net {
+class AuthChallengeInfo;
class HostPortPair;
class HttpRequestHeaders;
class HttpResponseHeaders;
@@ -48,9 +49,10 @@ class ExtensionWebRequestEventRouter {
kOnBeforeSendHeaders = 1 << 1,
kOnSendHeaders = 1 << 2,
kOnBeforeRedirect = 1 << 3,
- kOnResponseStarted = 1 << 4,
- kOnErrorOccurred = 1 << 5,
- kOnCompleted = 1 << 6,
+ kOnAuthRequired = 1 << 4,
+ kOnResponseStarted = 1 << 5,
+ kOnErrorOccurred = 1 << 6,
+ kOnCompleted = 1 << 7,
};
// Internal representation of the webRequest.RequestFilter type, used to
@@ -168,6 +170,12 @@ class ExtensionWebRequestEventRouter {
net::URLRequest* request,
const net::HttpRequestHeaders& headers);
+ // Dispatches the onAuthRequired event.
+ void OnAuthRequired(void* profile,
+ ExtensionInfoMap* extension_info_map,
+ net::URLRequest* request,
+ const net::AuthChallengeInfo& auth_info);
+
// Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
// only.
void OnBeforeRedirect(void* profile,
diff --git a/chrome/browser/extensions/extension_webrequest_api_constants.cc b/chrome/browser/extensions/extension_webrequest_api_constants.cc
index efa5b2f..dec2a05 100644
--- a/chrome/browser/extensions/extension_webrequest_api_constants.cc
+++ b/chrome/browser/extensions/extension_webrequest_api_constants.cc
@@ -23,6 +23,9 @@ const char kRequestHeadersKey[] = "requestHeaders";
const char kResponseHeadersKey[] = "responseHeaders";
const char kHeaderNameKey[] = "name";
const char kHeaderValueKey[] = "value";
+const char kIsProxyKey[] = "isProxy";
+const char kSchemeKey[] = "scheme";
+const char kRealmKey[] = "realm";
const char kOnBeforeRedirect[] = "experimental.webRequest.onBeforeRedirect";
const char kOnBeforeRequest[] = "experimental.webRequest.onBeforeRequest";
@@ -32,6 +35,8 @@ const char kOnCompleted[] = "experimental.webRequest.onCompleted";
const char kOnErrorOccurred[] = "experimental.webRequest.onErrorOccurred";
const char kOnResponseStarted[] = "experimental.webRequest.onResponseStarted";
const char kOnSendHeaders[] = "experimental.webRequest.onSendHeaders";
+const char kOnAuthRequired[] = "experimental.webRequest.onAuthRequired";
+
const char kInvalidRedirectUrl[] = "redirectUrl '*' is not a valid URL.";
const char kInvalidBlockingResponse[] =
diff --git a/chrome/browser/extensions/extension_webrequest_api_constants.h b/chrome/browser/extensions/extension_webrequest_api_constants.h
index 964c9bf..a0ad13d 100644
--- a/chrome/browser/extensions/extension_webrequest_api_constants.h
+++ b/chrome/browser/extensions/extension_webrequest_api_constants.h
@@ -29,8 +29,12 @@ extern const char kResponseHeadersKey[];
extern const char kHeadersKey[];
extern const char kHeaderNameKey[];
extern const char kHeaderValueKey[];
+extern const char kIsProxyKey[];
+extern const char kSchemeKey[];
+extern const char kRealmKey[];
// Events.
+extern const char kOnAuthRequired[];
extern const char kOnBeforeRedirect[];
extern const char kOnBeforeRequest[];
extern const char kOnBeforeSendHeaders[];
diff --git a/chrome/browser/extensions/extension_webrequest_apitest.cc b/chrome/browser/extensions/extension_webrequest_apitest.cc
index 3002959..aace273 100644
--- a/chrome/browser/extensions/extension_webrequest_apitest.cc
+++ b/chrome/browser/extensions/extension_webrequest_apitest.cc
@@ -5,9 +5,41 @@
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_webrequest_api.h"
+#include "chrome/browser/ui/login/login_prompt.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
+#include "content/common/notification_registrar.h"
+#include "content/common/notification_service.h"
#include "net/base/mock_host_resolver.h"
+namespace {
+
+class CancelLoginDialog : public NotificationObserver {
+ public:
+ CancelLoginDialog() {
+ registrar_.Add(this,
+ chrome::NOTIFICATION_AUTH_NEEDED,
+ NotificationService::AllSources());
+ }
+
+ virtual ~CancelLoginDialog() {}
+
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ LoginHandler* handler =
+ Details<LoginNotificationDetails>(details).ptr()->handler();
+ handler->CancelAuth();
+ }
+
+ private:
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(CancelLoginDialog);
+};
+
+} // namespace
+
class ExtensionWebRequestApiTest : public ExtensionApiTest {
public:
virtual void SetUpInProcessBrowserTestFixture() {
@@ -29,5 +61,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestEvents) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
+ CancelLoginDialog login_dialog_helper;
+
ASSERT_TRUE(RunExtensionTest("webrequest/events")) << message_;
}
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index d5a27ce..41cedf3 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -137,3 +137,10 @@ void ChromeNetworkDelegate::OnPACScriptError(int line_number,
ExtensionProxyEventRouter::GetInstance()->OnPACScriptError(
event_router_.get(), profile_, line_number, error);
}
+
+void ChromeNetworkDelegate::OnAuthRequired(
+ net::URLRequest* request,
+ const net::AuthChallengeInfo& auth_info) {
+ ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired(
+ profile_, extension_info_map_.get(), request, auth_info);
+}
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index 182b069..980a26b 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -58,6 +58,8 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
virtual void OnURLRequestDestroyed(net::URLRequest* request) OVERRIDE;
virtual void OnPACScriptError(int line_number,
const string16& error) OVERRIDE;
+ virtual void OnAuthRequired(net::URLRequest* request,
+ const net::AuthChallengeInfo& auth_info) OVERRIDE;
scoped_refptr<ExtensionEventRouterForwarder> event_router_;
void* profile_;
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index dcfbf30..ada7737 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -4837,6 +4837,45 @@
]
},
{
+ "name": "onAuthRequired",
+ "type": "function",
+ "description": "Fired when an authentication failure was received. Depending on whether the user provides credentials, the request is either reissued or cancelled.",
+ "parameters": [
+ {
+ "type": "object",
+ "name": "details",
+ "properties": {
+ "requestId": {"type": "string", "description": "The ID of the request."},
+ "url": {"type": "string"},
+ "scheme": {"type": "string", "description": "The authentication scheme, e.g. Basic or Digest."},
+ "realm": {"type": "string", "description": "The authentication realm provided by the server, if there is one.", "optional": true},
+ "isProxy": {"type": "boolean", "description": "True for Proxy-Authenticate, false for WWW-Authenticate."},
+ "timeStamp": {"type": "number", "description": "The time when the status line and response headers were received, in milliseconds since the epoch."},
+ "responseHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP response headers that were received along with this response."},
+ "statusLine": {"type": "string", "optional": true, "description": "HTTP status line of the response"}
+ }
+ }
+ ],
+ "extraParameters": [
+ {
+ "$ref": "RequestFilter",
+ "optional": true,
+ "name": "filter",
+ "description": "A set of filters that restricts the events that will be sent to this listener."
+ },
+ {
+ "type": "array",
+ "optional": true,
+ "name": "extraInfoSpec",
+ "description": "Array of extra information that should be passed to the listener function.",
+ "items": {
+ "type": "string",
+ "enum": ["statusLine", "responseHeaders"]
+ }
+ }
+ ]
+ },
+ {
"name": "onResponseStarted",
"type": "function",
"description": "Fired when the first byte of the response body is received. For HTTP requests, this means that the status line and response headers are available.",
diff --git a/chrome/common/extensions/docs/experimental.webRequest.html b/chrome/common/extensions/docs/experimental.webRequest.html
index de078bf..410c3c4 100644
--- a/chrome/common/extensions/docs/experimental.webRequest.html
+++ b/chrome/common/extensions/docs/experimental.webRequest.html
@@ -327,6 +327,8 @@
<a href="#global-events">Events</a>
<ol>
<li>
+ <a href="#event-onAuthRequired">onAuthRequired</a>
+ </li><li>
<a href="#event-onBeforeRedirect">onBeforeRedirect</a>
</li><li>
<a href="#event-onBeforeRequest">onBeforeRequest</a>
@@ -815,6 +817,805 @@ chrome.windows.onRemoved.addListener(
<h3>Events</h3>
<!-- iterates over all events -->
<div class="apiItem">
+ <a name="event-onAuthRequired"></a>
+ <h4>onAuthRequired</h4>
+
+ <div class="summary">
+ <!-- Note: intentionally longer 80 columns -->
+ <span class="subdued">chrome.experimental.webRequest.</span><span>onAuthRequired</span><span class="subdued">.addListener</span>(function(<span>object details</span>) <span class="subdued">{...}</span><span>, RequestFilter filter, array of string extraInfoSpec</span>));
+ </div>
+
+ <div class="description">
+ <p class="todo" style="display: none; ">Undocumented.</p>
+ <p>Fired when an authentication failure was received. Depending on whether the user provides credentials, the request is either reissued or cancelled.</p>
+
+ <!-- LISTENER PARAMETERS -->
+ <div>
+ <h4>Listener parameters</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>details</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>object</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </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>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>requestId</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>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>The ID of the request.</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>url</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>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </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>scheme</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>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>The authentication scheme, e.g. Basic or Digest.</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>realm</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">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>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>The authentication realm provided by the server, if there is one.</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>isProxy</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>boolean</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>True for Proxy-Authenticate, false for WWW-Authenticate.</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>timeStamp</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>number</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>The time when the status line and response headers were received, in milliseconds since the epoch.</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>responseHeaders</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span>
+ <a href="experimental.webRequest.html#type-HttpHeaders">HttpHeaders</a>
+ </span>
+ <span style="display: none; ">
+ <span>
+ array of <span><span></span></span>
+ </span>
+ <span>paramType</span>
+ <span></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>The HTTP response headers that were received along with this response.</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>statusLine</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">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>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>HTTP status line of the response</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>
+ </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>
+ </dl>
+ </div>
+
+ <!-- EXTRA PARAMETERS -->
+ <div>
+ <h4>Extra parameters to addListener</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>filter</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span>
+ <a href="experimental.webRequest.html#type-RequestFilter">RequestFilter</a>
+ </span>
+ <span style="display: none; ">
+ <span>
+ array of <span><span></span></span>
+ </span>
+ <span>paramType</span>
+ <span></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>A set of filters that restricts the events that will be sent to this listener.</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>extraInfoSpec</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span>
+ array of <span><span>
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>string</span>
+ <span>["statusLine", "responseHeaders"]</span>
+ </span>
+ </span></span>
+ </span>
+ <span style="display: none; ">paramType</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>Array of extra information that should be passed to the listener function.</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>
+ </dl>
+ </div>
+
+ <!-- LISTENER RETURN VALUE -->
+ <h4 style="display: none; ">Listener returns</h4>
+ <dl>
+ <div style="display: none; ">
+ <div>
+ </div>
+ </div>
+ </dl>
+
+ </div> <!-- /description -->
+ </div><div class="apiItem">
<a name="event-onBeforeRedirect"></a>
<h4>onBeforeRedirect</h4>
diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json
index b93c3a9..943c75e 100644
--- a/chrome/common/extensions/docs/samples.json
+++ b/chrome/common/extensions/docs/samples.json
@@ -80,6 +80,7 @@
"chrome.experimental.webNavigation.onErrorOccurred": "experimental.webNavigation.html#event-onErrorOccurred",
"chrome.experimental.webRequest.addEventListener": "experimental.webRequest.html#method-addEventListener",
"chrome.experimental.webRequest.eventHandled": "experimental.webRequest.html#method-eventHandled",
+ "chrome.experimental.webRequest.onAuthRequired": "experimental.webRequest.html#event-onAuthRequired",
"chrome.experimental.webRequest.onBeforeRedirect": "experimental.webRequest.html#event-onBeforeRedirect",
"chrome.experimental.webRequest.onBeforeRequest": "experimental.webRequest.html#event-onBeforeRequest",
"chrome.experimental.webRequest.onBeforeSendHeaders": "experimental.webRequest.html#event-onBeforeSendHeaders",
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 eeece94..e7fcb96 100644
--- a/chrome/test/data/extensions/api_test/webrequest/events/test.html
+++ b/chrome/test/data/extensions/api_test/webrequest/events/test.html
@@ -14,6 +14,8 @@ var URL_HTTP_SIMPLE_LOAD_REDIRECT =
'http://www.a.com:PORT/server-redirect?'+URL_HTTP_SIMPLE_LOAD;
var URL_ECHO_USER_AGENT =
'http://www.a.com:PORT/echoheader?User-Agent';
+var URL_AUTH_REQUIRED =
+ 'http://www.a.com:PORT/auth-basic';
function runTests(tests) {
chrome.tabs.getSelected(null, function(tab) {
@@ -25,6 +27,7 @@ function runTests(tests) {
URL_HTTP_SIMPLE_LOAD = fixPort(URL_HTTP_SIMPLE_LOAD);
URL_HTTP_SIMPLE_LOAD_REDIRECT = fixPort(URL_HTTP_SIMPLE_LOAD_REDIRECT);
URL_ECHO_USER_AGENT = fixPort(URL_ECHO_USER_AGENT);
+ URL_AUTH_REQUIRED = fixPort(URL_AUTH_REQUIRED);
chrome.test.runTests(tests);
});
@@ -200,6 +203,10 @@ function initListeners(filter, extraInfoSpec) {
function(details) {
return captureEvent("onSendHeaders", details);
}, filter, intersect(extraInfoSpec, ["requestHeaders"]));
+ chrome.experimental.webRequest.onAuthRequired.addListener(
+ function(details) {
+ return captureEvent("onAuthRequired", details);
+ }, filter, intersect(extraInfoSpec, ["responseHeaders", "statusLine"]));
chrome.experimental.webRequest.onResponseStarted.addListener(
function(details) {
return captureEvent("onResponseStarted", details);
@@ -230,6 +237,7 @@ function removeListeners() {
}
helper(chrome.experimental.webRequest.onBeforeRequest);
helper(chrome.experimental.webRequest.onBeforeSendHeaders);
+ helper(chrome.experimental.webRequest.onAuthRequired);
helper(chrome.experimental.webRequest.onSendHeaders);
helper(chrome.experimental.webRequest.onResponseStarted);
helper(chrome.experimental.webRequest.onBeforeRedirect);
@@ -753,5 +761,68 @@ runTests([
});
});
},
+
+ // Loads a testserver page that requires authentication.
+ function authRequired() {
+ expect(
+ [ // events
+ { label: "onBeforeRequest",
+ event: "onBeforeRequest",
+ details: {
+ method: "GET",
+ tabId: tabId,
+ type: "main_frame",
+ url: URL_AUTH_REQUIRED,
+ frameUrl: URL_AUTH_REQUIRED
+ }
+ },
+ { label: "onBeforeSendHeaders",
+ event: "onBeforeSendHeaders",
+ details: {
+ url: URL_AUTH_REQUIRED,
+ // Note: no requestHeaders because we don't ask for them.
+ },
+ },
+ { label: "onSendHeaders",
+ event: "onSendHeaders",
+ details: {
+ url: URL_AUTH_REQUIRED,
+ }
+ },
+ { label: "onAuthRequired",
+ event: "onAuthRequired",
+ details: {
+ url: URL_AUTH_REQUIRED,
+ isProxy: false,
+ scheme: "basic",
+ realm: "testrealm",
+ }
+ },
+ { label: "onResponseStarted",
+ event: "onResponseStarted",
+ details: {
+ url: URL_AUTH_REQUIRED,
+ fromCache: false,
+ statusCode: 401,
+ ip: "127.0.0.1"
+ }
+ },
+ { label: "onCompleted",
+ event: "onCompleted",
+ details: {
+ url: URL_AUTH_REQUIRED,
+ fromCache: false,
+ statusCode: 401,
+ ip: "127.0.0.1"
+ }
+ },
+ ],
+ [ // event order
+ ["onBeforeRequest", "onBeforeSendHeaders", "onSendHeaders",
+ "onAuthRequired", "onResponseStarted", "onCompleted"]
+ ],
+ {}, []);
+ navigateAndWait(URL_AUTH_REQUIRED);
+ },
]);
</script>
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index fc4ff57..28d0b31 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -69,4 +69,10 @@ void NetworkDelegate::NotifyPACScriptError(int line_number,
OnPACScriptError(line_number, error);
}
+void NetworkDelegate::NotifyAuthRequired(URLRequest* request,
+ const AuthChallengeInfo& auth_info) {
+ DCHECK(CalledOnValidThread());
+ OnAuthRequired(request, auth_info);
+}
+
} // namespace net
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h
index 0c0c556..2506788 100644
--- a/net/base/network_delegate.h
+++ b/net/base/network_delegate.h
@@ -24,6 +24,7 @@ namespace net {
// NOTE: It is not okay to add any compile-time dependencies on symbols outside
// of net/base here, because we have a net_base library. Forward declarations
// are ok.
+class AuthChallengeInfo;
class HostPortPair;
class HttpRequestHeaders;
class URLRequest;
@@ -52,6 +53,8 @@ class NetworkDelegate : public base::NonThreadSafe {
void NotifyCompleted(URLRequest* request);
void NotifyURLRequestDestroyed(URLRequest* request);
void NotifyPACScriptError(int line_number, const string16& error);
+ void NotifyAuthRequired(URLRequest* request,
+ const AuthChallengeInfo& auth_info);
private:
// This is the interface for subclasses of NetworkDelegate to implement. This
@@ -99,6 +102,10 @@ class NetworkDelegate : public base::NonThreadSafe {
// Corresponds to ProxyResolverJSBindings::OnError.
virtual void OnPACScriptError(int line_number, const string16& error) = 0;
+
+ // Corresponds to URLRequest::Delegate::OnAuthRequired.
+ virtual void OnAuthRequired(URLRequest* reqest,
+ const AuthChallengeInfo& auth_info) = 0;
};
} // namespace net
diff --git a/net/proxy/network_delegate_error_observer_unittest.cc b/net/proxy/network_delegate_error_observer_unittest.cc
index 1cb9790..4eec44d 100644
--- a/net/proxy/network_delegate_error_observer_unittest.cc
+++ b/net/proxy/network_delegate_error_observer_unittest.cc
@@ -49,6 +49,8 @@ class TestNetworkDelegate : public net::NetworkDelegate {
const string16& error) OVERRIDE {
got_pac_error_ = true;
}
+ virtual void OnAuthRequired(URLRequest* request,
+ const AuthChallengeInfo& auth_info) OVERRIDE {}
bool got_pac_error_;
};
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 97c4d06..b71b36b 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -748,6 +748,8 @@ void URLRequest::NotifyAuthRequired(AuthChallengeInfo* auth_info) {
// URLRequestTestHTTP.BasicAuthWithCookies. In both cases we observe a
// call sequence of OnBeforeSendHeaders -> OnSendHeaders ->
// OnBeforeSendHeaders.
+ if (context_ && context_->network_delegate())
+ context_->network_delegate()->NotifyAuthRequired(this, *auth_info);
if (delegate_)
delegate_->OnAuthRequired(this, auth_info);
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 8c1a4fe..7dca50f 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -456,3 +456,8 @@ net::URLRequestJob* TestNetworkDelegate::OnMaybeCreateURLRequestJob(
void TestNetworkDelegate::OnPACScriptError(int line_number,
const string16& error) {
}
+
+void TestNetworkDelegate::OnAuthRequired(
+ net::URLRequest* reqest,
+ const net::AuthChallengeInfo& auth_info) {
+}
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 8b3206ea..226163e 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -207,6 +207,8 @@ class TestNetworkDelegate : public net::NetworkDelegate {
virtual net::URLRequestJob* OnMaybeCreateURLRequestJob(
net::URLRequest* request);
virtual void OnPACScriptError(int line_number, const string16& error);
+ virtual void OnAuthRequired(net::URLRequest* request,
+ const net::AuthChallengeInfo& auth_info);
void InitRequestStatesIfNew(int request_id);