Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Unified Diff: chrome/browser/extensions/extension_webrequest_api.cc

Issue 8015004: webRequest.onAuthRequired listeners can provide authentication credentials. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Handle multiple blocking onAuthRequired Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 36ee72c7d9e8df807b8ae64a070ebc63077957b4..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();
@@ -620,7 +629,7 @@ void ExtensionWebRequestEventRouter::OnAuthRequired(
challenger->SetInteger(keys::kPortKey, auth_info.challenger.port());
dict->Set(keys::kChallengerKey, challenger);
dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
- if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) {
+ if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
dict->Set(keys::kResponseHeadersKey,
GetResponseHeadersList(request->response_headers()));
}
@@ -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(

Powered by Google App Engine
This is Rietveld 408576698