Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: net/http/http_response_headers.cc

Issue 18533: Merge r5767 - Protect cookie headers from XHR... (Closed) Base URL: svn://chrome-svn/chrome/branches/release_154.next/src/
Patch Set: Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_response_headers.h ('k') | net/http/http_response_headers_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 // The rules for header parsing were borrowed from Firefox: 5 // The rules for header parsing were borrowed from Firefox:
6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo nseHead.cpp 6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo nseHead.cpp
7 // The rules for parsing content-types were also borrowed from Firefox: 7 // The rules for parsing content-types were also borrowed from Firefox:
8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834
9 9
10 #include "net/http/http_response_headers.h" 10 #include "net/http/http_response_headers.h"
11 11
12 #include <algorithm> 12 #include <algorithm>
13 13
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/pickle.h" 15 #include "base/pickle.h"
16 #include "base/string_util.h" 16 #include "base/string_util.h"
17 #include "base/time.h" 17 #include "base/time.h"
18 #include "net/base/escape.h" 18 #include "net/base/escape.h"
19 #include "net/http/http_util.h" 19 #include "net/http/http_util.h"
20 20
21 namespace net { 21 namespace net {
22 22
23 //----------------------------------------------------------------------------- 23 //-----------------------------------------------------------------------------
24 24
25 namespace { 25 namespace {
26 26
27 // These response headers are not persisted in a cached representation of the 27 // These headers are RFC 2616 hop-by-hop headers;
28 // response headers. (This list comes from Mozilla's nsHttpResponseHead.cpp) 28 // not to be stored by caches.
29 const char* const kTransientHeaders[] = { 29 const char* const kHopByHopResponseHeaders[] = {
30 "connection", 30 "connection",
31 "proxy-connection", 31 "proxy-connection",
32 "keep-alive", 32 "keep-alive",
33 "www-authenticate",
34 "proxy-authenticate",
35 "trailer", 33 "trailer",
36 "transfer-encoding", 34 "transfer-encoding",
37 "upgrade", 35 "upgrade"
36 };
37
38 // These headers are challenge response headers;
39 // not to be stored by caches.
40 const char* const kChallengeResponseHeaders[] = {
41 "www-authenticate",
42 "proxy-authenticate"
43 };
44
45 // These headers are cookie setting headers;
46 // not to be stored by caches or disclosed otherwise.
47 const char* const kCookieResponseHeaders[] = {
38 "set-cookie", 48 "set-cookie",
39 "set-cookie2" 49 "set-cookie2"
40 }; 50 };
41 51
42 // These respones headers are not copied from a 304/206 response to the cached 52 // These response headers are not copied from a 304/206 response to the cached
43 // response headers. This list is based on Mozilla's nsHttpResponseHead.cpp. 53 // response headers. This list is based on Mozilla's nsHttpResponseHead.cpp.
44 const char* const kNonUpdatedHeaders[] = { 54 const char* const kNonUpdatedHeaders[] = {
45 "connection", 55 "connection",
46 "proxy-connection", 56 "proxy-connection",
47 "keep-alive", 57 "keep-alive",
48 "www-authenticate", 58 "www-authenticate",
49 "proxy-authenticate", 59 "proxy-authenticate",
50 "trailer", 60 "trailer",
51 "transfer-encoding", 61 "transfer-encoding",
52 "upgrade", 62 "upgrade",
(...skipping 27 matching lines...) Expand all
80 Parse(raw_input); 90 Parse(raw_input);
81 } 91 }
82 92
83 HttpResponseHeaders::HttpResponseHeaders(const Pickle& pickle, void** iter) 93 HttpResponseHeaders::HttpResponseHeaders(const Pickle& pickle, void** iter)
84 : response_code_(-1) { 94 : response_code_(-1) {
85 std::string raw_input; 95 std::string raw_input;
86 if (pickle.ReadString(iter, &raw_input)) 96 if (pickle.ReadString(iter, &raw_input))
87 Parse(raw_input); 97 Parse(raw_input);
88 } 98 }
89 99
90 void HttpResponseHeaders::Persist(Pickle* pickle, bool for_cache) { 100 void HttpResponseHeaders::Persist(Pickle* pickle, PersistOptions options) {
91 if (for_cache) { 101 if (options == PERSIST_RAW) {
92 HeaderSet transient_headers; 102 pickle->WriteString(raw_headers_);
93 GetTransientHeaders(&transient_headers); 103 return; // Done.
104 }
94 105
95 std::string blob; 106 HeaderSet filter_headers;
96 blob.reserve(raw_headers_.size());
97 107
98 // this just copies the status line w/ terminator 108 // Construct set of headers to filter out based on options.
99 blob.assign(raw_headers_.c_str(), strlen(raw_headers_.c_str()) + 1); 109 if ((options & PERSIST_SANS_NON_CACHEABLE) == PERSIST_SANS_NON_CACHEABLE)
110 AddNonCacheableHeaders(&filter_headers);
100 111
101 for (size_t i = 0; i < parsed_.size(); ++i) { 112 if ((options & PERSIST_SANS_COOKIES) == PERSIST_SANS_COOKIES)
102 DCHECK(!parsed_[i].is_continuation()); 113 AddCookieHeaders(&filter_headers);
103 114
104 // locate the start of the next header 115 if ((options & PERSIST_SANS_CHALLENGES) == PERSIST_SANS_CHALLENGES)
105 size_t k = i; 116 AddChallengeHeaders(&filter_headers);
106 while (++k < parsed_.size() && parsed_[k].is_continuation());
107 --k;
108 117
109 std::string header_name(parsed_[i].name_begin, parsed_[i].name_end); 118 if ((options & PERSIST_SANS_HOP_BY_HOP) == PERSIST_SANS_HOP_BY_HOP)
110 StringToLowerASCII(&header_name); 119 AddHopByHopHeaders(&filter_headers);
111 120
112 if (transient_headers.find(header_name) == transient_headers.end()) { 121 std::string blob;
113 // includes terminator 122 blob.reserve(raw_headers_.size());
114 blob.append(parsed_[i].name_begin, parsed_[k].value_end + 1);
115 }
116 123
117 i = k; 124 // This copies the status line w/ terminator null.
125 // Note raw_headers_ has embedded nulls instead of \n,
126 // so this just copies the first header line.
127 blob.assign(raw_headers_.c_str(), strlen(raw_headers_.c_str()) + 1);
128
129 for (size_t i = 0; i < parsed_.size(); ++i) {
130 DCHECK(!parsed_[i].is_continuation());
131
132 // Locate the start of the next header.
133 size_t k = i;
134 while (++k < parsed_.size() && parsed_[k].is_continuation());
135 --k;
136
137 std::string header_name(parsed_[i].name_begin, parsed_[i].name_end);
138 StringToLowerASCII(&header_name);
139
140 if (filter_headers.find(header_name) == filter_headers.end()) {
141 // Includes terminator null due to the + 1.
142 blob.append(parsed_[i].name_begin, parsed_[k].value_end + 1);
118 } 143 }
119 blob.push_back('\0');
120 144
121 pickle->WriteString(blob); 145 i = k;
122 } else {
123 pickle->WriteString(raw_headers_);
124 } 146 }
147 blob.push_back('\0');
148
149 pickle->WriteString(blob);
125 } 150 }
126 151
127 void HttpResponseHeaders::Update(const HttpResponseHeaders& new_headers) { 152 void HttpResponseHeaders::Update(const HttpResponseHeaders& new_headers) {
128 DCHECK(new_headers.response_code() == 304 || 153 DCHECK(new_headers.response_code() == 304 ||
129 new_headers.response_code() == 206); 154 new_headers.response_code() == 206);
130 155
131 // copy up to the null byte. this just copies the status line. 156 // copy up to the null byte. this just copies the status line.
132 std::string new_raw_headers(raw_headers_.c_str()); 157 std::string new_raw_headers(raw_headers_.c_str());
133 new_raw_headers.push_back('\0'); 158 new_raw_headers.push_back('\0');
134 159
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 std::string::const_iterator value_begin, 572 std::string::const_iterator value_begin,
548 std::string::const_iterator value_end) { 573 std::string::const_iterator value_end) {
549 ParsedHeader header; 574 ParsedHeader header;
550 header.name_begin = name_begin; 575 header.name_begin = name_begin;
551 header.name_end = name_end; 576 header.name_end = name_end;
552 header.value_begin = value_begin; 577 header.value_begin = value_begin;
553 header.value_end = value_end; 578 header.value_end = value_end;
554 parsed_.push_back(header); 579 parsed_.push_back(header);
555 } 580 }
556 581
557 void HttpResponseHeaders::GetTransientHeaders(HeaderSet* result) const { 582 void HttpResponseHeaders::AddNonCacheableHeaders(HeaderSet* result) const {
558 // Add server specified transients. Any 'cache-control: no-cache="foo,bar"' 583 // Add server specified transients. Any 'cache-control: no-cache="foo,bar"'
559 // headers present in the response specify additional headers that we should 584 // headers present in the response specify additional headers that we should
560 // not store in the cache. 585 // not store in the cache.
561 const std::string kCacheControl = "cache-control"; 586 const std::string kCacheControl = "cache-control";
562 const std::string kPrefix = "no-cache=\""; 587 const std::string kPrefix = "no-cache=\"";
563 std::string value; 588 std::string value;
564 void* iter = NULL; 589 void* iter = NULL;
565 while (EnumerateHeader(&iter, kCacheControl, &value)) { 590 while (EnumerateHeader(&iter, kCacheControl, &value)) {
566 if (value.size() > kPrefix.size() && 591 if (value.size() > kPrefix.size() &&
567 value.compare(0, kPrefix.size(), kPrefix) == 0) { 592 value.compare(0, kPrefix.size(), kPrefix) == 0) {
(...skipping 24 matching lines...) Expand all
592 617
593 // repeat 618 // repeat
594 begin_pos = comma_pos + 1; 619 begin_pos = comma_pos + 1;
595 while (begin_pos < value.size() && strchr(HTTP_LWS, value[begin_pos])) 620 while (begin_pos < value.size() && strchr(HTTP_LWS, value[begin_pos]))
596 begin_pos++; 621 begin_pos++;
597 if (begin_pos >= value.size()) 622 if (begin_pos >= value.size())
598 break; 623 break;
599 } 624 }
600 } 625 }
601 } 626 }
627 }
602 628
603 // Add standard transient headers. Perhaps we should move this to a 629 void HttpResponseHeaders::AddHopByHopHeaders(HeaderSet* result) {
604 // statically cached hash_set to avoid duplicated work? 630 for (size_t i = 0; i < arraysize(kHopByHopResponseHeaders); ++i)
605 for (size_t i = 0; i < arraysize(kTransientHeaders); ++i) 631 result->insert(std::string(kHopByHopResponseHeaders[i]));
606 result->insert(std::string(kTransientHeaders[i])); 632 }
633
634 void HttpResponseHeaders::AddCookieHeaders(HeaderSet* result) {
635 for (size_t i = 0; i < arraysize(kCookieResponseHeaders); ++i)
636 result->insert(std::string(kCookieResponseHeaders[i]));
637 }
638
639 void HttpResponseHeaders::AddChallengeHeaders(HeaderSet* result) {
640 for (size_t i = 0; i < arraysize(kChallengeResponseHeaders); ++i)
641 result->insert(std::string(kChallengeResponseHeaders[i]));
607 } 642 }
608 643
609 void HttpResponseHeaders::GetMimeTypeAndCharset(std::string* mime_type, 644 void HttpResponseHeaders::GetMimeTypeAndCharset(std::string* mime_type,
610 std::string* charset) const { 645 std::string* charset) const {
611 mime_type->clear(); 646 mime_type->clear();
612 charset->clear(); 647 charset->clear();
613 648
614 std::string name = "content-type"; 649 std::string name = "content-type";
615 std::string value; 650 std::string value;
616 651
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 int64 result; 965 int64 result;
931 bool ok = StringToInt64(content_length_val, &result); 966 bool ok = StringToInt64(content_length_val, &result);
932 if (!ok || result < 0) 967 if (!ok || result < 0)
933 return -1; 968 return -1;
934 969
935 return result; 970 return result;
936 } 971 }
937 972
938 } // namespace net 973 } // namespace net
939 974
OLDNEW
« no previous file with comments | « net/http/http_response_headers.h ('k') | net/http/http_response_headers_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698