| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "content/browser/browsing_data/clear_site_data_throttle.h" | 5 #include "content/browser/browsing_data/clear_site_data_throttle.h" |
| 6 | 6 |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #include "url/origin.h" | 30 #include "url/origin.h" |
| 31 | 31 |
| 32 namespace content { | 32 namespace content { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 const char kNameForLogging[] = "ClearSiteDataThrottle"; | 36 const char kNameForLogging[] = "ClearSiteDataThrottle"; |
| 37 | 37 |
| 38 const char kClearSiteDataHeader[] = "Clear-Site-Data"; | 38 const char kClearSiteDataHeader[] = "Clear-Site-Data"; |
| 39 | 39 |
| 40 const char kTypesKey[] = "types"; |
| 41 |
| 40 // Datatypes. | 42 // Datatypes. |
| 41 const char kDatatypeCookies[] = "cookies"; | 43 const char kDatatypeCookies[] = "cookies"; |
| 42 const char kDatatypeStorage[] = "storage"; | 44 const char kDatatypeStorage[] = "storage"; |
| 43 const char kDatatypeCache[] = "cache"; | 45 const char kDatatypeCache[] = "cache"; |
| 44 | 46 |
| 45 // Pretty-printed log output. | 47 // Pretty-printed log output. |
| 46 const char kConsoleMessageTemplate[] = "Clear-Site-Data header on '%s': %s"; | 48 const char kConsoleMessageTemplate[] = "Clear-Site-Data header on '%s': %s"; |
| 47 const char kConsoleMessageCleared[] = "Cleared data types: %s."; | 49 const char kConsoleMessageCleared[] = "Cleared data types: %s."; |
| 48 const char kConsoleMessageDatatypeSeparator[] = ", "; | 50 const char kConsoleMessageDatatypeSeparator[] = ", "; |
| 49 | 51 |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 bool* clear_storage, | 439 bool* clear_storage, |
| 438 bool* clear_cache, | 440 bool* clear_cache, |
| 439 ConsoleMessagesDelegate* delegate, | 441 ConsoleMessagesDelegate* delegate, |
| 440 const GURL& current_url) { | 442 const GURL& current_url) { |
| 441 if (!base::IsStringASCII(header)) { | 443 if (!base::IsStringASCII(header)) { |
| 442 delegate->AddMessage(current_url, "Must only contain ASCII characters.", | 444 delegate->AddMessage(current_url, "Must only contain ASCII characters.", |
| 443 CONSOLE_MESSAGE_LEVEL_ERROR); | 445 CONSOLE_MESSAGE_LEVEL_ERROR); |
| 444 return false; | 446 return false; |
| 445 } | 447 } |
| 446 | 448 |
| 447 // Wrap |header| in `[` and `]`, then process it as a JSON array: | 449 std::unique_ptr<base::Value> parsed_header = base::JSONReader::Read(header); |
| 448 // | |
| 449 // TODO(mkwst): Drop the JSONReader bits in favor of a simpler parser. | |
| 450 std::string wrapped = "[" + header + "]"; | |
| 451 std::unique_ptr<base::Value> parsed_header = base::JSONReader::Read(wrapped); | |
| 452 | 450 |
| 453 if (!parsed_header) { | 451 if (!parsed_header) { |
| 454 delegate->AddMessage(current_url, | 452 delegate->AddMessage(current_url, "Expected valid JSON.", |
| 455 "The header's value does not parse as valid JSON.", | |
| 456 CONSOLE_MESSAGE_LEVEL_ERROR); | 453 CONSOLE_MESSAGE_LEVEL_ERROR); |
| 457 return false; | 454 return false; |
| 458 } | 455 } |
| 459 | 456 |
| 460 // Expecting a header in the format `"value1", "value2", "value3"`: | 457 const base::DictionaryValue* dictionary = nullptr; |
| 461 const base::ListValue* types = nullptr; | 458 const base::ListValue* types = nullptr; |
| 462 DCHECK(parsed_header->GetAsList(&types)); | 459 if (!parsed_header->GetAsDictionary(&dictionary) || |
| 460 !dictionary->GetListWithoutPathExpansion(kTypesKey, &types)) { |
| 461 delegate->AddMessage(current_url, |
| 462 "Expected a JSON dictionary with a 'types' field.", |
| 463 CONSOLE_MESSAGE_LEVEL_ERROR); |
| 464 return false; |
| 465 } |
| 466 |
| 463 DCHECK(types); | 467 DCHECK(types); |
| 464 | 468 |
| 465 *clear_cookies = false; | 469 *clear_cookies = false; |
| 466 *clear_storage = false; | 470 *clear_storage = false; |
| 467 *clear_cache = false; | 471 *clear_cache = false; |
| 468 | 472 |
| 469 std::string type_names; | 473 std::string type_names; |
| 470 for (const base::Value& value : *types) { | 474 for (const base::Value& value : *types) { |
| 471 std::string type; | 475 std::string type; |
| 472 if (value.is_string() && value.GetAsString(&type)) { | 476 value.GetAsString(&type); |
| 473 bool* data_type = nullptr; | |
| 474 | 477 |
| 475 if (type == kDatatypeCookies) { | 478 bool* data_type = nullptr; |
| 476 data_type = clear_cookies; | |
| 477 } else if (type == kDatatypeStorage) { | |
| 478 data_type = clear_storage; | |
| 479 } else if (type == kDatatypeCache) { | |
| 480 data_type = clear_cache; | |
| 481 } else { | |
| 482 delegate->AddMessage( | |
| 483 current_url, | |
| 484 base::StringPrintf("Unrecognized type: \"%s\".", type.c_str()), | |
| 485 CONSOLE_MESSAGE_LEVEL_ERROR); | |
| 486 continue; | |
| 487 } | |
| 488 | 479 |
| 489 DCHECK(data_type); | 480 if (type == kDatatypeCookies) { |
| 490 | 481 data_type = clear_cookies; |
| 491 // Each data type should only be processed once. | 482 } else if (type == kDatatypeStorage) { |
| 492 if (*data_type) | 483 data_type = clear_storage; |
| 493 continue; | 484 } else if (type == kDatatypeCache) { |
| 494 | 485 data_type = clear_cache; |
| 495 *data_type = true; | |
| 496 if (!type_names.empty()) | |
| 497 type_names += kConsoleMessageDatatypeSeparator; | |
| 498 type_names += type; | |
| 499 } else { | 486 } else { |
| 500 std::string serialized_type; | 487 std::string serialized_type; |
| 501 JSONStringValueSerializer serializer(&serialized_type); | 488 JSONStringValueSerializer serializer(&serialized_type); |
| 502 serializer.Serialize(value); | 489 serializer.Serialize(value); |
| 503 delegate->AddMessage( | 490 delegate->AddMessage( |
| 504 current_url, | 491 current_url, |
| 505 base::StringPrintf("Unrecognized type: %s.", serialized_type.c_str()), | 492 base::StringPrintf("Unrecognized type: %s.", serialized_type.c_str()), |
| 506 CONSOLE_MESSAGE_LEVEL_ERROR); | 493 CONSOLE_MESSAGE_LEVEL_ERROR); |
| 494 continue; |
| 507 } | 495 } |
| 496 |
| 497 DCHECK(data_type); |
| 498 |
| 499 // Each data type should only be processed once. |
| 500 if (*data_type) |
| 501 continue; |
| 502 |
| 503 *data_type = true; |
| 504 if (!type_names.empty()) |
| 505 type_names += kConsoleMessageDatatypeSeparator; |
| 506 type_names += type; |
| 508 } | 507 } |
| 509 | 508 |
| 510 if (!*clear_cookies && !*clear_storage && !*clear_cache) { | 509 if (!*clear_cookies && !*clear_storage && !*clear_cache) { |
| 511 delegate->AddMessage(current_url, "No recognized types specified.", | 510 delegate->AddMessage(current_url, |
| 511 "No recognized types specified in the 'types' field.", |
| 512 CONSOLE_MESSAGE_LEVEL_ERROR); | 512 CONSOLE_MESSAGE_LEVEL_ERROR); |
| 513 return false; | 513 return false; |
| 514 } | 514 } |
| 515 | 515 |
| 516 // Pretty-print which types are to be cleared. | 516 // Pretty-print which types are to be cleared. |
| 517 delegate->AddMessage( | 517 delegate->AddMessage( |
| 518 current_url, | 518 current_url, |
| 519 base::StringPrintf(kConsoleMessageCleared, type_names.c_str()), | 519 base::StringPrintf(kConsoleMessageCleared, type_names.c_str()), |
| 520 CONSOLE_MESSAGE_LEVEL_INFO); | 520 CONSOLE_MESSAGE_LEVEL_INFO); |
| 521 | 521 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 Resume(); | 553 Resume(); |
| 554 } | 554 } |
| 555 | 555 |
| 556 void ClearSiteDataThrottle::OutputConsoleMessages() { | 556 void ClearSiteDataThrottle::OutputConsoleMessages() { |
| 557 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); | 557 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); |
| 558 if (info) | 558 if (info) |
| 559 delegate_->OutputMessages(info->GetWebContentsGetterForRequest()); | 559 delegate_->OutputMessages(info->GetWebContentsGetterForRequest()); |
| 560 } | 560 } |
| 561 | 561 |
| 562 } // namespace content | 562 } // namespace content |
| OLD | NEW |