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

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

Issue 1841863002: Update monet. (Closed) Base URL: https://github.com/domokit/monet.git@master
Patch Set: Created 4 years, 8 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
« 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) 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 // 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"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 // this list: 91 // this list:
92 const char* const kNonUpdatedHeaderPrefixes[] = { 92 const char* const kNonUpdatedHeaderPrefixes[] = {
93 "content-", 93 "content-",
94 "x-content-", 94 "x-content-",
95 "x-webkit-" 95 "x-webkit-"
96 }; 96 };
97 97
98 bool ShouldUpdateHeader(const std::string::const_iterator& name_begin, 98 bool ShouldUpdateHeader(const std::string::const_iterator& name_begin,
99 const std::string::const_iterator& name_end) { 99 const std::string::const_iterator& name_end) {
100 for (size_t i = 0; i < arraysize(kNonUpdatedHeaders); ++i) { 100 for (size_t i = 0; i < arraysize(kNonUpdatedHeaders); ++i) {
101 if (LowerCaseEqualsASCII(name_begin, name_end, kNonUpdatedHeaders[i])) 101 if (base::LowerCaseEqualsASCII(name_begin, name_end, kNonUpdatedHeaders[i]))
102 return false; 102 return false;
103 } 103 }
104 for (size_t i = 0; i < arraysize(kNonUpdatedHeaderPrefixes); ++i) { 104 for (size_t i = 0; i < arraysize(kNonUpdatedHeaderPrefixes); ++i) {
105 if (StartsWithASCII(std::string(name_begin, name_end), 105 if (base::StartsWithASCII(std::string(name_begin, name_end),
106 kNonUpdatedHeaderPrefixes[i], false)) 106 kNonUpdatedHeaderPrefixes[i], false))
107 return false; 107 return false;
108 } 108 }
109 return true; 109 return true;
110 } 110 }
111 111
112 void CheckDoesNotHaveEmbededNulls(const std::string& str) { 112 void CheckDoesNotHaveEmbededNulls(const std::string& str) {
113 // Care needs to be taken when adding values to the raw headers string to 113 // Care needs to be taken when adding values to the raw headers string to
114 // make sure it does not contain embeded NULLs. Any embeded '\0' may be 114 // make sure it does not contain embeded NULLs. Any embeded '\0' may be
115 // understood as line terminators and change how header lines get tokenized. 115 // understood as line terminators and change how header lines get tokenized.
116 CHECK(str.find('\0') == std::string::npos); 116 CHECK(str.find('\0') == std::string::npos);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 // new object from that pickle. 149 // new object from that pickle.
150 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.HttpResponseCode", 150 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.HttpResponseCode",
151 HttpUtil::MapStatusCodeForHistogram( 151 HttpUtil::MapStatusCodeForHistogram(
152 response_code_), 152 response_code_),
153 // Note the third argument is only 153 // Note the third argument is only
154 // evaluated once, see macro 154 // evaluated once, see macro
155 // definition for details. 155 // definition for details.
156 HttpUtil::GetStatusCodesForHistogram()); 156 HttpUtil::GetStatusCodesForHistogram());
157 } 157 }
158 158
159 HttpResponseHeaders::HttpResponseHeaders(PickleIterator* iter) 159 HttpResponseHeaders::HttpResponseHeaders(base::PickleIterator* iter)
160 : response_code_(-1) { 160 : response_code_(-1) {
161 std::string raw_input; 161 std::string raw_input;
162 if (iter->ReadString(&raw_input)) 162 if (iter->ReadString(&raw_input))
163 Parse(raw_input); 163 Parse(raw_input);
164 } 164 }
165 165
166 void HttpResponseHeaders::Persist(Pickle* pickle, PersistOptions options) { 166 void HttpResponseHeaders::Persist(base::Pickle* pickle,
167 PersistOptions options) {
167 if (options == PERSIST_RAW) { 168 if (options == PERSIST_RAW) {
168 pickle->WriteString(raw_headers_); 169 pickle->WriteString(raw_headers_);
169 return; // Done. 170 return; // Done.
170 } 171 }
171 172
172 HeaderSet filter_headers; 173 HeaderSet filter_headers;
173 174
174 // Construct set of headers to filter out based on options. 175 // Construct set of headers to filter out based on options.
175 if ((options & PERSIST_SANS_NON_CACHEABLE) == PERSIST_SANS_NON_CACHEABLE) 176 if ((options & PERSIST_SANS_NON_CACHEABLE) == PERSIST_SANS_NON_CACHEABLE)
176 AddNonCacheableHeaders(&filter_headers); 177 AddNonCacheableHeaders(&filter_headers);
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 597
597 bool HttpResponseHeaders::HasHeaderValue(const base::StringPiece& name, 598 bool HttpResponseHeaders::HasHeaderValue(const base::StringPiece& name,
598 const base::StringPiece& value) const { 599 const base::StringPiece& value) const {
599 // The value has to be an exact match. This is important since 600 // The value has to be an exact match. This is important since
600 // 'cache-control: no-cache' != 'cache-control: no-cache="foo"' 601 // 'cache-control: no-cache' != 'cache-control: no-cache="foo"'
601 void* iter = NULL; 602 void* iter = NULL;
602 std::string temp; 603 std::string temp;
603 while (EnumerateHeader(&iter, name, &temp)) { 604 while (EnumerateHeader(&iter, name, &temp)) {
604 if (value.size() == temp.size() && 605 if (value.size() == temp.size() &&
605 std::equal(temp.begin(), temp.end(), value.begin(), 606 std::equal(temp.begin(), temp.end(), value.begin(),
606 base::CaseInsensitiveCompare<char>())) 607 base::CaseInsensitiveCompareASCII<char>()))
607 return true; 608 return true;
608 } 609 }
609 return false; 610 return false;
610 } 611 }
611 612
612 bool HttpResponseHeaders::HasHeader(const base::StringPiece& name) const { 613 bool HttpResponseHeaders::HasHeader(const base::StringPiece& name) const {
613 return FindHeader(0, name) != std::string::npos; 614 return FindHeader(0, name) != std::string::npos;
614 } 615 }
615 616
616 HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) { 617 HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) {
617 } 618 }
618 619
619 HttpResponseHeaders::~HttpResponseHeaders() { 620 HttpResponseHeaders::~HttpResponseHeaders() {
620 } 621 }
621 622
622 // Note: this implementation implicitly assumes that line_end points at a valid 623 // Note: this implementation implicitly assumes that line_end points at a valid
623 // sentinel character (such as '\0'). 624 // sentinel character (such as '\0').
624 // static 625 // static
625 HttpVersion HttpResponseHeaders::ParseVersion( 626 HttpVersion HttpResponseHeaders::ParseVersion(
626 std::string::const_iterator line_begin, 627 std::string::const_iterator line_begin,
627 std::string::const_iterator line_end) { 628 std::string::const_iterator line_end) {
628 std::string::const_iterator p = line_begin; 629 std::string::const_iterator p = line_begin;
629 630
630 // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT 631 // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
631 // TODO: (1*DIGIT apparently means one or more digits, but we only handle 1). 632 // TODO: (1*DIGIT apparently means one or more digits, but we only handle 1).
632 // TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1. 633 // TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1.
633 634
634 if ((line_end - p < 4) || !LowerCaseEqualsASCII(p, p + 4, "http")) { 635 if ((line_end - p < 4) || !base::LowerCaseEqualsASCII(p, p + 4, "http")) {
635 DVLOG(1) << "missing status line"; 636 DVLOG(1) << "missing status line";
636 return HttpVersion(); 637 return HttpVersion();
637 } 638 }
638 639
639 p += 4; 640 p += 4;
640 641
641 if (p >= line_end || *p != '/') { 642 if (p >= line_end || *p != '/') {
642 DVLOG(1) << "missing version"; 643 DVLOG(1) << "missing version";
643 return HttpVersion(); 644 return HttpVersion();
644 } 645 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 739
739 size_t HttpResponseHeaders::FindHeader(size_t from, 740 size_t HttpResponseHeaders::FindHeader(size_t from,
740 const base::StringPiece& search) const { 741 const base::StringPiece& search) const {
741 for (size_t i = from; i < parsed_.size(); ++i) { 742 for (size_t i = from; i < parsed_.size(); ++i) {
742 if (parsed_[i].is_continuation()) 743 if (parsed_[i].is_continuation())
743 continue; 744 continue;
744 const std::string::const_iterator& name_begin = parsed_[i].name_begin; 745 const std::string::const_iterator& name_begin = parsed_[i].name_begin;
745 const std::string::const_iterator& name_end = parsed_[i].name_end; 746 const std::string::const_iterator& name_end = parsed_[i].name_end;
746 if (static_cast<size_t>(name_end - name_begin) == search.size() && 747 if (static_cast<size_t>(name_end - name_begin) == search.size() &&
747 std::equal(name_begin, name_end, search.begin(), 748 std::equal(name_begin, name_end, search.begin(),
748 base::CaseInsensitiveCompare<char>())) 749 base::CaseInsensitiveCompareASCII<char>()))
749 return i; 750 return i;
750 } 751 }
751 752
752 return std::string::npos; 753 return std::string::npos;
753 } 754 }
754 755
755 bool HttpResponseHeaders::GetCacheControlDirective(const StringPiece& directive, 756 bool HttpResponseHeaders::GetCacheControlDirective(const StringPiece& directive,
756 TimeDelta* result) const { 757 TimeDelta* result) const {
757 StringPiece name("cache-control"); 758 StringPiece name("cache-control");
758 std::string value; 759 std::string value;
759 760
760 size_t directive_size = directive.size(); 761 size_t directive_size = directive.size();
761 762
762 void* iter = NULL; 763 void* iter = NULL;
763 while (EnumerateHeader(&iter, name, &value)) { 764 while (EnumerateHeader(&iter, name, &value)) {
764 if (value.size() > directive_size + 1 && 765 if (value.size() > directive_size + 1 &&
765 LowerCaseEqualsASCII(value.begin(), 766 base::LowerCaseEqualsASCII(
766 value.begin() + directive_size, 767 value.begin(), value.begin() + directive_size, directive.begin()) &&
767 directive.begin()) &&
768 value[directive_size] == '=') { 768 value[directive_size] == '=') {
769 int64 seconds; 769 int64 seconds;
770 base::StringToInt64( 770 base::StringToInt64(
771 StringPiece(value.begin() + directive_size + 1, value.end()), 771 StringPiece(value.begin() + directive_size + 1, value.end()),
772 &seconds); 772 &seconds);
773 *result = TimeDelta::FromSeconds(seconds); 773 *result = TimeDelta::FromSeconds(seconds);
774 return true; 774 return true;
775 } 775 }
776 } 776 }
777 777
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 {"close", false}}; 1224 {"close", false}};
1225 1225
1226 if (http_version_ < HttpVersion(1, 0)) 1226 if (http_version_ < HttpVersion(1, 0))
1227 return false; 1227 return false;
1228 1228
1229 for (const char* header : kConnectionHeaders) { 1229 for (const char* header : kConnectionHeaders) {
1230 void* iterator = nullptr; 1230 void* iterator = nullptr;
1231 std::string token; 1231 std::string token;
1232 while (EnumerateHeader(&iterator, header, &token)) { 1232 while (EnumerateHeader(&iterator, header, &token)) {
1233 for (const KeepAliveToken& keep_alive_token : kKeepAliveTokens) { 1233 for (const KeepAliveToken& keep_alive_token : kKeepAliveTokens) {
1234 if (LowerCaseEqualsASCII(token, keep_alive_token.token)) 1234 if (base::LowerCaseEqualsASCII(token, keep_alive_token.token))
1235 return keep_alive_token.keep_alive; 1235 return keep_alive_token.keep_alive;
1236 } 1236 }
1237 } 1237 }
1238 } 1238 }
1239 return http_version_ != HttpVersion(1, 0); 1239 return http_version_ != HttpVersion(1, 0);
1240 } 1240 }
1241 1241
1242 bool HttpResponseHeaders::HasStrongValidators() const { 1242 bool HttpResponseHeaders::HasStrongValidators() const {
1243 std::string etag_header; 1243 std::string etag_header;
1244 EnumerateHeader(NULL, "etag", &etag_header); 1244 EnumerateHeader(NULL, "etag", &etag_header);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 size_t space_position = content_range_spec.find(' '); 1301 size_t space_position = content_range_spec.find(' ');
1302 if (space_position == std::string::npos) 1302 if (space_position == std::string::npos)
1303 return false; 1303 return false;
1304 1304
1305 // Invalid header if it doesn't contain "bytes-unit". 1305 // Invalid header if it doesn't contain "bytes-unit".
1306 std::string::const_iterator content_range_spec_begin = 1306 std::string::const_iterator content_range_spec_begin =
1307 content_range_spec.begin(); 1307 content_range_spec.begin();
1308 std::string::const_iterator content_range_spec_end = 1308 std::string::const_iterator content_range_spec_end =
1309 content_range_spec.begin() + space_position; 1309 content_range_spec.begin() + space_position;
1310 HttpUtil::TrimLWS(&content_range_spec_begin, &content_range_spec_end); 1310 HttpUtil::TrimLWS(&content_range_spec_begin, &content_range_spec_end);
1311 if (!LowerCaseEqualsASCII(content_range_spec_begin, 1311 if (!base::LowerCaseEqualsASCII(content_range_spec_begin,
1312 content_range_spec_end, 1312 content_range_spec_end, "bytes")) {
1313 "bytes")) {
1314 return false; 1313 return false;
1315 } 1314 }
1316 1315
1317 size_t slash_position = content_range_spec.find('/', space_position + 1); 1316 size_t slash_position = content_range_spec.find('/', space_position + 1);
1318 if (slash_position == std::string::npos) 1317 if (slash_position == std::string::npos)
1319 return false; 1318 return false;
1320 1319
1321 // Obtain the part behind the space and before slash. 1320 // Obtain the part behind the space and before slash.
1322 std::string::const_iterator byte_range_resp_spec_begin = 1321 std::string::const_iterator byte_range_resp_spec_begin =
1323 content_range_spec.begin() + space_position + 1; 1322 content_range_spec.begin() + space_position + 1;
1324 std::string::const_iterator byte_range_resp_spec_end = 1323 std::string::const_iterator byte_range_resp_spec_end =
1325 content_range_spec.begin() + slash_position; 1324 content_range_spec.begin() + slash_position;
1326 HttpUtil::TrimLWS(&byte_range_resp_spec_begin, &byte_range_resp_spec_end); 1325 HttpUtil::TrimLWS(&byte_range_resp_spec_begin, &byte_range_resp_spec_end);
1327 1326
1328 // Parse the byte-range-resp-spec part. 1327 // Parse the byte-range-resp-spec part.
1329 std::string byte_range_resp_spec(byte_range_resp_spec_begin, 1328 std::string byte_range_resp_spec(byte_range_resp_spec_begin,
1330 byte_range_resp_spec_end); 1329 byte_range_resp_spec_end);
1331 // If byte-range-resp-spec != "*". 1330 // If byte-range-resp-spec != "*".
1332 if (!LowerCaseEqualsASCII(byte_range_resp_spec, "*")) { 1331 if (!base::LowerCaseEqualsASCII(byte_range_resp_spec, "*")) {
1333 size_t minus_position = byte_range_resp_spec.find('-'); 1332 size_t minus_position = byte_range_resp_spec.find('-');
1334 if (minus_position != std::string::npos) { 1333 if (minus_position != std::string::npos) {
1335 // Obtain first-byte-pos. 1334 // Obtain first-byte-pos.
1336 std::string::const_iterator first_byte_pos_begin = 1335 std::string::const_iterator first_byte_pos_begin =
1337 byte_range_resp_spec.begin(); 1336 byte_range_resp_spec.begin();
1338 std::string::const_iterator first_byte_pos_end = 1337 std::string::const_iterator first_byte_pos_end =
1339 byte_range_resp_spec.begin() + minus_position; 1338 byte_range_resp_spec.begin() + minus_position;
1340 HttpUtil::TrimLWS(&first_byte_pos_begin, &first_byte_pos_end); 1339 HttpUtil::TrimLWS(&first_byte_pos_begin, &first_byte_pos_end);
1341 1340
1342 bool ok = base::StringToInt64(StringPiece(first_byte_pos_begin, 1341 bool ok = base::StringToInt64(StringPiece(first_byte_pos_begin,
(...skipping 23 matching lines...) Expand all
1366 } 1365 }
1367 1366
1368 // Parse the instance-length part. 1367 // Parse the instance-length part.
1369 // If instance-length == "*". 1368 // If instance-length == "*".
1370 std::string::const_iterator instance_length_begin = 1369 std::string::const_iterator instance_length_begin =
1371 content_range_spec.begin() + slash_position + 1; 1370 content_range_spec.begin() + slash_position + 1;
1372 std::string::const_iterator instance_length_end = 1371 std::string::const_iterator instance_length_end =
1373 content_range_spec.end(); 1372 content_range_spec.end();
1374 HttpUtil::TrimLWS(&instance_length_begin, &instance_length_end); 1373 HttpUtil::TrimLWS(&instance_length_begin, &instance_length_end);
1375 1374
1376 if (LowerCaseEqualsASCII(instance_length_begin, instance_length_end, "*")) { 1375 if (base::LowerCaseEqualsASCII(instance_length_begin, instance_length_end,
1376 "*")) {
1377 return false; 1377 return false;
1378 } else if (!base::StringToInt64(StringPiece(instance_length_begin, 1378 } else if (!base::StringToInt64(StringPiece(instance_length_begin,
1379 instance_length_end), 1379 instance_length_end),
1380 instance_length)) { 1380 instance_length)) {
1381 *instance_length = -1; 1381 *instance_length = -1;
1382 return false; 1382 return false;
1383 } 1383 }
1384 1384
1385 // We have all the values; let's verify that they make sense for a 206 1385 // We have all the values; let's verify that they make sense for a 206
1386 // response. 1386 // response.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 return true; 1444 return true;
1445 } 1445 }
1446 1446
1447 bool HttpResponseHeaders::IsChunkEncoded() const { 1447 bool HttpResponseHeaders::IsChunkEncoded() const {
1448 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. 1448 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies.
1449 return GetHttpVersion() >= HttpVersion(1, 1) && 1449 return GetHttpVersion() >= HttpVersion(1, 1) &&
1450 HasHeaderValue("Transfer-Encoding", "chunked"); 1450 HasHeaderValue("Transfer-Encoding", "chunked");
1451 } 1451 }
1452 1452
1453 } // namespace net 1453 } // namespace net
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