| Index: chrome/browser/extensions/extension_webrequest_api.cc
|
| diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc
|
| index cf13a5290c116aaa7377380c0de81a0123ae10d9..50f26bedb3ad99a2cd34078b70b0593b252411fc 100644
|
| --- a/chrome/browser/extensions/extension_webrequest_api.cc
|
| +++ b/chrome/browser/extensions/extension_webrequest_api.cc
|
| @@ -303,6 +303,10 @@ struct ExtensionWebRequestEventRouter::BlockedRequest {
|
| // for OnBeforeSendHeaders.
|
| net::HttpRequestHeaders* request_headers;
|
|
|
| + // If non-empty, this contains the auth credentials that may be filled in.
|
| + // Only valid for OnAuthRequired.
|
| + net::AuthCredentials* auth_credentials;
|
| +
|
| // Time the request was paused. Used for logging purposes.
|
| base::Time blocking_time;
|
|
|
| @@ -316,7 +320,8 @@ struct ExtensionWebRequestEventRouter::BlockedRequest {
|
| net_log(NULL),
|
| callback(NULL),
|
| new_url(NULL),
|
| - request_headers(NULL) {}
|
| + request_headers(NULL),
|
| + auth_credentials(NULL) {}
|
| };
|
|
|
| bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue(
|
| @@ -585,25 +590,29 @@ void ExtensionWebRequestEventRouter::OnSendHeaders(
|
| DispatchEvent(profile, request, listeners, args);
|
| }
|
|
|
| -void ExtensionWebRequestEventRouter::OnAuthRequired(
|
| +int ExtensionWebRequestEventRouter::OnAuthRequired(
|
| void* profile,
|
| ExtensionInfoMap* extension_info_map,
|
| net::URLRequest* request,
|
| - const net::AuthChallengeInfo& auth_info) {
|
| + const net::AuthChallengeInfo& auth_info,
|
| + net::CompletionCallback* callback,
|
| + net::AuthCredentials* credentials) {
|
| + // No profile means that this is for authentication challenges in the
|
| + // system context. Skip in that case.
|
| if (!profile)
|
| - return;
|
| + return net::OK;
|
|
|
| base::Time time(base::Time::Now());
|
|
|
| if (!HasWebRequestScheme(request->url()))
|
| - return;
|
| + return net::OK;
|
|
|
| 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;
|
| + return net::OK;
|
|
|
| ListValue args;
|
| DictionaryValue* dict = new DictionaryValue();
|
| @@ -628,7 +637,13 @@ void ExtensionWebRequestEventRouter::OnAuthRequired(
|
| dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| args.Append(dict);
|
|
|
| - DispatchEvent(profile, request, listeners, args);
|
| + if (DispatchEvent(profile, request, listeners, args)) {
|
| + blocked_requests_[request->identifier()].event = kOnAuthRequired;
|
| + blocked_requests_[request->identifier()].callback = callback;
|
| + blocked_requests_[request->identifier()].auth_credentials = credentials;
|
| + return net::ERR_IO_PENDING;
|
| + }
|
| + return net::OK;
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnBeforeRedirect(
|
| @@ -1124,6 +1139,9 @@ linked_ptr<ExtensionWebRequestEventRouter::EventResponseDelta>
|
| }
|
| }
|
|
|
| + if (blocked_request->event == kOnAuthRequired)
|
| + result->auth_credentials.swap(response->auth_credentials);
|
| +
|
| return result;
|
| }
|
|
|
| @@ -1255,6 +1273,28 @@ void ExtensionWebRequestEventRouter::MergeOnBeforeSendHeadersResponses(
|
| }
|
| }
|
|
|
| +void ExtensionWebRequestEventRouter::MergeOnAuthRequiredResponses(
|
| + BlockedRequest* request,
|
| + std::list<std::string>* conflicting_extensions) const {
|
| + CHECK(request);
|
| + CHECK(request->auth_credentials);
|
| + bool credentials_set = false;
|
| +
|
| + const EventResponseDeltas& deltas = request->response_deltas;
|
| + for (EventResponseDeltas::const_iterator it = deltas.begin();
|
| + it != deltas.end();
|
| + ++it) {
|
| + if (!(*it)->auth_credentials.get())
|
| + continue;
|
| + if (credentials_set) {
|
| + conflicting_extensions->push_back((*it)->extension_id);
|
| + } else {
|
| + *request->auth_credentials = *(*it)->auth_credentials;
|
| + credentials_set = true;
|
| + }
|
| + }
|
| +}
|
| +
|
| void ExtensionWebRequestEventRouter::DecrementBlockCount(
|
| void* profile,
|
| const std::string& extension_id,
|
| @@ -1310,6 +1350,9 @@ void ExtensionWebRequestEventRouter::DecrementBlockCount(
|
| CHECK(blocked_request.callback);
|
| MergeOnBeforeSendHeadersResponses(&blocked_request,
|
| &conflicting_extensions);
|
| + } else if (blocked_request.event == kOnAuthRequired) {
|
| + CHECK(blocked_request.callback);
|
| + MergeOnAuthRequiredResponses(&blocked_request, &conflicting_extensions);
|
| } else {
|
| NOTREACHED();
|
| }
|
| @@ -1490,6 +1533,21 @@ bool WebRequestEventHandled::RunImpl() {
|
| response->request_headers->SetHeader(name, value);
|
| }
|
| }
|
| +
|
| + if (value->HasKey(keys::kAuthCredentialsKey)) {
|
| + DictionaryValue* credentials_value = NULL;
|
| + EXTENSION_FUNCTION_VALIDATE(value->GetDictionary(
|
| + keys::kAuthCredentialsKey,
|
| + &credentials_value));
|
| + response->auth_credentials.reset(new net::AuthCredentials());
|
| + EXTENSION_FUNCTION_VALIDATE(
|
| + credentials_value->GetString(keys::kUsernameKey,
|
| + &response->auth_credentials->username));
|
| + EXTENSION_FUNCTION_VALIDATE(
|
| + credentials_value->GetString(keys::kPasswordKey,
|
| + &response->auth_credentials->password));
|
| + response->auth_credentials->is_valid = true;
|
| + }
|
| }
|
|
|
| ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
|
|
|