OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |