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

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: feedback 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[] = {
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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 false;
302 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;
310 }
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 dict->SetDouble(keys::kTimeStampKey, 320 dict->SetDouble(keys::kTimeStampKey,
312 request->request_time().ToDoubleT() * 1000); 321 request->request_time().ToDoubleT() * 1000);
313 args.Append(dict); 322 args.Append(dict);
314 323
324 return DispatchEvent(profile_id, event_router, request, callback, listeners,
325 args);
326 }
327
328 bool 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 false;
337
338 HttpRequestMap::iterator iter = http_requests_.find(request_id);
339 if (iter == http_requests_.end())
340 return false;
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 false;
349
350 ListValue args;
351 DictionaryValue* dict = new DictionaryValue();
352 dict->SetString(keys::kUrlKey, request->url().spec());
353 dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
354 // TODO(mpcomplete): request headers.
355 return DispatchEvent(profile_id, event_router, request, callback, listeners,
356 args);
357 }
358
359 void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
360 ProfileId profile_id, net::URLRequest* request) {
361 http_requests_.erase(request->identifier());
362 }
363
364 bool ExtensionWebRequestEventRouter::DispatchEvent(
365 ProfileId profile_id,
366 ExtensionEventRouterForwarder* event_router,
367 net::URLRequest* request,
368 net::CompletionCallback* callback,
369 const std::vector<const EventListener*>& listeners,
370 const ListValue& args) {
315 std::string json_args; 371 std::string json_args;
316 base::JSONWriter::Write(&args, false, &json_args); 372 base::JSONWriter::Write(&args, false, &json_args);
317 373
318 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 374 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
319 // pairs into a single message sent to a list of sub_event_names. 375 // pairs into a single message sent to a list of sub_event_names.
320 int num_handlers_blocking = 0; 376 int num_handlers_blocking = 0;
321 for (std::vector<const EventListener*>::iterator it = listeners.begin(); 377 for (std::vector<const EventListener*>::const_iterator it = listeners.begin();
322 it != listeners.end(); ++it) { 378 it != listeners.end(); ++it) {
323 event_router->DispatchEventToExtension( 379 event_router->DispatchEventToExtension(
324 (*it)->extension_id, (*it)->sub_event_name, json_args, 380 (*it)->extension_id, (*it)->sub_event_name, json_args,
325 profile_id, true, GURL()); 381 profile_id, true, GURL());
326 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { 382 if (callback && (*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) {
327 (*it)->blocked_requests.insert(request->identifier()); 383 (*it)->blocked_requests.insert(request->identifier());
328 ++num_handlers_blocking; 384 ++num_handlers_blocking;
329 } 385 }
330 } 386 }
331 387
332 if (num_handlers_blocking > 0) { 388 if (num_handlers_blocking > 0) {
333 CHECK(blocked_requests_.find(request->identifier()) == 389 CHECK(blocked_requests_.find(request->identifier()) ==
334 blocked_requests_.end()); 390 blocked_requests_.end());
335 blocked_requests_[request->identifier()].num_handlers_blocking = 391 blocked_requests_[request->identifier()].num_handlers_blocking =
336 num_handlers_blocking; 392 num_handlers_blocking;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 if (!it->filter.types.empty() && 493 if (!it->filter.types.empty() &&
438 std::find(it->filter.types.begin(), it->filter.types.end(), 494 std::find(it->filter.types.begin(), it->filter.types.end(),
439 resource_type) == it->filter.types.end()) 495 resource_type) == it->filter.types.end())
440 continue; 496 continue;
441 497
442 matching_listeners.push_back(&(*it)); 498 matching_listeners.push_back(&(*it));
443 } 499 }
444 return matching_listeners; 500 return matching_listeners;
445 } 501 }
446 502
503 std::vector<const ExtensionWebRequestEventRouter::EventListener*>
504 ExtensionWebRequestEventRouter::GetMatchingListeners(
505 ProfileId profile_id,
506 const std::string& event_name,
507 net::URLRequest* request) {
508 int tab_id = -1;
509 int window_id = -1;
510 ResourceType::Type resource_type = ResourceType::LAST_TYPE;
511 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
512
513 return GetMatchingListeners(
514 profile_id, event_name, request->url(), tab_id, window_id, resource_type);
515 }
516
447 void ExtensionWebRequestEventRouter::DecrementBlockCount(uint64 request_id, 517 void ExtensionWebRequestEventRouter::DecrementBlockCount(uint64 request_id,
448 bool cancel) { 518 bool cancel) {
449 // It's possible that this request was already cancelled by a previous event 519 // It's possible that this request was already cancelled by a previous event
450 // handler. If so, ignore this response. 520 // handler. If so, ignore this response.
451 if (blocked_requests_.find(request_id) == blocked_requests_.end()) 521 if (blocked_requests_.find(request_id) == blocked_requests_.end())
452 return; 522 return;
453 523
454 BlockedRequest& blocked_request = blocked_requests_[request_id]; 524 BlockedRequest& blocked_request = blocked_requests_[request_id];
455 int num_handlers_blocking = --blocked_request.num_handlers_blocking; 525 int num_handlers_blocking = --blocked_request.num_handlers_blocking;
456 CHECK_GE(num_handlers_blocking, 0); 526 CHECK_GE(num_handlers_blocking, 0);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 594
525 BrowserThread::PostTask( 595 BrowserThread::PostTask(
526 BrowserThread::IO, FROM_HERE, 596 BrowserThread::IO, FROM_HERE,
527 NewRunnableFunction( 597 NewRunnableFunction(
528 &EventHandledOnIOThread, 598 &EventHandledOnIOThread,
529 profile()->GetRuntimeId(), extension_id(), 599 profile()->GetRuntimeId(), extension_id(),
530 event_name, sub_event_name, request_id, cancel)); 600 event_name, sub_event_name, request_id, cancel));
531 601
532 return true; 602 return true;
533 } 603 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698