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

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

Issue 12491012: Improved extension activity logging for the chrome.webRequest API. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add activity log enabled check, and create constants for fields in the activity log Created 7 years, 8 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
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/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
17 #include "base/values.h" 17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chrome_content_browser_client.h" 19 #include "chrome/browser/chrome_content_browser_client.h"
20 #include "chrome/browser/extensions/activity_log.h"
20 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" 21 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
21 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h" 22 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h"
22 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h" 23 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h"
23 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helper s.h" 24 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helper s.h"
24 #include "chrome/browser/extensions/api/web_request/upload_data_presenter.h" 25 #include "chrome/browser/extensions/api/web_request/upload_data_presenter.h"
26 #include "chrome/browser/extensions/api/web_request/web_request_activitylog_cons tants.h"
25 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" 27 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h"
26 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" 28 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
27 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" 29 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h"
28 #include "chrome/browser/extensions/event_router.h" 30 #include "chrome/browser/extensions/event_router.h"
29 #include "chrome/browser/extensions/extension_info_map.h" 31 #include "chrome/browser/extensions/extension_info_map.h"
30 #include "chrome/browser/extensions/extension_prefs.h" 32 #include "chrome/browser/extensions/extension_prefs.h"
31 #include "chrome/browser/extensions/extension_renderer_state.h" 33 #include "chrome/browser/extensions/extension_renderer_state.h"
32 #include "chrome/browser/extensions/extension_service.h" 34 #include "chrome/browser/extensions/extension_service.h"
33 #include "chrome/browser/extensions/extension_system.h" 35 #include "chrome/browser/extensions/extension_system.h"
34 #include "chrome/browser/extensions/extension_warning_service.h" 36 #include "chrome/browser/extensions/extension_warning_service.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 using extensions::ExtensionWarning; 72 using extensions::ExtensionWarning;
71 using extensions::ExtensionWarningService; 73 using extensions::ExtensionWarningService;
72 using extensions::ExtensionWarningSet; 74 using extensions::ExtensionWarningSet;
73 using extensions::Feature; 75 using extensions::Feature;
74 using extensions::web_navigation_api_helpers::GetFrameId; 76 using extensions::web_navigation_api_helpers::GetFrameId;
75 77
76 namespace helpers = extension_web_request_api_helpers; 78 namespace helpers = extension_web_request_api_helpers;
77 namespace keys = extension_web_request_api_constants; 79 namespace keys = extension_web_request_api_constants;
78 namespace web_request = extensions::api::web_request; 80 namespace web_request = extensions::api::web_request;
79 namespace declarative_keys = extensions::declarative_webrequest_constants; 81 namespace declarative_keys = extensions::declarative_webrequest_constants;
82 namespace activitylog = extension_web_request_activitylog_constants;
80 83
81 namespace { 84 namespace {
82 85
83 // List of all the webRequest events. 86 // List of all the webRequest events.
84 const char* const kWebRequestEvents[] = { 87 const char* const kWebRequestEvents[] = {
85 keys::kOnBeforeRedirectEvent, 88 keys::kOnBeforeRedirectEvent,
86 keys::kOnBeforeRequestEvent, 89 keys::kOnBeforeRequestEvent,
87 keys::kOnBeforeSendHeadersEvent, 90 keys::kOnBeforeSendHeadersEvent,
88 keys::kOnCompletedEvent, 91 keys::kOnCompletedEvent,
89 keys::kOnErrorOccurredEvent, 92 keys::kOnErrorOccurredEvent,
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 return helpers::CalculateOnAuthRequiredDelta( 1416 return helpers::CalculateOnAuthRequiredDelta(
1414 response->extension_id, response->extension_install_time, 1417 response->extension_id, response->extension_install_time,
1415 response->cancel, &response->auth_credentials); 1418 response->cancel, &response->auth_credentials);
1416 default: 1419 default:
1417 NOTREACHED(); 1420 NOTREACHED();
1418 break; 1421 break;
1419 } 1422 }
1420 return NULL; 1423 return NULL;
1421 } 1424 }
1422 1425
1426 Value* SerializeResponseHeaders(const helpers::ResponseHeaders& headers) {
1427 scoped_ptr<ListValue> serialized_headers(new ListValue());
1428 for (helpers::ResponseHeaders::const_iterator i = headers.begin();
1429 i != headers.end(); ++i) {
1430 serialized_headers->Append(ToHeaderDictionary(i->first, i->second));
1431 }
1432 return serialized_headers.release();
1433 }
1434
1435 // Convert a RequestCookieModifications/ResponseCookieModifications object to a
1436 // ListValue which summarizes the changes made. This is templated since the
1437 // two types (request/response) are different but contain essentially the same
1438 // fields.
1439 template<typename CookieType>
1440 ListValue* SummarizeCookieModifications(
1441 const std::vector<linked_ptr<CookieType> >& modifications) {
1442 scoped_ptr<ListValue> cookie_modifications(new ListValue());
1443 for (typename std::vector<linked_ptr<CookieType> >::const_iterator i =
1444 modifications.begin();
1445 i != modifications.end(); ++i) {
1446 scoped_ptr<DictionaryValue> summary(new DictionaryValue());
1447 const CookieType& mod = *i->get();
1448 switch (mod.type) {
1449 case helpers::ADD:
1450 summary->SetString(activitylog::kCookieModificationTypeKey,
1451 activitylog::kCookieModificationAdd);
1452 break;
1453 case helpers::EDIT:
1454 summary->SetString(activitylog::kCookieModificationTypeKey,
1455 activitylog::kCookieModificationEdit);
1456 break;
1457 case helpers::REMOVE:
1458 summary->SetString(activitylog::kCookieModificationTypeKey,
1459 activitylog::kCookieModificationRemove);
1460 break;
1461 }
1462 if (mod.filter) {
1463 if (mod.filter->name)
1464 summary->SetString(activitylog::kCookieFilterNameKey,
1465 *mod.modification->name);
1466 if (mod.filter->domain)
1467 summary->SetString(activitylog::kCookieFilterDomainKey,
1468 *mod.modification->name);
1469 }
1470 if (mod.modification) {
1471 if (mod.modification->name)
1472 summary->SetString(activitylog::kCookieModDomainKey,
1473 *mod.modification->name);
1474 if (mod.modification->domain)
1475 summary->SetString(activitylog::kCookieModDomainKey,
1476 *mod.modification->name);
1477 }
1478 cookie_modifications->Append(summary.release());
1479 }
1480 return cookie_modifications.release();
1481 }
1482
1483 // Converts an EventResponseDelta object to a dictionary value suitable for the
1484 // activity log. The caller takes ownership of the returned DictionaryValue
1485 // object.
1486 DictionaryValue* SummarizeResponseDelta(
1487 const std::string& event_name,
1488 const helpers::EventResponseDelta& delta) {
1489 scoped_ptr<DictionaryValue> details(new DictionaryValue());
1490 if (delta.cancel) {
1491 details->SetBoolean(activitylog::kCancelKey, true);
1492 }
1493 if (!delta.new_url.is_empty()) {
1494 details->SetString(activitylog::kNewUrlKey, delta.new_url.spec());
1495 }
1496
1497 scoped_ptr<ListValue> modified_headers(new ListValue());
1498 net::HttpRequestHeaders::Iterator iter(delta.modified_request_headers);
1499 while (iter.GetNext()) {
1500 modified_headers->Append(ToHeaderDictionary(iter.name(), iter.value()));
1501 }
1502 if (!modified_headers->empty()) {
1503 details->Set(activitylog::kModifiedRequestHeadersKey,
1504 modified_headers.release());
1505 }
1506
1507 scoped_ptr<ListValue> deleted_headers(new ListValue());
1508 deleted_headers->AppendStrings(delta.deleted_request_headers);
1509 if (!deleted_headers->empty()) {
1510 details->Set(activitylog::kDeletedRequestHeadersKey,
1511 deleted_headers.release());
1512 }
1513
1514 if (!delta.added_response_headers.empty()) {
1515 details->Set(activitylog::kAddedRequestHeadersKey,
1516 SerializeResponseHeaders(delta.added_response_headers));
1517 }
1518 if (!delta.deleted_response_headers.empty()) {
1519 details->Set(activitylog::kDeletedResponseHeadersKey,
1520 SerializeResponseHeaders(delta.deleted_response_headers));
1521 }
1522 if (delta.auth_credentials) {
1523 details->SetString(activitylog::kAuthCredentialsKey,
1524 UTF16ToUTF8(delta.auth_credentials->username()) + ":*");
1525 }
1526
1527 if (!delta.response_cookie_modifications.empty()) {
1528 details->Set(
1529 activitylog::kResponseCookieModificationsKey,
1530 SummarizeCookieModifications(delta.response_cookie_modifications));
1531 }
1532
1533 return details.release();
1534 }
1535
1536 void LogExtensionActivity(Profile* profile,
1537 const std::string& extension_id,
1538 const GURL& url,
1539 const std::string& api_call,
1540 DictionaryValue* details) {
1541 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
1542 BrowserThread::PostTask(BrowserThread::UI,
1543 FROM_HERE,
1544 base::Bind(&LogExtensionActivity,
1545 profile,
1546 extension_id,
1547 url,
1548 api_call,
1549 details));
1550 } else {
1551 // An ExtensionService might not be running during unit tests, or an
1552 // extension might have been unloadd by the time we get to logging it. In
1553 // those cases log a warning.
1554 ExtensionService* extension_service =
1555 extensions::ExtensionSystem::Get(profile)->extension_service();
1556 if (!extension_service) {
1557 LOG(WARNING) << "ExtensionService does not seem to be available "
1558 << "(this may be normal for unit tests)";
1559 } else {
1560 const Extension* extension =
1561 extension_service->extensions()->GetByID(extension_id);
1562 if (!extension) {
1563 LOG(WARNING) << "Extension " << extension_id << " not found!";
1564 } else {
1565 extensions::ActivityLog::GetInstance(profile)->LogWebRequestAction(
1566 extension,
1567 url,
1568 api_call,
1569 scoped_ptr<DictionaryValue>(details),
1570 "");
1571 }
1572 }
1573 }
1574 }
1575
1423 } // namespace 1576 } // namespace
1424 1577
1425 void ExtensionWebRequestEventRouter::DecrementBlockCount( 1578 void ExtensionWebRequestEventRouter::DecrementBlockCount(
1426 void* profile, 1579 void* profile,
1427 const std::string& extension_id, 1580 const std::string& extension_id,
1428 const std::string& event_name, 1581 const std::string& event_name,
1429 uint64 request_id, 1582 uint64 request_id,
1430 EventResponse* response) { 1583 EventResponse* response) {
1431 scoped_ptr<EventResponse> response_scoped(response); 1584 scoped_ptr<EventResponse> response_scoped(response);
1432 1585
1433 // It's possible that this request was deleted, or cancelled by a previous 1586 // It's possible that this request was deleted, or cancelled by a previous
1434 // event handler. If so, ignore this response. 1587 // event handler. If so, ignore this response.
1435 if (blocked_requests_.find(request_id) == blocked_requests_.end()) 1588 if (blocked_requests_.find(request_id) == blocked_requests_.end())
1436 return; 1589 return;
1437 1590
1438 BlockedRequest& blocked_request = blocked_requests_[request_id]; 1591 BlockedRequest& blocked_request = blocked_requests_[request_id];
1439 int num_handlers_blocking = --blocked_request.num_handlers_blocking; 1592 int num_handlers_blocking = --blocked_request.num_handlers_blocking;
1440 CHECK_GE(num_handlers_blocking, 0); 1593 CHECK_GE(num_handlers_blocking, 0);
1441 1594
1442 if (response) { 1595 if (response) {
1596 helpers::EventResponseDelta* delta =
1597 CalculateDelta(&blocked_request, response);
1598
1599 if (extensions::ActivityLog::IsLogEnabled()) {
1600 LogExtensionActivity(static_cast<Profile*>(profile),
1601 extension_id,
1602 blocked_request.request->url(),
1603 event_name,
1604 SummarizeResponseDelta(event_name, *delta));
1605 }
1606
1443 blocked_request.response_deltas.push_back( 1607 blocked_request.response_deltas.push_back(
1444 linked_ptr<helpers::EventResponseDelta>( 1608 linked_ptr<helpers::EventResponseDelta>(delta));
1445 CalculateDelta(&blocked_request, response)));
1446 } 1609 }
1447 1610
1448 base::TimeDelta block_time = 1611 base::TimeDelta block_time =
1449 base::Time::Now() - blocked_request.blocking_time; 1612 base::Time::Now() - blocked_request.blocking_time;
1450 if (!extension_id.empty()) { 1613 if (!extension_id.empty()) {
1451 request_time_tracker_->IncrementExtensionBlockTime( 1614 request_time_tracker_->IncrementExtensionBlockTime(
1452 extension_id, request_id, block_time); 1615 extension_id, request_id, block_time);
1453 } else { 1616 } else {
1454 // |extension_id| is empty for requests blocked on startup waiting for the 1617 // |extension_id| is empty for requests blocked on startup waiting for the
1455 // declarative rules to be read from disk. 1618 // declarative rules to be read from disk.
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
2033 } else if ((*it)->name().find("AdBlock") != std::string::npos) { 2196 } else if ((*it)->name().find("AdBlock") != std::string::npos) {
2034 adblock = true; 2197 adblock = true;
2035 } else { 2198 } else {
2036 other = true; 2199 other = true;
2037 } 2200 }
2038 } 2201 }
2039 } 2202 }
2040 2203
2041 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); 2204 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other));
2042 } 2205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698