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_helpers.h" | 5 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/string_number_conversions.h" | |
8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
9 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
10 #include "base/values.h" | 11 #include "base/values.h" |
11 #include "chrome/browser/extensions/api/web_request/web_request_api.h" | 12 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
12 #include "chrome/common/url_constants.h" | 13 #include "chrome/common/url_constants.h" |
13 #include "net/base/net_log.h" | 14 #include "net/base/net_log.h" |
15 #include "net/cookies/parsed_cookie.h" | |
14 #include "net/http/http_util.h" | 16 #include "net/http/http_util.h" |
15 #include "net/url_request/url_request.h" | 17 #include "net/url_request/url_request.h" |
16 | 18 |
17 namespace extension_web_request_api_helpers { | 19 namespace extension_web_request_api_helpers { |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
23 // A ParsedRequestCookie consists of the key and value of the cookie. | |
24 typedef std::pair<base::StringPiece, base::StringPiece> ParsedRequestCookie; | |
25 typedef std::vector<ParsedRequestCookie> ParsedRequestCookies; | |
26 typedef std::vector<linked_ptr<net::ParsedCookie> > ParsedResponseCookies; | |
27 | |
21 static const char* kResourceTypeStrings[] = { | 28 static const char* kResourceTypeStrings[] = { |
22 "main_frame", | 29 "main_frame", |
23 "sub_frame", | 30 "sub_frame", |
24 "stylesheet", | 31 "stylesheet", |
25 "script", | 32 "script", |
26 "image", | 33 "image", |
27 "object", | 34 "object", |
28 "xmlhttprequest", | 35 "xmlhttprequest", |
29 "other", | 36 "other", |
30 "other", | 37 "other", |
(...skipping 15 matching lines...) Expand all Loading... | |
46 // entry is no longer required, this should be removed. | 53 // entry is no longer required, this should be removed. |
47 ResourceType::LAST_TYPE, | 54 ResourceType::LAST_TYPE, |
48 }; | 55 }; |
49 | 56 |
50 COMPILE_ASSERT( | 57 COMPILE_ASSERT( |
51 arraysize(kResourceTypeStrings) == arraysize(kResourceTypeValues), | 58 arraysize(kResourceTypeStrings) == arraysize(kResourceTypeValues), |
52 keep_resource_types_in_sync); | 59 keep_resource_types_in_sync); |
53 | 60 |
54 } // namespace | 61 } // namespace |
55 | 62 |
63 RequestCookie::RequestCookie() {} | |
64 RequestCookie::~RequestCookie() {} | |
65 | |
66 ResponseCookie::ResponseCookie() {} | |
67 ResponseCookie::~ResponseCookie() {} | |
68 | |
69 RequestCookieModification::RequestCookieModification() {} | |
70 RequestCookieModification::~RequestCookieModification() {} | |
71 | |
72 ResponseCookieModification::ResponseCookieModification() : type(ADD) {} | |
73 ResponseCookieModification::~ResponseCookieModification() {} | |
56 | 74 |
57 EventResponseDelta::EventResponseDelta( | 75 EventResponseDelta::EventResponseDelta( |
58 const std::string& extension_id, const base::Time& extension_install_time) | 76 const std::string& extension_id, const base::Time& extension_install_time) |
59 : extension_id(extension_id), | 77 : extension_id(extension_id), |
60 extension_install_time(extension_install_time), | 78 extension_install_time(extension_install_time), |
61 cancel(false) { | 79 cancel(false) { |
62 } | 80 } |
63 | 81 |
64 EventResponseDelta::~EventResponseDelta() { | 82 EventResponseDelta::~EventResponseDelta() { |
65 } | 83 } |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 // special case as they represent a way of cancelling a request. | 333 // special case as they represent a way of cancelling a request. |
316 if (MergeOnBeforeRequestResponsesHelper( | 334 if (MergeOnBeforeRequestResponsesHelper( |
317 deltas, new_url, conflicting_extensions, net_log, true)) { | 335 deltas, new_url, conflicting_extensions, net_log, true)) { |
318 // If any extension cancelled a request by redirecting to a data:// URL or | 336 // If any extension cancelled a request by redirecting to a data:// URL or |
319 // about:blank, we don't consider the other redirects. | 337 // about:blank, we don't consider the other redirects. |
320 return; | 338 return; |
321 } | 339 } |
322 | 340 |
323 // Handle all other redirects. | 341 // Handle all other redirects. |
324 MergeOnBeforeRequestResponsesHelper( | 342 MergeOnBeforeRequestResponsesHelper( |
325 deltas, new_url, conflicting_extensions, net_log, false); | 343 deltas, new_url, conflicting_extensions, net_log, false); |
344 } | |
345 | |
346 // Assumes that |header_value| is the cookie header value of a HTTP Request | |
347 // following the cookie-string schema of RFC 6265, section 4.2.1, and returns | |
348 // cookie name/value pairs. If cookie values are presented in double quotes, | |
349 // these will appear in |parsed| as well. We can assume that the cookie header | |
350 // is written by Chromium and therefore, well-formed. | |
351 static void ParseRequestCookieLine( | |
352 const std::string& header_value, | |
353 ParsedRequestCookies* parsed_cookies) { | |
354 std::string::const_iterator i = header_value.begin(); | |
355 while (i != header_value.end()) { | |
356 // Here we are at the beginning of a cookie. | |
357 | |
358 // Eat whitespace. | |
359 while (i != header_value.end() && *i == ' ') ++i; | |
360 if (i == header_value.end()) return; | |
361 | |
362 // Find cookie name. | |
363 std::string::const_iterator cookie_name_beginning = i; | |
364 while (i != header_value.end() && *i != '=') ++i; | |
365 base::StringPiece cookie_name(cookie_name_beginning, i); | |
366 | |
367 // Find cookie value. | |
368 base::StringPiece cookie_value; | |
369 if (i != header_value.end()) { // Cookies may have no value. | |
370 ++i; // Skip '='. | |
371 std::string::const_iterator cookie_value_beginning = i; | |
372 if (*i == '"') { | |
373 while (i != header_value.end() && *i != '"') ++i; | |
Nico
2013/08/22 17:15:36
http://www.viva64.com/en/b/0205/#ID0ELSBI points o
| |
374 if (i == header_value.end()) return; | |
375 ++i; // Skip '"'. | |
376 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
377 // i points to character after '"', potentially a ';' | |
378 } else { | |
379 while (i != header_value.end() && *i != ';') ++i; | |
380 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
381 // i points to ';' or end of string. | |
382 } | |
383 } | |
384 parsed_cookies->push_back(make_pair(cookie_name, cookie_value)); | |
385 // Eat ';' | |
386 if (i != header_value.end()) ++i; | |
387 } | |
388 } | |
389 | |
390 // Writes all cookies of |parsed_cookies| into a HTTP Request header value | |
391 // that belongs to the "Cookie" header. | |
392 static std::string SerializeRequestCookieLine( | |
393 const ParsedRequestCookies& parsed_cookies) { | |
394 std::string buffer; | |
395 for (ParsedRequestCookies::const_iterator i = parsed_cookies.begin(); | |
396 i != parsed_cookies.end(); ++i) { | |
397 if (!buffer.empty()) | |
398 buffer += "; "; | |
399 buffer += i->first.as_string(); | |
400 if (!i->second.empty()) | |
401 buffer += "=" + i->second.as_string(); | |
402 } | |
403 return buffer; | |
404 } | |
405 | |
406 static bool DoesRequestCookieMatchFilter( | |
407 const ParsedRequestCookie& cookie, | |
408 RequestCookie* filter) { | |
409 if (!filter) return true; | |
410 if (filter->name.get() && cookie.first != *filter->name) return false; | |
411 if (filter->value.get() && cookie.second != *filter->value) return false; | |
412 return true; | |
413 } | |
414 | |
415 // Applies all CookieModificationType::ADD operations for request cookies of | |
416 // |deltas| to |cookies|. Returns whether any cookie was added. | |
417 static bool MergeAddRequestCookieModifications( | |
418 const EventResponseDeltas& deltas, | |
419 ParsedRequestCookies* cookies) { | |
420 bool modified = false; | |
421 // We assume here that the deltas are sorted in decreasing extension | |
422 // precedence (i.e. decreasing extension installation time). | |
423 EventResponseDeltas::const_reverse_iterator delta; | |
424 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
425 const RequestCookieModifications& modifications = | |
426 (*delta)->request_cookie_modifications; | |
427 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
428 mod != modifications.end(); ++mod) { | |
429 if ((*mod)->type != ADD || !(*mod)->modification.get()) | |
430 continue; | |
431 std::string* new_name = (*mod)->modification->name.get(); | |
432 std::string* new_value = (*mod)->modification->value.get(); | |
433 if (!new_name || !new_value) | |
434 continue; | |
435 | |
436 bool cookie_with_same_name_found = false; | |
437 for (ParsedRequestCookies::iterator cookie = cookies->begin(); | |
438 cookie != cookies->end() && !cookie_with_same_name_found; ++cookie) { | |
439 if (cookie->first == *new_name) { | |
440 if (cookie->second != *new_value) { | |
441 cookie->second = *new_value; | |
442 modified = true; | |
443 } | |
444 cookie_with_same_name_found = true; | |
445 } | |
446 } | |
447 if (!cookie_with_same_name_found) { | |
448 cookies->push_back(std::make_pair(base::StringPiece(*new_name), | |
449 base::StringPiece(*new_value))); | |
450 modified = true; | |
451 } | |
452 } | |
453 } | |
454 return modified; | |
455 } | |
456 | |
457 // Applies all CookieModificationType::EDIT operations for request cookies of | |
458 // |deltas| to |cookies|. Returns whether any cookie was modified. | |
459 static bool MergeEditRequestCookieModifications( | |
460 const EventResponseDeltas& deltas, | |
461 ParsedRequestCookies* cookies) { | |
462 bool modified = false; | |
463 // We assume here that the deltas are sorted in decreasing extension | |
464 // precedence (i.e. decreasing extension installation time). | |
465 EventResponseDeltas::const_reverse_iterator delta; | |
466 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
467 const RequestCookieModifications& modifications = | |
468 (*delta)->request_cookie_modifications; | |
469 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
470 mod != modifications.end(); ++mod) { | |
471 if ((*mod)->type != EDIT || !(*mod)->modification.get()) | |
472 continue; | |
473 | |
474 std::string* new_value = (*mod)->modification->value.get(); | |
475 RequestCookie* filter = (*mod)->filter.get(); | |
476 for (ParsedRequestCookies::iterator cookie = cookies->begin(); | |
477 cookie != cookies->end(); ++cookie) { | |
478 if (!DoesRequestCookieMatchFilter(*cookie, filter)) | |
479 continue; | |
480 // If the edit operation tries to modify the cookie name, we just ignore | |
481 // this. We only modify the cookie value. | |
482 if (new_value && cookie->second != *new_value) { | |
483 cookie->second = *new_value; | |
484 modified = true; | |
485 } | |
486 } | |
487 } | |
488 } | |
489 return modified; | |
490 } | |
491 | |
492 // Applies all CookieModificationType::REMOVE operations for request cookies of | |
493 // |deltas| to |cookies|. Returns whether any cookie was deleted. | |
494 static bool MergeRemoveRequestCookieModifications( | |
495 const EventResponseDeltas& deltas, | |
496 ParsedRequestCookies* cookies) { | |
497 bool modified = false; | |
498 // We assume here that the deltas are sorted in decreasing extension | |
499 // precedence (i.e. decreasing extension installation time). | |
500 EventResponseDeltas::const_reverse_iterator delta; | |
501 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
502 const RequestCookieModifications& modifications = | |
503 (*delta)->request_cookie_modifications; | |
504 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
505 mod != modifications.end(); ++mod) { | |
506 if ((*mod)->type != REMOVE) | |
507 continue; | |
508 | |
509 RequestCookie* filter = (*mod)->filter.get(); | |
510 ParsedRequestCookies::iterator i = cookies->begin(); | |
511 while (i != cookies->end()) { | |
512 if (DoesRequestCookieMatchFilter(*i, filter)) { | |
513 i = cookies->erase(i); | |
514 modified = true; | |
515 } else { | |
516 ++i; | |
517 } | |
518 } | |
519 } | |
520 } | |
521 return modified; | |
522 } | |
523 | |
524 void MergeCookiesInOnBeforeSendHeadersResponses( | |
525 const EventResponseDeltas& deltas, | |
526 net::HttpRequestHeaders* request_headers, | |
527 std::set<std::string>* conflicting_extensions, | |
528 const net::BoundNetLog* net_log) { | |
529 // Skip all work if there are no registered cookie modifications. | |
530 bool cookie_modifications_exist = false; | |
531 EventResponseDeltas::const_iterator delta; | |
532 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | |
533 cookie_modifications_exist |= | |
534 !(*delta)->request_cookie_modifications.empty(); | |
535 } | |
536 if (!cookie_modifications_exist) | |
537 return; | |
538 | |
539 // Parse old cookie line. | |
540 std::string cookie_header; | |
541 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); | |
542 ParsedRequestCookies cookies; | |
543 ParseRequestCookieLine(cookie_header, &cookies); | |
544 | |
545 // Modify cookies. | |
546 bool modified = false; | |
547 modified |= MergeAddRequestCookieModifications(deltas, &cookies); | |
548 modified |= MergeEditRequestCookieModifications(deltas, &cookies); | |
549 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); | |
550 | |
551 // Reassemble and store new cookie line. | |
552 if (modified) { | |
553 std::string new_cookie_header = SerializeRequestCookieLine(cookies); | |
554 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, | |
555 new_cookie_header); | |
556 } | |
326 } | 557 } |
327 | 558 |
328 void MergeOnBeforeSendHeadersResponses( | 559 void MergeOnBeforeSendHeadersResponses( |
329 const EventResponseDeltas& deltas, | 560 const EventResponseDeltas& deltas, |
330 net::HttpRequestHeaders* request_headers, | 561 net::HttpRequestHeaders* request_headers, |
331 std::set<std::string>* conflicting_extensions, | 562 std::set<std::string>* conflicting_extensions, |
332 const net::BoundNetLog* net_log) { | 563 const net::BoundNetLog* net_log) { |
333 EventResponseDeltas::const_iterator delta; | 564 EventResponseDeltas::const_iterator delta; |
334 | 565 |
335 // Here we collect which headers we have removed or set to new values | 566 // Here we collect which headers we have removed or set to new values |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 net_log->AddEvent( | 642 net_log->AddEvent( |
412 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 643 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
413 base::Bind(&NetLogModificationCallback, delta->get())); | 644 base::Bind(&NetLogModificationCallback, delta->get())); |
414 } else { | 645 } else { |
415 conflicting_extensions->insert((*delta)->extension_id); | 646 conflicting_extensions->insert((*delta)->extension_id); |
416 net_log->AddEvent( | 647 net_log->AddEvent( |
417 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 648 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
418 CreateNetLogExtensionIdCallback(delta->get())); | 649 CreateNetLogExtensionIdCallback(delta->get())); |
419 } | 650 } |
420 } | 651 } |
652 | |
653 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, | |
654 conflicting_extensions, net_log); | |
655 } | |
656 | |
657 // Retrives all cookies from |override_response_headers|. | |
658 static ParsedResponseCookies GetResponseCookies( | |
659 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | |
660 ParsedResponseCookies result; | |
661 | |
662 void* iter = NULL; | |
663 std::string value; | |
664 while (override_response_headers->EnumerateHeader(&iter, "Set-Cookie", | |
665 &value)) { | |
666 result.push_back(make_linked_ptr(new net::ParsedCookie(value))); | |
667 } | |
668 return result; | |
669 } | |
670 | |
671 // Stores all |cookies| in |override_response_headers| deleting previously | |
672 // existing cookie definitions. | |
673 static void StoreResponseCookies( | |
674 const ParsedResponseCookies& cookies, | |
675 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | |
676 override_response_headers->RemoveHeader("Set-Cookie"); | |
677 for (ParsedResponseCookies::const_iterator i = cookies.begin(); | |
678 i != cookies.end(); ++i) { | |
679 override_response_headers->AddHeader("Set-Cookie: " + (*i)->ToCookieLine()); | |
680 } | |
681 } | |
682 | |
683 // Modifies |cookie| according to |modification|. Each value that is set in | |
684 // |modification| is applied to |cookie|. | |
685 static bool ApplyResponseCookieModification(ResponseCookie* modification, | |
686 net::ParsedCookie* cookie) { | |
687 bool modified = false; | |
688 if (modification->name.get()) | |
689 modified |= cookie->SetName(*modification->name); | |
690 if (modification->value.get()) | |
691 modified |= cookie->SetValue(*modification->value); | |
692 if (modification->expires.get()) | |
693 modified |= cookie->SetExpires(*modification->expires); | |
694 if (modification->max_age.get()) | |
695 modified |= cookie->SetMaxAge(base::IntToString(*modification->max_age)); | |
696 if (modification->domain.get()) | |
697 modified |= cookie->SetDomain(*modification->domain); | |
698 if (modification->path.get()) | |
699 modified |= cookie->SetPath(*modification->path); | |
700 if (modification->secure.get()) | |
701 modified |= cookie->SetIsSecure(*modification->secure); | |
702 if (modification->http_only.get()) | |
703 modified |= cookie->SetIsHttpOnly(*modification->http_only); | |
704 return modified; | |
705 } | |
706 | |
707 static bool DoesResponseCookieMatchFilter(net::ParsedCookie* cookie, | |
708 ResponseCookie* filter) { | |
709 if (!cookie->IsValid()) return false; | |
710 if (!filter) return true; | |
711 if (filter->name.get() && cookie->Name() != *filter->name) return false; | |
712 if (filter->value.get() && cookie->Value() != *filter->value) return false; | |
713 if (filter->expires.get()) { | |
714 std::string actual_value = cookie->HasExpires() ? cookie->Expires() : ""; | |
715 if (actual_value != *filter->expires) | |
716 return false; | |
717 } | |
718 if (filter->max_age.get()) { | |
719 std::string actual_value = cookie->HasMaxAge() ? cookie->MaxAge() : ""; | |
720 if (actual_value != base::IntToString(*filter->max_age)) | |
721 return false; | |
722 } | |
723 if (filter->domain.get()) { | |
724 std::string actual_value = cookie->HasDomain() ? cookie->Domain() : ""; | |
725 if (actual_value != *filter->domain) | |
726 return false; | |
727 } | |
728 if (filter->path.get()) { | |
729 std::string actual_value = cookie->HasPath() ? cookie->Path() : ""; | |
730 if (actual_value != *filter->path) | |
731 return false; | |
732 } | |
733 if (filter->secure.get() && cookie->IsSecure() != *filter->secure) | |
734 return false; | |
735 if (filter->http_only.get() && cookie->IsHttpOnly() != *filter->http_only) | |
736 return false; | |
737 return true; | |
738 } | |
739 | |
740 // Applies all CookieModificationType::ADD operations for response cookies of | |
741 // |deltas| to |cookies|. Returns whether any cookie was added. | |
742 static bool MergeAddResponseCookieModifications( | |
743 const EventResponseDeltas& deltas, | |
744 ParsedResponseCookies* cookies) { | |
745 bool modified = false; | |
746 // We assume here that the deltas are sorted in decreasing extension | |
747 // precedence (i.e. decreasing extension installation time). | |
748 EventResponseDeltas::const_reverse_iterator delta; | |
749 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
750 const ResponseCookieModifications& modifications = | |
751 (*delta)->response_cookie_modifications; | |
752 for (ResponseCookieModifications::const_iterator mod = | |
753 modifications.begin(); mod != modifications.end(); ++mod) { | |
754 if ((*mod)->type != ADD || !(*mod)->modification.get()) | |
755 continue; | |
756 // Cookie names are not unique in response cookies so we always append | |
757 // and never override. | |
758 linked_ptr<net::ParsedCookie> cookie(new net::ParsedCookie("")); | |
759 ApplyResponseCookieModification((*mod)->modification.get(), cookie.get()); | |
760 cookies->push_back(cookie); | |
761 modified = true; | |
762 } | |
763 } | |
764 return modified; | |
765 } | |
766 | |
767 // Applies all CookieModificationType::EDIT operations for response cookies of | |
768 // |deltas| to |cookies|. Returns whether any cookie was modified. | |
769 static bool MergeEditResponseCookieModifications( | |
770 const EventResponseDeltas& deltas, | |
771 ParsedResponseCookies* cookies) { | |
772 bool modified = false; | |
773 // We assume here that the deltas are sorted in decreasing extension | |
774 // precedence (i.e. decreasing extension installation time). | |
775 EventResponseDeltas::const_reverse_iterator delta; | |
776 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
777 const ResponseCookieModifications& modifications = | |
778 (*delta)->response_cookie_modifications; | |
779 for (ResponseCookieModifications::const_iterator mod = | |
780 modifications.begin(); mod != modifications.end(); ++mod) { | |
781 if ((*mod)->type != EDIT || !(*mod)->modification.get()) | |
782 continue; | |
783 | |
784 for (ParsedResponseCookies::iterator cookie = cookies->begin(); | |
785 cookie != cookies->end(); ++cookie) { | |
786 if (DoesResponseCookieMatchFilter(cookie->get(), | |
787 (*mod)->filter.get())) { | |
788 modified |= ApplyResponseCookieModification( | |
789 (*mod)->modification.get(), cookie->get()); | |
790 } | |
791 } | |
792 } | |
793 } | |
794 return modified; | |
795 } | |
796 | |
797 // Applies all CookieModificationType::REMOVE operations for response cookies of | |
798 // |deltas| to |cookies|. Returns whether any cookie was deleted. | |
799 static bool MergeRemoveResponseCookieModifications( | |
800 const EventResponseDeltas& deltas, | |
801 ParsedResponseCookies* cookies) { | |
802 bool modified = false; | |
803 // We assume here that the deltas are sorted in decreasing extension | |
804 // precedence (i.e. decreasing extension installation time). | |
805 EventResponseDeltas::const_reverse_iterator delta; | |
806 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
807 const ResponseCookieModifications& modifications = | |
808 (*delta)->response_cookie_modifications; | |
809 for (ResponseCookieModifications::const_iterator mod = | |
810 modifications.begin(); mod != modifications.end(); ++mod) { | |
811 if ((*mod)->type != REMOVE) | |
812 continue; | |
813 | |
814 ParsedResponseCookies::iterator i = cookies->begin(); | |
815 while (i != cookies->end()) { | |
816 if (DoesResponseCookieMatchFilter(i->get(), | |
817 (*mod)->filter.get())) { | |
818 i = cookies->erase(i); | |
819 modified = true; | |
820 } else { | |
821 ++i; | |
822 } | |
823 } | |
824 } | |
825 } | |
826 return modified; | |
827 } | |
828 | |
829 void MergeCookiesInOnHeadersReceivedResponses( | |
830 const EventResponseDeltas& deltas, | |
831 const net::HttpResponseHeaders* original_response_headers, | |
832 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | |
833 std::set<std::string>* conflicting_extensions, | |
834 const net::BoundNetLog* net_log) { | |
835 // Skip all work if there are no registered cookie modifications. | |
836 bool cookie_modifications_exist = false; | |
837 EventResponseDeltas::const_reverse_iterator delta; | |
838 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
839 cookie_modifications_exist |= | |
840 !(*delta)->response_cookie_modifications.empty(); | |
841 } | |
842 if (!cookie_modifications_exist) | |
843 return; | |
844 | |
845 // Only create a copy if we really want to modify the response headers. | |
846 if (override_response_headers->get() == NULL) { | |
847 *override_response_headers = new net::HttpResponseHeaders( | |
848 original_response_headers->raw_headers()); | |
849 } | |
850 | |
851 ParsedResponseCookies cookies = | |
852 GetResponseCookies(*override_response_headers); | |
853 | |
854 bool modified = false; | |
855 modified |= MergeAddResponseCookieModifications(deltas, &cookies); | |
856 modified |= MergeEditResponseCookieModifications(deltas, &cookies); | |
857 modified |= MergeRemoveResponseCookieModifications(deltas, &cookies); | |
858 | |
859 // Store new value. | |
860 if (modified) | |
861 StoreResponseCookies(cookies, *override_response_headers); | |
421 } | 862 } |
422 | 863 |
423 // Converts the key of the (key, value) pair to lower case. | 864 // Converts the key of the (key, value) pair to lower case. |
424 static ResponseHeader ToLowerCase(const ResponseHeader& header) { | 865 static ResponseHeader ToLowerCase(const ResponseHeader& header) { |
425 std::string lower_key(header.first); | 866 std::string lower_key(header.first); |
426 StringToLowerASCII(&lower_key); | 867 StringToLowerASCII(&lower_key); |
427 return ResponseHeader(lower_key, header.second); | 868 return ResponseHeader(lower_key, header.second); |
428 } | 869 } |
429 | 870 |
430 void MergeOnHeadersReceivedResponses( | 871 void MergeOnHeadersReceivedResponses( |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
495 net_log->AddEvent( | 936 net_log->AddEvent( |
496 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 937 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
497 CreateNetLogExtensionIdCallback(delta->get())); | 938 CreateNetLogExtensionIdCallback(delta->get())); |
498 } else { | 939 } else { |
499 conflicting_extensions->insert((*delta)->extension_id); | 940 conflicting_extensions->insert((*delta)->extension_id); |
500 net_log->AddEvent( | 941 net_log->AddEvent( |
501 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 942 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
502 CreateNetLogExtensionIdCallback(delta->get())); | 943 CreateNetLogExtensionIdCallback(delta->get())); |
503 } | 944 } |
504 } | 945 } |
946 | |
947 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, | |
948 override_response_headers, conflicting_extensions, net_log); | |
505 } | 949 } |
506 | 950 |
507 bool MergeOnAuthRequiredResponses( | 951 bool MergeOnAuthRequiredResponses( |
508 const EventResponseDeltas& deltas, | 952 const EventResponseDeltas& deltas, |
509 net::AuthCredentials* auth_credentials, | 953 net::AuthCredentials* auth_credentials, |
510 std::set<std::string>* conflicting_extensions, | 954 std::set<std::string>* conflicting_extensions, |
511 const net::BoundNetLog* net_log) { | 955 const net::BoundNetLog* net_log) { |
512 CHECK(auth_credentials); | 956 CHECK(auth_credentials); |
513 bool credentials_set = false; | 957 bool credentials_set = false; |
514 | 958 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 | 1011 |
568 bool CanExtensionAccessURL(const extensions::Extension* extension, | 1012 bool CanExtensionAccessURL(const extensions::Extension* extension, |
569 const GURL& url) { | 1013 const GURL& url) { |
570 // about: URLs are not covered in host permissions, but are allowed anyway. | 1014 // about: URLs are not covered in host permissions, but are allowed anyway. |
571 return (url.SchemeIs(chrome::kAboutScheme) || | 1015 return (url.SchemeIs(chrome::kAboutScheme) || |
572 extension->HasHostPermission(url) || | 1016 extension->HasHostPermission(url) || |
573 url.GetOrigin() == extension->url()); | 1017 url.GetOrigin() == extension->url()); |
574 } | 1018 } |
575 | 1019 |
576 } // namespace extension_web_request_api_helpers | 1020 } // namespace extension_web_request_api_helpers |
OLD | NEW |