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

Side by Side Diff: chrome/browser/extensions/extension_webrequest_api.cc

Issue 6698009: Add request_id to HttpRequestInfo and pass it to the NetworkDelegate for events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test fixes Created 9 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_webrequest_api.h" 5 #include "chrome/browser/extensions/extension_webrequest_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/extensions/extension_event_router_forwarder.h" 13 #include "chrome/browser/extensions/extension_event_router_forwarder.h"
14 #include "chrome/browser/extensions/extension_tab_id_map.h" 14 #include "chrome/browser/extensions/extension_tab_id_map.h"
15 #include "chrome/browser/extensions/extension_webrequest_api_constants.h" 15 #include "chrome/browser/extensions/extension_webrequest_api_constants.h"
16 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/extensions/extension.h" 17 #include "chrome/common/extensions/extension.h"
18 #include "chrome/common/extensions/extension_extent.h" 18 #include "chrome/common/extensions/extension_extent.h"
19 #include "chrome/common/extensions/url_pattern.h" 19 #include "chrome/common/extensions/url_pattern.h"
20 #include "chrome/common/url_constants.h"
20 #include "content/browser/browser_thread.h" 21 #include "content/browser/browser_thread.h"
21 #include "content/browser/renderer_host/resource_dispatcher_host.h" 22 #include "content/browser/renderer_host/resource_dispatcher_host.h"
22 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" 23 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
23 #include "net/base/net_errors.h" 24 #include "net/base/net_errors.h"
24 #include "net/url_request/url_request.h" 25 #include "net/url_request/url_request.h"
25 #include "googleurl/src/gurl.h" 26 #include "googleurl/src/gurl.h"
26 27
27 namespace keys = extension_webrequest_api_constants; 28 namespace keys = extension_webrequest_api_constants;
28 29
29 namespace { 30 namespace {
30 31
31 // List of all the webRequest events. 32 // List of all the webRequest events.
32 static const char *kWebRequestEvents[] = { 33 static const char *kWebRequestEvents[] = {
willchan no longer on Chromium 2011/03/26 01:46:49 Where's OnRequestDeleted? Nit: FYI, these should
Matt Perry 2011/03/28 22:51:01 These are only the extension-visible events. Exten
willchan no longer on Chromium 2011/03/29 20:46:27 OK, I defer to you here. Just noting that this mea
33 keys::kOnBeforeRedirect, 34 keys::kOnBeforeRedirect,
34 keys::kOnBeforeRequest, 35 keys::kOnBeforeRequest,
36 keys::kOnBeforeSendHeaders,
35 keys::kOnCompleted, 37 keys::kOnCompleted,
36 keys::kOnErrorOccurred, 38 keys::kOnErrorOccurred,
37 keys::kOnHeadersReceived, 39 keys::kOnHeadersReceived,
38 keys::kOnRequestSent 40 keys::kOnRequestSent
39 }; 41 };
40 42
41 static const char* kResourceTypeStrings[] = { 43 static const char* kResourceTypeStrings[] = {
42 "main_frame", 44 "main_frame",
43 "sub_frame", 45 "sub_frame",
44 "stylesheet", 46 "stylesheet",
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 // Internal representation of the extraInfoSpec parameter on webRequest events, 150 // Internal representation of the extraInfoSpec parameter on webRequest events,
149 // used to specify extra information to be included with network events. 151 // used to specify extra information to be included with network events.
150 struct ExtensionWebRequestEventRouter::ExtraInfoSpec { 152 struct ExtensionWebRequestEventRouter::ExtraInfoSpec {
151 enum Flags { 153 enum Flags {
152 REQUEST_LINE = 1<<0, 154 REQUEST_LINE = 1<<0,
153 REQUEST_HEADERS = 1<<1, 155 REQUEST_HEADERS = 1<<1,
154 STATUS_LINE = 1<<2, 156 STATUS_LINE = 1<<2,
155 RESPONSE_HEADERS = 1<<3, 157 RESPONSE_HEADERS = 1<<3,
156 REDIRECT_REQUEST_LINE = 1<<4, 158 REDIRECT_REQUEST_LINE = 1<<4,
157 REDIRECT_REQUEST_HEADERS = 1<<5, 159 REDIRECT_REQUEST_HEADERS = 1<<5,
158 BLOCKING = 1<<5, 160 BLOCKING = 1<<6,
159 }; 161 };
160 162
161 static bool InitFromValue(const ListValue& value, int* extra_info_spec); 163 static bool InitFromValue(const ListValue& value, int* extra_info_spec);
162 }; 164 };
163 165
164 // Represents a single unique listener to an event, along with whatever filter 166 // Represents a single unique listener to an event, along with whatever filter
165 // parameters and extra_info_spec were specified at the time the listener was 167 // parameters and extra_info_spec were specified at the time the listener was
166 // added. 168 // added.
167 struct ExtensionWebRequestEventRouter::EventListener { 169 struct ExtensionWebRequestEventRouter::EventListener {
168 std::string extension_id; 170 std::string extension_id;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 ExtensionWebRequestEventRouter* ExtensionWebRequestEventRouter::GetInstance() { 275 ExtensionWebRequestEventRouter* ExtensionWebRequestEventRouter::GetInstance() {
274 return Singleton<ExtensionWebRequestEventRouter>::get(); 276 return Singleton<ExtensionWebRequestEventRouter>::get();
275 } 277 }
276 278
277 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() { 279 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() {
278 } 280 }
279 281
280 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { 282 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() {
281 } 283 }
282 284
283 bool ExtensionWebRequestEventRouter::OnBeforeRequest( 285 int ExtensionWebRequestEventRouter::OnBeforeRequest(
284 ProfileId profile_id, 286 ProfileId profile_id,
285 ExtensionEventRouterForwarder* event_router, 287 ExtensionEventRouterForwarder* event_router,
286 net::URLRequest* request, 288 net::URLRequest* request,
287 net::CompletionCallback* callback) { 289 net::CompletionCallback* callback) {
288 // TODO(jochen): Figure out what to do with events from the system context. 290 // TODO(jochen): Figure out what to do with events from the system context.
289 if (profile_id == Profile::kInvalidProfileId) 291 if (profile_id == Profile::kInvalidProfileId)
290 return false; 292 return net::OK;
291 293
292 int tab_id = -1; 294 int tab_id = -1;
293 int window_id = -1; 295 int window_id = -1;
294 ResourceType::Type resource_type = ResourceType::LAST_TYPE; 296 ResourceType::Type resource_type = ResourceType::LAST_TYPE;
295 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type); 297 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
296 298
297 std::vector<const EventListener*> listeners = 299 std::vector<const EventListener*> listeners =
298 GetMatchingListeners(profile_id, keys::kOnBeforeRequest, request->url(), 300 GetMatchingListeners(profile_id, keys::kOnBeforeRequest, request->url(),
299 tab_id, window_id, resource_type); 301 tab_id, window_id, resource_type);
300 if (listeners.empty()) 302 if (listeners.empty())
301 return false; 303 return net::OK;
304
305 // If this is an HTTP request, keep track of it. HTTP-specific events only
306 // have the request ID, so we'll need to look up the URLRequest from that.
307 if (request->url().SchemeIs(chrome::kHttpScheme) ||
308 request->url().SchemeIs(chrome::kHttpsScheme)) {
309 http_requests_[request->identifier()] = request;
willchan no longer on Chromium 2011/03/26 01:46:49 As discussed previously, this may include more tha
Matt Perry 2011/03/28 22:51:01 OK. I think it doesn't affect anything if these ar
willchan no longer on Chromium 2011/03/29 20:46:27 No there isn't. I suspect that eventually you'll w
310 }
302 311
303 ListValue args; 312 ListValue args;
304 DictionaryValue* dict = new DictionaryValue(); 313 DictionaryValue* dict = new DictionaryValue();
305 dict->SetString(keys::kRequestIdKey, 314 dict->SetString(keys::kRequestIdKey,
306 base::Uint64ToString(request->identifier())); 315 base::Uint64ToString(request->identifier()));
307 dict->SetString(keys::kUrlKey, request->url().spec()); 316 dict->SetString(keys::kUrlKey, request->url().spec());
308 dict->SetString(keys::kMethodKey, request->method()); 317 dict->SetString(keys::kMethodKey, request->method());
309 dict->SetInteger(keys::kTabIdKey, tab_id); 318 dict->SetInteger(keys::kTabIdKey, tab_id);
310 dict->SetString(keys::kTypeKey, ResourceTypeToString(resource_type)); 319 dict->SetString(keys::kTypeKey, ResourceTypeToString(resource_type));
311 args.Append(dict); 320 args.Append(dict);
312 321
322 if (DispatchEvent(profile_id, event_router, request, callback, listeners,
323 args))
324 return net::ERR_IO_PENDING;
325 return net::OK;
326 }
327
328 int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
329 ProfileId profile_id,
330 ExtensionEventRouterForwarder* event_router,
331 uint64 request_id,
332 net::HttpRequestHeaders* headers,
333 net::CompletionCallback* callback) {
334 // TODO(jochen): Figure out what to do with events from the system context.
335 if (profile_id == Profile::kInvalidProfileId)
336 return net::OK;
337
338 HttpRequestMap::iterator iter = http_requests_.find(request_id);
339 if (iter == http_requests_.end())
340 return net::OK;
341
342 net::URLRequest* request = iter->second;
343 http_requests_.erase(iter);
344
345 std::vector<const EventListener*> listeners =
346 GetMatchingListeners(profile_id, keys::kOnBeforeSendHeaders, request);
347 if (listeners.empty())
348 return net::OK;
349
350 ListValue args;
351 DictionaryValue* dict = new DictionaryValue();
352 dict->SetString(keys::kRequestIdKey,
353 base::Uint64ToString(request->identifier()));
354 dict->SetString(keys::kUrlKey, request->url().spec());
355 dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
356 // TODO(mpcomplete): request headers.
357 args.Append(dict);
358
359 if (DispatchEvent(profile_id, event_router, request, callback, listeners,
360 args))
361 return net::ERR_IO_PENDING;
362 return net::OK;
363 }
364
365 void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
366 ProfileId profile_id, net::URLRequest* request) {
367 http_requests_.erase(request->identifier());
willchan no longer on Chromium 2011/03/26 01:46:49 Doesn't erase() cause crashes if the key doesn't e
Matt Perry 2011/03/28 22:51:01 No, that's not an error.
willchan no longer on Chromium 2011/03/29 20:46:27 Learn something new everyday.
368 }
369
370 bool ExtensionWebRequestEventRouter::DispatchEvent(
371 ProfileId profile_id,
372 ExtensionEventRouterForwarder* event_router,
373 net::URLRequest* request,
374 net::CompletionCallback* callback,
375 const std::vector<const EventListener*>& listeners,
376 const ListValue& args) {
313 std::string json_args; 377 std::string json_args;
314 base::JSONWriter::Write(&args, false, &json_args); 378 base::JSONWriter::Write(&args, false, &json_args);
315 379
316 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 380 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
317 // pairs into a single message sent to a list of sub_event_names. 381 // pairs into a single message sent to a list of sub_event_names.
318 int num_handlers_blocking = 0; 382 int num_handlers_blocking = 0;
319 for (std::vector<const EventListener*>::iterator it = listeners.begin(); 383 for (std::vector<const EventListener*>::const_iterator it = listeners.begin();
320 it != listeners.end(); ++it) { 384 it != listeners.end(); ++it) {
321 event_router->DispatchEventToExtension( 385 event_router->DispatchEventToExtension(
322 (*it)->extension_id, (*it)->sub_event_name, json_args, 386 (*it)->extension_id, (*it)->sub_event_name, json_args,
323 profile_id, true, GURL()); 387 profile_id, true, GURL());
324 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { 388 if (callback && (*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) {
325 (*it)->blocked_requests.insert(request->identifier()); 389 (*it)->blocked_requests.insert(request->identifier());
326 ++num_handlers_blocking; 390 ++num_handlers_blocking;
327 } 391 }
328 } 392 }
329 393
330 if (num_handlers_blocking > 0) { 394 if (num_handlers_blocking > 0) {
331 CHECK(blocked_requests_.find(request->identifier()) == 395 CHECK(blocked_requests_.find(request->identifier()) ==
332 blocked_requests_.end()); 396 blocked_requests_.end());
333 blocked_requests_[request->identifier()].num_handlers_blocking = 397 blocked_requests_[request->identifier()].num_handlers_blocking =
334 num_handlers_blocking; 398 num_handlers_blocking;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 if (!it->filter.types.empty() && 499 if (!it->filter.types.empty() &&
436 std::find(it->filter.types.begin(), it->filter.types.end(), 500 std::find(it->filter.types.begin(), it->filter.types.end(),
437 resource_type) == it->filter.types.end()) 501 resource_type) == it->filter.types.end())
438 continue; 502 continue;
439 503
440 matching_listeners.push_back(&(*it)); 504 matching_listeners.push_back(&(*it));
441 } 505 }
442 return matching_listeners; 506 return matching_listeners;
443 } 507 }
444 508
509 std::vector<const ExtensionWebRequestEventRouter::EventListener*>
510 ExtensionWebRequestEventRouter::GetMatchingListeners(
511 ProfileId profile_id,
512 const std::string& event_name,
513 net::URLRequest* request) {
514 int tab_id = -1;
515 int window_id = -1;
516 ResourceType::Type resource_type = ResourceType::LAST_TYPE;
517 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
518
519 return GetMatchingListeners(
520 profile_id, event_name, request->url(), tab_id, window_id, resource_type);
521 }
522
445 void ExtensionWebRequestEventRouter::DecrementBlockCount(uint64 request_id, 523 void ExtensionWebRequestEventRouter::DecrementBlockCount(uint64 request_id,
446 bool cancel) { 524 bool cancel) {
447 // It's possible that this request was already cancelled by a previous event 525 // It's possible that this request was already cancelled by a previous event
448 // handler. If so, ignore this response. 526 // handler. If so, ignore this response.
449 if (blocked_requests_.find(request_id) == blocked_requests_.end()) 527 if (blocked_requests_.find(request_id) == blocked_requests_.end())
450 return; 528 return;
451 529
452 BlockedRequest& blocked_request = blocked_requests_[request_id]; 530 BlockedRequest& blocked_request = blocked_requests_[request_id];
453 int num_handlers_blocking = --blocked_request.num_handlers_blocking; 531 int num_handlers_blocking = --blocked_request.num_handlers_blocking;
454 CHECK_GE(num_handlers_blocking, 0); 532 CHECK_GE(num_handlers_blocking, 0);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 600
523 BrowserThread::PostTask( 601 BrowserThread::PostTask(
524 BrowserThread::IO, FROM_HERE, 602 BrowserThread::IO, FROM_HERE,
525 NewRunnableFunction( 603 NewRunnableFunction(
526 &EventHandledOnIOThread, 604 &EventHandledOnIOThread,
527 profile()->GetRuntimeId(), extension_id(), 605 profile()->GetRuntimeId(), extension_id(),
528 event_name, sub_event_name, request_id, cancel)); 606 event_name, sub_event_name, request_id, cancel));
529 607
530 return true; 608 return true;
531 } 609 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698