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/cookie_monster.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::CookieMonster::MutableParsedCookie> > | |
27 ParsedResponseCookies; | |
28 | |
21 static const char* kResourceTypeStrings[] = { | 29 static const char* kResourceTypeStrings[] = { |
22 "main_frame", | 30 "main_frame", |
23 "sub_frame", | 31 "sub_frame", |
24 "stylesheet", | 32 "stylesheet", |
25 "script", | 33 "script", |
26 "image", | 34 "image", |
27 "object", | 35 "object", |
28 "xmlhttprequest", | 36 "xmlhttprequest", |
29 "other", | 37 "other", |
30 "other", | 38 "other", |
(...skipping 15 matching lines...) Expand all Loading... | |
46 // entry is no longer required, this should be removed. | 54 // entry is no longer required, this should be removed. |
47 ResourceType::LAST_TYPE, | 55 ResourceType::LAST_TYPE, |
48 }; | 56 }; |
49 | 57 |
50 COMPILE_ASSERT( | 58 COMPILE_ASSERT( |
51 arraysize(kResourceTypeStrings) == arraysize(kResourceTypeValues), | 59 arraysize(kResourceTypeStrings) == arraysize(kResourceTypeValues), |
52 keep_resource_types_in_sync); | 60 keep_resource_types_in_sync); |
53 | 61 |
54 } // namespace | 62 } // namespace |
55 | 63 |
64 RequestCookie::RequestCookie() {} | |
65 RequestCookie::~RequestCookie() {} | |
66 | |
67 ResponseCookie::ResponseCookie() {} | |
68 ResponseCookie::~ResponseCookie() {} | |
69 | |
70 RequestCookieModification::RequestCookieModification() {} | |
71 RequestCookieModification::~RequestCookieModification() {} | |
72 | |
73 ResponseCookieModification::ResponseCookieModification() : type(ADD) {} | |
74 ResponseCookieModification::~ResponseCookieModification() {} | |
56 | 75 |
57 EventResponseDelta::EventResponseDelta( | 76 EventResponseDelta::EventResponseDelta( |
58 const std::string& extension_id, const base::Time& extension_install_time) | 77 const std::string& extension_id, const base::Time& extension_install_time) |
59 : extension_id(extension_id), | 78 : extension_id(extension_id), |
60 extension_install_time(extension_install_time), | 79 extension_install_time(extension_install_time), |
61 cancel(false) { | 80 cancel(false) { |
62 } | 81 } |
63 | 82 |
64 EventResponseDelta::~EventResponseDelta() { | 83 EventResponseDelta::~EventResponseDelta() { |
65 } | 84 } |
(...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. | 334 // special case as they represent a way of cancelling a request. |
316 if (MergeOnBeforeRequestResponsesHelper( | 335 if (MergeOnBeforeRequestResponsesHelper( |
317 deltas, new_url, conflicting_extensions, net_log, true)) { | 336 deltas, new_url, conflicting_extensions, net_log, true)) { |
318 // If any extension cancelled a request by redirecting to a data:// URL or | 337 // If any extension cancelled a request by redirecting to a data:// URL or |
319 // about:blank, we don't consider the other redirects. | 338 // about:blank, we don't consider the other redirects. |
320 return; | 339 return; |
321 } | 340 } |
322 | 341 |
323 // Handle all other redirects. | 342 // Handle all other redirects. |
324 MergeOnBeforeRequestResponsesHelper( | 343 MergeOnBeforeRequestResponsesHelper( |
325 deltas, new_url, conflicting_extensions, net_log, false); | 344 deltas, new_url, conflicting_extensions, net_log, false); |
345 } | |
346 | |
347 // Assumes that |header_value| is the cookie header value of a HTTP Request | |
348 // following the cookie-string schema of RFC 6265, section 4.2.1, and returns | |
349 // cookie name/value pairs. If cookie values are presented in double quotes, | |
350 // these will appear in |parsed| as well. We can assume that the cookie header | |
351 // is written by Chromium and therefore, well-formed. | |
352 static void ParseRequestCookieLine( | |
Matt Perry
2012/07/09 23:26:13
We already have cookie parsing code in net/. Can w
battre
2012/08/02 17:17:34
net/ has parsing code for *response* cookie lines.
Matt Perry
2012/08/02 17:37:51
I see. And I presume there's no way to pull the st
| |
353 const std::string& header_value, | |
354 ParsedRequestCookies* parsed_cookies) { | |
355 std::string::const_iterator i = header_value.begin(); | |
356 while (i != header_value.end()) { | |
357 // Here we are at the beginning of a cookie. | |
358 | |
359 // Eat whitespace. | |
360 while (i != header_value.end() && *i == ' ') ++i; | |
361 if (i == header_value.end()) return; | |
362 | |
363 // Find cookie name. | |
364 std::string::const_iterator cookie_name_beginning = i; | |
365 while (i != header_value.end() && *i != '=') ++i; | |
366 if (i == header_value.end()) return; | |
367 base::StringPiece cookie_name(cookie_name_beginning, i); | |
368 | |
369 // Find cookie value. | |
370 ++i; // Skip '='. | |
371 std::string::const_iterator cookie_value_beginning = i; | |
372 base::StringPiece cookie_value; | |
373 if (*i == '"') { | |
374 while (i != header_value.end() && *i != '"') ++i; | |
375 if (i == header_value.end()) return; | |
376 ++i; // Skip '"'. | |
377 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
378 // i points to character after '"', potentially a ';' | |
379 } else { | |
380 while (i != header_value.end() && *i != ';') ++i; | |
381 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
382 // i points to ';' or end of string. | |
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() + "=" + i->second.as_string(); | |
400 } | |
401 return buffer; | |
402 } | |
403 | |
404 static bool DoesRequestCookieMatchFilter( | |
405 const ParsedRequestCookie& cookie, | |
406 RequestCookie* filter) { | |
407 if (!filter) return true; | |
408 if (filter->name.get() && cookie.first != *filter->name) return false; | |
409 if (filter->value.get() && cookie.second != *filter->value) return false; | |
410 return true; | |
411 } | |
412 | |
413 // Applies all CookieModificationType::ADD operations for request cookies of | |
414 // |deltas| to |cookies|. Returns whether any cookie was added. | |
415 static bool MergeAddRequestCookieModifications( | |
416 const EventResponseDeltas& deltas, | |
417 ParsedRequestCookies* cookies) { | |
418 bool modified = false; | |
419 // We assume here that the deltas are sorted in decreasing extension | |
420 // precedence (i.e. decreasing extension installation time). | |
421 EventResponseDeltas::const_reverse_iterator delta; | |
422 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
423 const RequestCookieModifications& modifications = | |
424 (*delta)->request_cookie_modifications; | |
425 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
426 mod != modifications.end(); ++mod) { | |
427 if ((*mod)->type != ADD || !(*mod)->modification.get()) | |
428 continue; | |
429 std::string* new_name = (*mod)->modification->name.get(); | |
430 std::string* new_value = (*mod)->modification->value.get(); | |
431 if (!new_name || !new_value) | |
432 continue; | |
433 | |
434 bool cookie_with_same_name_found = false; | |
435 for (ParsedRequestCookies::iterator cookie = cookies->begin(); | |
436 cookie != cookies->end() && !cookie_with_same_name_found; ++cookie) { | |
437 if (cookie->first == *new_name) { | |
438 if (cookie->second != *new_value) { | |
439 cookie->second = *new_value; | |
440 modified = true; | |
441 } | |
442 cookie_with_same_name_found = true; | |
443 } | |
444 } | |
445 if (!cookie_with_same_name_found) { | |
446 cookies->push_back(std::make_pair(*new_name, *new_value)); | |
447 modified = true; | |
448 } | |
449 } | |
450 } | |
451 return modified; | |
452 } | |
453 | |
454 // Applies all CookieModificationType::EDIT operations for request cookies of | |
455 // |deltas| to |cookies|. Returns whether any cookie was modified. | |
456 static bool MergeEditRequestCookieModifications( | |
457 const EventResponseDeltas& deltas, | |
458 ParsedRequestCookies* cookies) { | |
459 bool modified = false; | |
460 // We assume here that the deltas are sorted in decreasing extension | |
461 // precedence (i.e. decreasing extension installation time). | |
462 EventResponseDeltas::const_reverse_iterator delta; | |
463 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
464 const RequestCookieModifications& modifications = | |
465 (*delta)->request_cookie_modifications; | |
466 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
467 mod != modifications.end(); ++mod) { | |
468 if ((*mod)->type != EDIT || !(*mod)->modification.get()) | |
469 continue; | |
470 | |
471 std::string* new_value = (*mod)->modification->value.get(); | |
472 RequestCookie* filter = (*mod)->filter.get(); | |
473 for (ParsedRequestCookies::iterator cookie = cookies->begin(); | |
474 cookie != cookies->end(); ++cookie) { | |
475 if (!DoesRequestCookieMatchFilter(*cookie, filter)) | |
476 continue; | |
477 // If the edit operation tries to modify the cookie name, we just ignore | |
478 // this. We only modify the cookie value. | |
479 if (new_value && cookie->second != *new_value) { | |
480 cookie->second = *new_value; | |
481 modified = true; | |
482 } | |
483 } | |
484 } | |
485 } | |
486 return modified; | |
487 } | |
488 | |
489 // Applies all CookieModificationType::REMOVE operations for request cookies of | |
490 // |deltas| to |cookies|. Returns whether any cookie was deleted. | |
491 static bool MergeRemoveRequestCookieModifications( | |
492 const EventResponseDeltas& deltas, | |
493 ParsedRequestCookies* cookies) { | |
494 bool modified = false; | |
495 // We assume here that the deltas are sorted in decreasing extension | |
496 // precedence (i.e. decreasing extension installation time). | |
497 EventResponseDeltas::const_reverse_iterator delta; | |
498 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
499 const RequestCookieModifications& modifications = | |
500 (*delta)->request_cookie_modifications; | |
501 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
502 mod != modifications.end(); ++mod) { | |
503 if ((*mod)->type != REMOVE) | |
504 continue; | |
505 | |
506 RequestCookie* filter = (*mod)->filter.get(); | |
507 ParsedRequestCookies::iterator i = cookies->begin(); | |
508 while (i != cookies->end()) { | |
509 if (DoesRequestCookieMatchFilter(*i, filter)) { | |
510 i = cookies->erase(i); | |
511 modified = true; | |
512 } else { | |
513 ++i; | |
514 } | |
515 } | |
516 } | |
517 } | |
518 return modified; | |
519 } | |
520 | |
521 void MergeCookiesInOnBeforeSendHeadersResponses( | |
522 const EventResponseDeltas& deltas, | |
523 net::HttpRequestHeaders* request_headers, | |
524 std::set<std::string>* conflicting_extensions, | |
525 const net::BoundNetLog* net_log) { | |
526 // Skip all work if there are no registered cookie modifications. | |
527 bool cookie_modifications_exist = false; | |
528 EventResponseDeltas::const_iterator delta; | |
529 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | |
530 cookie_modifications_exist |= | |
531 !(*delta)->request_cookie_modifications.empty(); | |
532 } | |
533 if (!cookie_modifications_exist) | |
534 return; | |
535 | |
536 // Parse old cookie line. | |
537 std::string cookie_header; | |
538 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); | |
539 ParsedRequestCookies cookies; | |
540 ParseRequestCookieLine(cookie_header, &cookies); | |
541 | |
542 // Modify cookies. | |
543 bool modified = false; | |
544 modified |= MergeAddRequestCookieModifications(deltas, &cookies); | |
545 modified |= MergeEditRequestCookieModifications(deltas, &cookies); | |
546 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); | |
547 | |
548 // Resemble and store new cookie line. | |
Matt Perry
2012/07/09 23:26:13
Reassemble*
battre
2012/08/02 17:17:34
Done.
| |
549 if (modified) { | |
550 std::string new_cookie_header = SerializeRequestCookieLine(cookies); | |
551 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, | |
552 new_cookie_header); | |
553 } | |
326 } | 554 } |
327 | 555 |
328 void MergeOnBeforeSendHeadersResponses( | 556 void MergeOnBeforeSendHeadersResponses( |
329 const EventResponseDeltas& deltas, | 557 const EventResponseDeltas& deltas, |
330 net::HttpRequestHeaders* request_headers, | 558 net::HttpRequestHeaders* request_headers, |
331 std::set<std::string>* conflicting_extensions, | 559 std::set<std::string>* conflicting_extensions, |
332 const net::BoundNetLog* net_log) { | 560 const net::BoundNetLog* net_log) { |
333 EventResponseDeltas::const_iterator delta; | 561 EventResponseDeltas::const_iterator delta; |
334 | 562 |
335 // Here we collect which headers we have removed or set to new values | 563 // 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( | 639 net_log->AddEvent( |
412 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 640 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
413 base::Bind(&NetLogModificationCallback, delta->get())); | 641 base::Bind(&NetLogModificationCallback, delta->get())); |
414 } else { | 642 } else { |
415 conflicting_extensions->insert((*delta)->extension_id); | 643 conflicting_extensions->insert((*delta)->extension_id); |
416 net_log->AddEvent( | 644 net_log->AddEvent( |
417 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 645 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
418 CreateNetLogExtensionIdCallback(delta->get())); | 646 CreateNetLogExtensionIdCallback(delta->get())); |
419 } | 647 } |
420 } | 648 } |
649 | |
650 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, | |
651 conflicting_extensions, net_log); | |
652 } | |
653 | |
654 // Retrives all cookies from |override_response_headers|. | |
655 static ParsedResponseCookies GetResponseCookies( | |
656 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | |
657 ParsedResponseCookies result; | |
658 | |
659 void* iter = NULL; | |
660 std::string value; | |
661 while (override_response_headers->EnumerateHeader(&iter, "Set-Cookie", | |
662 &value)) { | |
663 result.push_back(make_linked_ptr( | |
664 new net::CookieMonster::MutableParsedCookie(value))); | |
665 } | |
666 return result; | |
667 } | |
668 | |
669 // Stores all |cookies| in |override_response_headers| deleting previously | |
670 // existing cookie definitions. | |
671 static void StoreResponseCookies( | |
672 const ParsedResponseCookies& cookies, | |
673 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | |
674 override_response_headers->RemoveHeader("Set-Cookie"); | |
675 for (ParsedResponseCookies::const_iterator i = cookies.begin(); | |
676 i != cookies.end(); ++i) { | |
677 override_response_headers->AddHeader("Set-Cookie: " + (*i)->ToCookieLine()); | |
678 } | |
679 } | |
680 | |
681 // Modifies |cookie| according to |modification|. Each value that is set in | |
682 // |modification| is applied to |cookie|. | |
683 static bool ApplyResponseCookieModification( | |
684 ResponseCookie* modification, | |
685 net::CookieMonster::MutableParsedCookie* cookie) { | |
686 bool modified = false; | |
687 if (modification->name.get()) | |
688 modified |= cookie->SetName(*modification->name); | |
689 if (modification->value.get()) | |
690 modified |= cookie->SetValue(*modification->value); | |
691 if (modification->expires.get()) | |
692 modified |= cookie->SetExpires(*modification->expires); | |
693 if (modification->max_age.get()) | |
694 modified |= cookie->SetMaxAge(base::IntToString(*modification->max_age)); | |
695 if (modification->domain.get()) | |
696 modified |= cookie->SetDomain(*modification->domain); | |
697 if (modification->path.get()) | |
698 modified |= cookie->SetPath(*modification->path); | |
699 if (modification->secure.get()) | |
700 modified |= cookie->SetIsSecure(*modification->secure); | |
701 if (modification->http_only.get()) | |
702 modified |= cookie->SetIsHttpOnly(*modification->http_only); | |
703 return modified; | |
704 } | |
705 | |
706 static bool DoesResponseCookieMatchFilter( | |
707 net::CookieMonster::MutableParsedCookie* 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::CookieMonster::MutableParsedCookie> cookie = | |
759 make_linked_ptr(new net::CookieMonster::MutableParsedCookie("")); | |
760 ApplyResponseCookieModification((*mod)->modification.get(), cookie.get()); | |
761 cookies->push_back(cookie); | |
762 modified = true; | |
763 } | |
764 } | |
765 return modified; | |
766 } | |
767 | |
768 // Applies all CookieModificationType::EDIT operations for response cookies of | |
769 // |deltas| to |cookies|. Returns whether any cookie was modified. | |
770 static bool MergeEditResponseCookieModifications( | |
771 const EventResponseDeltas& deltas, | |
772 ParsedResponseCookies* cookies) { | |
773 bool modified = false; | |
774 // We assume here that the deltas are sorted in decreasing extension | |
775 // precedence (i.e. decreasing extension installation time). | |
776 EventResponseDeltas::const_reverse_iterator delta; | |
777 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
778 const ResponseCookieModifications& modifications = | |
779 (*delta)->response_cookie_modifications; | |
780 for (ResponseCookieModifications::const_iterator mod = | |
781 modifications.begin(); mod != modifications.end(); ++mod) { | |
782 if ((*mod)->type != EDIT || !(*mod)->modification.get()) | |
783 continue; | |
784 | |
785 for (ParsedResponseCookies::iterator cookie = cookies->begin(); | |
786 cookie != cookies->end(); ++cookie) { | |
787 if (DoesResponseCookieMatchFilter(cookie->get(), | |
788 (*mod)->filter.get())) { | |
789 modified |= ApplyResponseCookieModification( | |
790 (*mod)->modification.get(), cookie->get()); | |
791 } | |
792 } | |
793 } | |
794 } | |
795 return modified; | |
796 } | |
797 | |
798 // Applies all CookieModificationType::REMOVE operations for response cookies of | |
799 // |deltas| to |cookies|. Returns whether any cookie was deleteds. | |
Matt Perry
2012/07/09 23:26:13
deleted*
battre
2012/08/02 17:17:34
Done.
| |
800 static bool MergeRemoveResponseCookieModifications( | |
801 const EventResponseDeltas& deltas, | |
802 ParsedResponseCookies* cookies) { | |
803 bool modified = false; | |
804 // We assume here that the deltas are sorted in decreasing extension | |
805 // precedence (i.e. decreasing extension installation time). | |
806 EventResponseDeltas::const_reverse_iterator delta; | |
807 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
808 const ResponseCookieModifications& modifications = | |
809 (*delta)->response_cookie_modifications; | |
810 for (ResponseCookieModifications::const_iterator mod = | |
811 modifications.begin(); mod != modifications.end(); ++mod) { | |
812 if ((*mod)->type != REMOVE) | |
813 continue; | |
814 | |
815 ParsedResponseCookies::iterator i = cookies->begin(); | |
816 while (i != cookies->end()) { | |
817 if (DoesResponseCookieMatchFilter(i->get(), | |
818 (*mod)->filter.get())) { | |
819 i = cookies->erase(i); | |
820 modified = true; | |
821 } else { | |
822 ++i; | |
823 } | |
824 } | |
825 } | |
826 } | |
827 return modified; | |
828 } | |
829 | |
830 void MergeCookiesInOnHeadersReceivedResponses( | |
831 const EventResponseDeltas& deltas, | |
832 const net::HttpResponseHeaders* original_response_headers, | |
833 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | |
834 std::set<std::string>* conflicting_extensions, | |
835 const net::BoundNetLog* net_log) { | |
836 // Skip all work if there are no registered cookie modifications. | |
837 bool cookie_modifications_exist = false; | |
838 EventResponseDeltas::const_reverse_iterator delta; | |
839 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
840 cookie_modifications_exist |= | |
841 !(*delta)->response_cookie_modifications.empty(); | |
842 } | |
843 if (!cookie_modifications_exist) | |
844 return; | |
845 | |
846 // Only create a copy if we really want to modify the response headers. | |
847 if (override_response_headers->get() == NULL) { | |
848 *override_response_headers = new net::HttpResponseHeaders( | |
849 original_response_headers->raw_headers()); | |
850 } | |
851 | |
852 ParsedResponseCookies cookies = | |
853 GetResponseCookies(*override_response_headers); | |
854 | |
855 bool modified = false; | |
856 modified |= MergeAddResponseCookieModifications(deltas, &cookies); | |
857 modified |= MergeEditResponseCookieModifications(deltas, &cookies); | |
858 modified |= MergeRemoveResponseCookieModifications(deltas, &cookies); | |
859 | |
860 // Store new value. | |
861 if (modified) | |
862 StoreResponseCookies(cookies, *override_response_headers); | |
421 } | 863 } |
422 | 864 |
423 // Converts the key of the (key, value) pair to lower case. | 865 // Converts the key of the (key, value) pair to lower case. |
424 static ResponseHeader ToLowerCase(const ResponseHeader& header) { | 866 static ResponseHeader ToLowerCase(const ResponseHeader& header) { |
425 std::string lower_key(header.first); | 867 std::string lower_key(header.first); |
426 StringToLowerASCII(&lower_key); | 868 StringToLowerASCII(&lower_key); |
427 return ResponseHeader(lower_key, header.second); | 869 return ResponseHeader(lower_key, header.second); |
428 } | 870 } |
429 | 871 |
430 void MergeOnHeadersReceivedResponses( | 872 void MergeOnHeadersReceivedResponses( |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 net_log->AddEvent( | 938 net_log->AddEvent( |
497 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 939 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
498 CreateNetLogExtensionIdCallback(delta->get())); | 940 CreateNetLogExtensionIdCallback(delta->get())); |
499 } else { | 941 } else { |
500 conflicting_extensions->insert((*delta)->extension_id); | 942 conflicting_extensions->insert((*delta)->extension_id); |
501 net_log->AddEvent( | 943 net_log->AddEvent( |
502 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 944 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
503 CreateNetLogExtensionIdCallback(delta->get())); | 945 CreateNetLogExtensionIdCallback(delta->get())); |
504 } | 946 } |
505 } | 947 } |
948 | |
949 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, | |
950 override_response_headers, conflicting_extensions, net_log); | |
506 } | 951 } |
507 | 952 |
508 bool MergeOnAuthRequiredResponses( | 953 bool MergeOnAuthRequiredResponses( |
509 const EventResponseDeltas& deltas, | 954 const EventResponseDeltas& deltas, |
510 net::AuthCredentials* auth_credentials, | 955 net::AuthCredentials* auth_credentials, |
511 std::set<std::string>* conflicting_extensions, | 956 std::set<std::string>* conflicting_extensions, |
512 const net::BoundNetLog* net_log) { | 957 const net::BoundNetLog* net_log) { |
513 CHECK(auth_credentials); | 958 CHECK(auth_credentials); |
514 bool credentials_set = false; | 959 bool credentials_set = false; |
515 | 960 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 ResourceType::Type* type) { | 1063 ResourceType::Type* type) { |
619 const char** iter = | 1064 const char** iter = |
620 std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str); | 1065 std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str); |
621 if (iter == ARRAYEND(kResourceTypeStrings)) | 1066 if (iter == ARRAYEND(kResourceTypeStrings)) |
622 return false; | 1067 return false; |
623 *type = kResourceTypeValues[iter - kResourceTypeStrings]; | 1068 *type = kResourceTypeValues[iter - kResourceTypeStrings]; |
624 return true; | 1069 return true; |
625 } | 1070 } |
626 | 1071 |
627 } // namespace extension_web_request_api_helpers | 1072 } // namespace extension_web_request_api_helpers |
OLD | NEW |