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

Side by Side Diff: chrome/browser/extensions/api/web_request/web_request_api.cc

Issue 10451071: Add support for response header manipulation in Declarative WebRequest API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Made header value comparison case-insensitive Created 8 years, 6 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/api/web_request/web_request_api.h" 5 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/time.h" 14 #include "base/time.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "base/values.h" 16 #include "base/values.h"
17 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chrome_content_browser_client.h" 18 #include "chrome/browser/chrome_content_browser_client.h"
19 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h "
19 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h" 20 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h"
20 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" 21 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h"
21 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" 22 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
22 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" 23 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h"
23 #include "chrome/browser/extensions/extension_event_router.h" 24 #include "chrome/browser/extensions/extension_event_router.h"
24 #include "chrome/browser/extensions/extension_info_map.h" 25 #include "chrome/browser/extensions/extension_info_map.h"
25 #include "chrome/browser/extensions/extension_prefs.h" 26 #include "chrome/browser/extensions/extension_prefs.h"
26 #include "chrome/browser/extensions/extension_service.h" 27 #include "chrome/browser/extensions/extension_service.h"
27 #include "chrome/browser/extensions/extension_tab_id_map.h" 28 #include "chrome/browser/extensions/extension_tab_id_map.h"
28 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 482
482 request_time_tracker_->LogRequestStartTime(request->identifier(), 483 request_time_tracker_->LogRequestStartTime(request->identifier(),
483 base::Time::Now(), 484 base::Time::Now(),
484 request->url(), 485 request->url(),
485 profile); 486 profile);
486 487
487 // Whether to initialized blocked_requests_. 488 // Whether to initialized blocked_requests_.
488 bool initialize_blocked_requests = false; 489 bool initialize_blocked_requests = false;
489 490
490 initialize_blocked_requests |= 491 initialize_blocked_requests |=
491 ProcessDeclarativeRules(request, extensions::ON_BEFORE_REQUEST); 492 ProcessDeclarativeRules(request, extensions::ON_BEFORE_REQUEST, NULL);
492 493
493 int extra_info_spec = 0; 494 int extra_info_spec = 0;
494 std::vector<const EventListener*> listeners = 495 std::vector<const EventListener*> listeners =
495 GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest, 496 GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest,
496 request, &extra_info_spec); 497 request, &extra_info_spec);
497 if (!listeners.empty() && 498 if (!listeners.empty() &&
498 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { 499 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) {
499 ListValue args; 500 ListValue args;
500 DictionaryValue* dict = new DictionaryValue(); 501 DictionaryValue* dict = new DictionaryValue();
501 ExtractRequestInfo(request, dict); 502 ExtractRequestInfo(request, dict);
(...skipping 27 matching lines...) Expand all
529 net::URLRequest* request, 530 net::URLRequest* request,
530 const net::CompletionCallback& callback, 531 const net::CompletionCallback& callback,
531 net::HttpRequestHeaders* headers) { 532 net::HttpRequestHeaders* headers) {
532 // We hide events from the system context as well as sensitive requests. 533 // We hide events from the system context as well as sensitive requests.
533 if (!profile || helpers::HideRequestForURL(request->url())) 534 if (!profile || helpers::HideRequestForURL(request->url()))
534 return net::OK; 535 return net::OK;
535 536
536 bool initialize_blocked_requests = false; 537 bool initialize_blocked_requests = false;
537 538
538 initialize_blocked_requests |= 539 initialize_blocked_requests |=
539 ProcessDeclarativeRules(request, extensions::ON_BEFORE_SEND_HEADERS); 540 ProcessDeclarativeRules(request, extensions::ON_BEFORE_SEND_HEADERS,
541 NULL);
540 542
541 int extra_info_spec = 0; 543 int extra_info_spec = 0;
542 std::vector<const EventListener*> listeners = 544 std::vector<const EventListener*> listeners =
543 GetMatchingListeners(profile, extension_info_map, 545 GetMatchingListeners(profile, extension_info_map,
544 keys::kOnBeforeSendHeaders, request, 546 keys::kOnBeforeSendHeaders, request,
545 &extra_info_spec); 547 &extra_info_spec);
546 if (!listeners.empty() && 548 if (!listeners.empty() &&
547 !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) { 549 !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) {
548 ListValue args; 550 ListValue args;
549 DictionaryValue* dict = new DictionaryValue(); 551 DictionaryValue* dict = new DictionaryValue();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 void* profile, 611 void* profile,
610 ExtensionInfoMap* extension_info_map, 612 ExtensionInfoMap* extension_info_map,
611 net::URLRequest* request, 613 net::URLRequest* request,
612 const net::CompletionCallback& callback, 614 const net::CompletionCallback& callback,
613 net::HttpResponseHeaders* original_response_headers, 615 net::HttpResponseHeaders* original_response_headers,
614 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) { 616 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
615 // We hide events from the system context as well as sensitive requests. 617 // We hide events from the system context as well as sensitive requests.
616 if (!profile || helpers::HideRequestForURL(request->url())) 618 if (!profile || helpers::HideRequestForURL(request->url()))
617 return net::OK; 619 return net::OK;
618 620
621 bool initialize_blocked_requests = false;
622
623 initialize_blocked_requests |=
624 ProcessDeclarativeRules(request, extensions::ON_HEADERS_RECEIVED,
625 original_response_headers);
626
619 int extra_info_spec = 0; 627 int extra_info_spec = 0;
620 std::vector<const EventListener*> listeners = 628 std::vector<const EventListener*> listeners =
621 GetMatchingListeners(profile, extension_info_map, 629 GetMatchingListeners(profile, extension_info_map,
622 keys::kOnHeadersReceived, request, 630 keys::kOnHeadersReceived, request,
623 &extra_info_spec); 631 &extra_info_spec);
624 632
625 if (listeners.empty()) 633 if (!listeners.empty() &&
626 return net::OK; 634 !GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) {
635 ListValue args;
636 DictionaryValue* dict = new DictionaryValue();
637 ExtractRequestInfo(request, dict);
638 dict->SetString(keys::kStatusLineKey,
639 original_response_headers->GetStatusLine());
640 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
641 dict->Set(keys::kResponseHeadersKey,
642 GetResponseHeadersList(original_response_headers));
643 }
644 args.Append(dict);
627 645
628 if (GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) 646 initialize_blocked_requests |=
629 return net::OK; 647 DispatchEvent(profile, request, listeners, args);
648 }
630 649
631 ListValue args; 650 if (!initialize_blocked_requests)
632 DictionaryValue* dict = new DictionaryValue(); 651 return net::OK; // Nobody saw a reason for modifying the request.
633 ExtractRequestInfo(request, dict);
634 dict->SetString(keys::kStatusLineKey,
635 original_response_headers->GetStatusLine());
636 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
637 dict->Set(keys::kResponseHeadersKey,
638 GetResponseHeadersList(original_response_headers));
639 }
640 args.Append(dict);
641 652
642 if (DispatchEvent(profile, request, listeners, args)) { 653 blocked_requests_[request->identifier()].event = kOnHeadersReceived;
643 blocked_requests_[request->identifier()].event = kOnHeadersReceived; 654 blocked_requests_[request->identifier()].callback = callback;
644 blocked_requests_[request->identifier()].callback = callback; 655 blocked_requests_[request->identifier()].net_log = &request->net_log();
645 blocked_requests_[request->identifier()].net_log = &request->net_log(); 656 blocked_requests_[request->identifier()].override_response_headers =
646 blocked_requests_[request->identifier()].override_response_headers = 657 override_response_headers;
647 override_response_headers; 658 blocked_requests_[request->identifier()].original_response_headers =
648 blocked_requests_[request->identifier()].original_response_headers = 659 original_response_headers;
649 original_response_headers; 660
661 if (blocked_requests_[request->identifier()].num_handlers_blocking == 0) {
662 // If there are no blocking handlers, only the declarative rules tried
663 // to modify the request and we can respond synchronously.
664 return ExecuteDeltas(profile, request->identifier(),
665 false /* call_callback*/);
666 } else {
650 return net::ERR_IO_PENDING; 667 return net::ERR_IO_PENDING;
651 } 668 }
652 return net::OK;
653 } 669 }
654 670
655 net::NetworkDelegate::AuthRequiredResponse 671 net::NetworkDelegate::AuthRequiredResponse
656 ExtensionWebRequestEventRouter::OnAuthRequired( 672 ExtensionWebRequestEventRouter::OnAuthRequired(
657 void* profile, 673 void* profile,
658 ExtensionInfoMap* extension_info_map, 674 ExtensionInfoMap* extension_info_map,
659 net::URLRequest* request, 675 net::URLRequest* request,
660 const net::AuthChallengeInfo& auth_info, 676 const net::AuthChallengeInfo& auth_info,
661 const net::NetworkDelegate::AuthCallback& callback, 677 const net::NetworkDelegate::AuthCallback& callback,
662 net::AuthCredentials* credentials) { 678 net::AuthCredentials* credentials) {
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 if (call_callback) 1393 if (call_callback)
1378 callback.Run(response); 1394 callback.Run(response);
1379 } else { 1395 } else {
1380 blocked_requests_.erase(request_id); 1396 blocked_requests_.erase(request_id);
1381 } 1397 }
1382 return rv; 1398 return rv;
1383 } 1399 }
1384 1400
1385 bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules( 1401 bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules(
1386 net::URLRequest* request, 1402 net::URLRequest* request,
1387 extensions::RequestStages request_stage) { 1403 extensions::RequestStages request_stage,
1404 net::HttpResponseHeaders* original_response_headers) {
1388 if (!rules_registry_.get()) 1405 if (!rules_registry_.get())
1389 return false; 1406 return false;
1390 1407
1391 base::Time start = base::Time::Now(); 1408 base::Time start = base::Time::Now();
1392 1409
1393 // TODO(battre): Annotate deltas with extension IDs, so that we can 1410 // TODO(battre): Annotate deltas with extension IDs, so that we can
1394 // - Sort deltas by precedence 1411 // - Sort deltas by precedence
1395 // - Check whether extensions have host permissions. 1412 // - Check whether extensions have host permissions.
1413 extensions::WebRequestRule::OptionalRequestData optional_request_data;
1414 optional_request_data.original_response_headers =
1415 original_response_headers;
1396 std::list<linked_ptr<helpers::EventResponseDelta> > result = 1416 std::list<linked_ptr<helpers::EventResponseDelta> > result =
1397 rules_registry_->CreateDeltas(request, request_stage); 1417 rules_registry_->CreateDeltas(request, request_stage,
1418 optional_request_data);
1398 1419
1399 base::TimeDelta elapsed_time = start - base::Time::Now(); 1420 base::TimeDelta elapsed_time = start - base::Time::Now();
1400 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay", 1421 UMA_HISTOGRAM_TIMES("Extensions.DeclarativeWebRequestNetworkDelay",
1401 elapsed_time); 1422 elapsed_time);
1402 1423
1403 if (result.empty()) 1424 if (result.empty())
1404 return false; 1425 return false;
1405 1426
1406 helpers::EventResponseDeltas& deltas = 1427 helpers::EventResponseDeltas& deltas =
1407 blocked_requests_[request->identifier()].response_deltas; 1428 blocked_requests_[request->identifier()].response_deltas;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 } else if ((*it)->name().find("AdBlock") != std::string::npos) { 1751 } else if ((*it)->name().find("AdBlock") != std::string::npos) {
1731 adblock = true; 1752 adblock = true;
1732 } else { 1753 } else {
1733 other = true; 1754 other = true;
1734 } 1755 }
1735 } 1756 }
1736 } 1757 }
1737 1758
1738 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); 1759 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other));
1739 } 1760 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698