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); | |
mvrable
2013/04/11 21:41:26
I'm wondering whether I should define some constan
felt
2013/04/11 21:43:28
You could consider adding a helper method to one o
mvrable
2013/04/12 18:50:49
I ended up creating a new file in the web_request
| |
1483 } | |
1484 if (!delta.new_url.is_empty()) { | |
1485 details->SetString("new_url", delta.new_url.spec()); | |
1486 } | |
1487 | |
1488 scoped_ptr<ListValue> modified_headers(new ListValue()); | |
1489 net::HttpRequestHeaders::Iterator iter(delta.modified_request_headers); | |
1490 while (iter.GetNext()) { | |
1491 modified_headers->Append(ToHeaderDictionary(iter.name(), iter.value())); | |
1492 } | |
1493 if (!modified_headers->empty()) { | |
1494 details->Set("modified_request_headers", modified_headers.release()); | |
1495 } | |
1496 | |
1497 scoped_ptr<ListValue> deleted_headers(new ListValue()); | |
1498 deleted_headers->AppendStrings(delta.deleted_request_headers); | |
1499 if (!deleted_headers->empty()) { | |
1500 details->Set("deleted_request_headers", deleted_headers.release()); | |
1501 } | |
1502 | |
1503 if (!delta.added_response_headers.empty()) { | |
1504 details->Set("added_response_headers", | |
1505 SerializeResponseHeaders(delta.added_response_headers)); | |
1506 } | |
1507 if (!delta.deleted_response_headers.empty()) { | |
1508 details->Set("deleted_response_headers", | |
1509 SerializeResponseHeaders(delta.deleted_response_headers)); | |
1510 } | |
1511 if (delta.auth_credentials) { | |
1512 details->SetString("auth_credentials", | |
1513 UTF16ToUTF8(delta.auth_credentials->username()) + ":*"); | |
1514 } | |
1515 | |
1516 if (!delta.response_cookie_modifications.empty()) { | |
1517 details->Set( | |
1518 "response_cookie_modifications", | |
1519 SummarizeCookieModifications(delta.response_cookie_modifications)); | |
1520 } | |
1521 | |
1522 return details.release(); | |
1523 } | |
1524 | |
1525 void LogExtensionActivity(Profile* profile, | |
1526 const std::string& extension_id, | |
1527 const GURL& url, | |
1528 const std::string& api_call, | |
1529 DictionaryValue* details) { | |
1530 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
1531 BrowserThread::PostTask(BrowserThread::UI, | |
1532 FROM_HERE, | |
1533 base::Bind(&LogExtensionActivity, | |
1534 profile, | |
1535 extension_id, | |
1536 url, | |
1537 api_call, | |
1538 details)); | |
1539 } else { | |
1540 // An ExtensionService might not be running during unit tests, or an | |
1541 // extension might have been unloadd by the time we get to logging it. In | |
1542 // those cases log a warning. | |
1543 ExtensionService* extension_service = | |
1544 extensions::ExtensionSystem::Get(profile)->extension_service(); | |
1545 if (!extension_service) { | |
1546 LOG(WARNING) << "ExtensionService does not seem to be available " | |
1547 << "(this may be normal for unit tests)"; | |
1548 } else { | |
1549 const Extension* extension = | |
1550 extension_service->extensions()->GetByID(extension_id); | |
1551 if (!extension) { | |
1552 LOG(WARNING) << "Extension " << extension_id << " not found!"; | |
1553 } else { | |
1554 extensions::ActivityLog::GetInstance(profile)->LogWebRequestAction( | |
1555 extension, | |
1556 url, | |
1557 api_call, | |
1558 scoped_ptr<DictionaryValue>(details), | |
1559 ""); | |
1560 } | |
1561 } | |
1562 } | |
1563 } | |
1564 | |
1423 } // namespace | 1565 } // namespace |
1424 | 1566 |
1425 void ExtensionWebRequestEventRouter::DecrementBlockCount( | 1567 void ExtensionWebRequestEventRouter::DecrementBlockCount( |
1426 void* profile, | 1568 void* profile, |
1427 const std::string& extension_id, | 1569 const std::string& extension_id, |
1428 const std::string& event_name, | 1570 const std::string& event_name, |
1429 uint64 request_id, | 1571 uint64 request_id, |
1430 EventResponse* response) { | 1572 EventResponse* response) { |
1431 scoped_ptr<EventResponse> response_scoped(response); | 1573 scoped_ptr<EventResponse> response_scoped(response); |
1432 | 1574 |
1433 // It's possible that this request was deleted, or cancelled by a previous | 1575 // It's possible that this request was deleted, or cancelled by a previous |
1434 // event handler. If so, ignore this response. | 1576 // event handler. If so, ignore this response. |
1435 if (blocked_requests_.find(request_id) == blocked_requests_.end()) | 1577 if (blocked_requests_.find(request_id) == blocked_requests_.end()) |
1436 return; | 1578 return; |
1437 | 1579 |
1438 BlockedRequest& blocked_request = blocked_requests_[request_id]; | 1580 BlockedRequest& blocked_request = blocked_requests_[request_id]; |
1439 int num_handlers_blocking = --blocked_request.num_handlers_blocking; | 1581 int num_handlers_blocking = --blocked_request.num_handlers_blocking; |
1440 CHECK_GE(num_handlers_blocking, 0); | 1582 CHECK_GE(num_handlers_blocking, 0); |
1441 | 1583 |
1442 if (response) { | 1584 if (response) { |
1585 helpers::EventResponseDelta* delta = | |
1586 CalculateDelta(&blocked_request, response); | |
1587 | |
1588 LogExtensionActivity(static_cast<Profile*>(profile), | |
1589 extension_id, | |
1590 blocked_request.request->url(), | |
1591 event_name, | |
1592 SummarizeResponseDelta(event_name, *delta)); | |
Matt Perry
2013/04/12 00:53:43
This looks somewhat expensive. Ideally we wouldn't
mvrable
2013/04/12 18:50:49
Done.
| |
1593 | |
1443 blocked_request.response_deltas.push_back( | 1594 blocked_request.response_deltas.push_back( |
1444 linked_ptr<helpers::EventResponseDelta>( | 1595 linked_ptr<helpers::EventResponseDelta>(delta)); |
1445 CalculateDelta(&blocked_request, response))); | |
1446 } | 1596 } |
1447 | 1597 |
1448 base::TimeDelta block_time = | 1598 base::TimeDelta block_time = |
1449 base::Time::Now() - blocked_request.blocking_time; | 1599 base::Time::Now() - blocked_request.blocking_time; |
1450 if (!extension_id.empty()) { | 1600 if (!extension_id.empty()) { |
1451 request_time_tracker_->IncrementExtensionBlockTime( | 1601 request_time_tracker_->IncrementExtensionBlockTime( |
1452 extension_id, request_id, block_time); | 1602 extension_id, request_id, block_time); |
1453 } else { | 1603 } else { |
1454 // |extension_id| is empty for requests blocked on startup waiting for the | 1604 // |extension_id| is empty for requests blocked on startup waiting for the |
1455 // declarative rules to be read from disk. | 1605 // 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) { | 2183 } else if ((*it)->name().find("AdBlock") != std::string::npos) { |
2034 adblock = true; | 2184 adblock = true; |
2035 } else { | 2185 } else { |
2036 other = true; | 2186 other = true; |
2037 } | 2187 } |
2038 } | 2188 } |
2039 } | 2189 } |
2040 | 2190 |
2041 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); | 2191 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); |
2042 } | 2192 } |
OLD | NEW |