Chromium Code Reviews| 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 |