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" |
25 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" | 26 #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" | 27 #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" | 28 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" |
28 #include "chrome/browser/extensions/event_router.h" | 29 #include "chrome/browser/extensions/event_router.h" |
29 #include "chrome/browser/extensions/extension_info_map.h" | 30 #include "chrome/browser/extensions/extension_info_map.h" |
(...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1413 return helpers::CalculateOnAuthRequiredDelta( | 1414 return helpers::CalculateOnAuthRequiredDelta( |
1414 response->extension_id, response->extension_install_time, | 1415 response->extension_id, response->extension_install_time, |
1415 response->cancel, &response->auth_credentials); | 1416 response->cancel, &response->auth_credentials); |
1416 default: | 1417 default: |
1417 NOTREACHED(); | 1418 NOTREACHED(); |
1418 break; | 1419 break; |
1419 } | 1420 } |
1420 return NULL; | 1421 return NULL; |
1421 } | 1422 } |
1422 | 1423 |
1424 Value* SerializeResponseHeaders(const helpers::ResponseHeaders& headers) { | |
1425 scoped_ptr<ListValue> serialized_headers(new ListValue()); | |
1426 for (helpers::ResponseHeaders::const_iterator i = headers.begin(); | |
1427 i != headers.end(); ++i) { | |
1428 serialized_headers->Append(ToHeaderDictionary(i->first, i->second)); | |
1429 } | |
1430 return serialized_headers.release(); | |
1431 } | |
1432 | |
1433 // Convert a RequestCookieModifications/ResponseCookieModifications object to a | |
1434 // ListValue which summarizes the changes made. This is templated since the | |
1435 // two types (request/response) are different but contain essentially the same | |
1436 // fields. | |
1437 template<typename CookieType> | |
1438 ListValue* SummarizeCookieModifications( | |
1439 const std::vector<linked_ptr<CookieType> >& modifications) { | |
1440 scoped_ptr<ListValue> cookie_modifications(new ListValue()); | |
1441 for (typename std::vector<linked_ptr<CookieType> >::const_iterator i = | |
1442 modifications.begin(); | |
1443 i != modifications.end(); ++i) { | |
1444 scoped_ptr<DictionaryValue> summary(new DictionaryValue()); | |
1445 const CookieType& mod = *i->get(); | |
1446 switch (mod.type) { | |
1447 case helpers::ADD: | |
1448 summary->SetString("type", "ADD"); | |
1449 break; | |
1450 case helpers::EDIT: | |
1451 summary->SetString("type", "EDIT"); | |
1452 break; | |
1453 case helpers::REMOVE: | |
1454 summary->SetString("type", "REMOVE"); | |
1455 break; | |
1456 } | |
1457 if (mod.filter) { | |
1458 if (mod.filter->name) | |
1459 summary->SetString("filter_name", *mod.modification->name); | |
1460 if (mod.filter->domain) | |
1461 summary->SetString("filter_domain", *mod.modification->name); | |
1462 } | |
1463 if (mod.modification) { | |
1464 if (mod.modification->name) | |
1465 summary->SetString("mod_name", *mod.modification->name); | |
1466 if (mod.modification->domain) | |
1467 summary->SetString("mod_domain", *mod.modification->name); | |
1468 } | |
1469 cookie_modifications->Append(summary.release()); | |
1470 } | |
1471 return cookie_modifications.release(); | |
1472 } | |
1473 | |
1474 // Converts an EventResponseDelta object to a dictionary value suitable for the | |
1475 // activity log. The caller takes ownership of the returned DictionaryValue | |
1476 // object. | |
1477 DictionaryValue* SummarizeResponseDelta( | |
1478 const std::string& event_name, | |
1479 const helpers::EventResponseDelta& delta) { | |
1480 scoped_ptr<DictionaryValue> details(new DictionaryValue()); | |
1481 if (delta.cancel) { | |
1482 details->SetBoolean("cancel", true); | |
1483 } | |
1484 if (!delta.new_url.is_empty()) { | |
1485 details->SetString("new_url", delta.new_url.spec()); | |
1486 } | |
1487 | |
1488 { | |
felt
2013/04/11 21:13:37
is this meant to be an if block?
mvrable
2013/04/11 21:41:26
No, it was keeping local variables scoped more tig
| |
1489 scoped_ptr<ListValue> modified_headers(new ListValue()); | |
1490 net::HttpRequestHeaders::Iterator iter(delta.modified_request_headers); | |
1491 while (iter.GetNext()) { | |
1492 modified_headers->Append(ToHeaderDictionary(iter.name(), iter.value())); | |
1493 } | |
1494 if (!modified_headers->empty()) { | |
1495 details->Set("modified_request_headers", modified_headers.release()); | |
1496 } | |
1497 } | |
1498 | |
1499 { | |
1500 scoped_ptr<ListValue> deleted_headers(new ListValue()); | |
1501 deleted_headers->AppendStrings(delta.deleted_request_headers); | |
1502 if (!deleted_headers->empty()) { | |
1503 details->Set("deleted_request_headers", deleted_headers.release()); | |
1504 } | |
1505 } | |
1506 | |
1507 if (!delta.added_response_headers.empty()) { | |
1508 details->Set("added_response_headers", | |
1509 SerializeResponseHeaders(delta.added_response_headers)); | |
1510 } | |
1511 if (!delta.deleted_response_headers.empty()) { | |
1512 details->Set("deleted_response_headers", | |
1513 SerializeResponseHeaders(delta.deleted_response_headers)); | |
1514 } | |
1515 if (delta.auth_credentials) { | |
1516 details->SetString("auth_credentials", | |
1517 UTF16ToUTF8(delta.auth_credentials->username()) + ":*"); | |
1518 } | |
1519 | |
1520 if (!delta.response_cookie_modifications.empty()) { | |
1521 details->Set( | |
1522 "response_cookie_modifications", | |
1523 SummarizeCookieModifications(delta.response_cookie_modifications)); | |
1524 } | |
1525 | |
1526 return details.release(); | |
1527 } | |
1528 | |
1529 void LogExtensionActivity(Profile* profile, | |
1530 const std::string& extension_id, | |
1531 const GURL& url, | |
1532 const std::string& api_call, | |
1533 DictionaryValue* details) { | |
1534 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
1535 BrowserThread::PostTask(BrowserThread::UI, | |
1536 FROM_HERE, | |
1537 base::Bind(&LogExtensionActivity, | |
1538 profile, | |
1539 extension_id, | |
1540 url, | |
1541 api_call, | |
1542 details)); | |
1543 } else { | |
1544 // An ExtensionService might not be running during unit tests, or an | |
1545 // extension might have been unloadd by the time we get to logging it. In | |
1546 // those cases log a warning. | |
1547 ExtensionService* extension_service = | |
1548 extensions::ExtensionSystem::Get(profile)->extension_service(); | |
1549 if (!extension_service) { | |
1550 LOG(WARNING) << "ExtensionService does not seem to be available " | |
1551 << "(this may be normal for unit tests)"; | |
1552 } else { | |
1553 const Extension* extension = | |
1554 extension_service->extensions()->GetByID(extension_id); | |
1555 if (!extension) { | |
1556 LOG(WARNING) << "Extension " << extension_id << " not found!"; | |
1557 } else { | |
1558 extensions::ActivityLog::GetInstance(profile)->LogWebRequestAction( | |
1559 extension, | |
1560 url, | |
1561 api_call, | |
1562 scoped_ptr<DictionaryValue>(details), | |
1563 ""); | |
1564 } | |
1565 } | |
1566 } | |
1567 } | |
1568 | |
1423 } // namespace | 1569 } // namespace |
1424 | 1570 |
1425 void ExtensionWebRequestEventRouter::DecrementBlockCount( | 1571 void ExtensionWebRequestEventRouter::DecrementBlockCount( |
1426 void* profile, | 1572 void* profile, |
1427 const std::string& extension_id, | 1573 const std::string& extension_id, |
1428 const std::string& event_name, | 1574 const std::string& event_name, |
1429 uint64 request_id, | 1575 uint64 request_id, |
1430 EventResponse* response) { | 1576 EventResponse* response) { |
1431 scoped_ptr<EventResponse> response_scoped(response); | 1577 scoped_ptr<EventResponse> response_scoped(response); |
1432 | 1578 |
1433 // It's possible that this request was deleted, or cancelled by a previous | 1579 // It's possible that this request was deleted, or cancelled by a previous |
1434 // event handler. If so, ignore this response. | 1580 // event handler. If so, ignore this response. |
1435 if (blocked_requests_.find(request_id) == blocked_requests_.end()) | 1581 if (blocked_requests_.find(request_id) == blocked_requests_.end()) |
1436 return; | 1582 return; |
1437 | 1583 |
1438 BlockedRequest& blocked_request = blocked_requests_[request_id]; | 1584 BlockedRequest& blocked_request = blocked_requests_[request_id]; |
1439 int num_handlers_blocking = --blocked_request.num_handlers_blocking; | 1585 int num_handlers_blocking = --blocked_request.num_handlers_blocking; |
1440 CHECK_GE(num_handlers_blocking, 0); | 1586 CHECK_GE(num_handlers_blocking, 0); |
1441 | 1587 |
1442 if (response) { | 1588 if (response) { |
1589 helpers::EventResponseDelta* delta = | |
1590 CalculateDelta(&blocked_request, response); | |
1591 | |
1592 LogExtensionActivity(static_cast<Profile*>(profile), | |
1593 extension_id, | |
1594 blocked_request.request->url(), | |
1595 event_name, | |
1596 SummarizeResponseDelta(event_name, *delta)); | |
1597 | |
1443 blocked_request.response_deltas.push_back( | 1598 blocked_request.response_deltas.push_back( |
1444 linked_ptr<helpers::EventResponseDelta>( | 1599 linked_ptr<helpers::EventResponseDelta>(delta)); |
1445 CalculateDelta(&blocked_request, response))); | |
1446 } | 1600 } |
1447 | 1601 |
1448 base::TimeDelta block_time = | 1602 base::TimeDelta block_time = |
1449 base::Time::Now() - blocked_request.blocking_time; | 1603 base::Time::Now() - blocked_request.blocking_time; |
1450 if (!extension_id.empty()) { | 1604 if (!extension_id.empty()) { |
1451 request_time_tracker_->IncrementExtensionBlockTime( | 1605 request_time_tracker_->IncrementExtensionBlockTime( |
1452 extension_id, request_id, block_time); | 1606 extension_id, request_id, block_time); |
1453 } else { | 1607 } else { |
1454 // |extension_id| is empty for requests blocked on startup waiting for the | 1608 // |extension_id| is empty for requests blocked on startup waiting for the |
1455 // declarative rules to be read from disk. | 1609 // 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) { | 2187 } else if ((*it)->name().find("AdBlock") != std::string::npos) { |
2034 adblock = true; | 2188 adblock = true; |
2035 } else { | 2189 } else { |
2036 other = true; | 2190 other = true; |
2037 } | 2191 } |
2038 } | 2192 } |
2039 } | 2193 } |
2040 | 2194 |
2041 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); | 2195 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); |
2042 } | 2196 } |
OLD | NEW |