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 // 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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 const std::string::const_iterator& name_end = parsed_[i].name_end; | 746 const std::string::const_iterator& name_end = parsed_[i].name_end; |
747 if (static_cast<size_t>(name_end - name_begin) == search.size() && | 747 if (static_cast<size_t>(name_end - name_begin) == search.size() && |
748 std::equal(name_begin, name_end, search.begin(), | 748 std::equal(name_begin, name_end, search.begin(), |
749 base::CaseInsensitiveCompare<char>())) | 749 base::CaseInsensitiveCompare<char>())) |
750 return i; | 750 return i; |
751 } | 751 } |
752 | 752 |
753 return std::string::npos; | 753 return std::string::npos; |
754 } | 754 } |
755 | 755 |
756 bool HttpResponseHeaders::GetCacheControlDirective(const StringPiece& directive, | |
rvargas (doing something else)
2014/07/29 19:21:22
wow, methods are quite out of order in this file :
Adam Rice
2014/07/30 02:00:59
Yes. I probably just made work for you by moving t
| |
757 TimeDelta* result) const { | |
758 StringPiece name("cache-control"); | |
759 std::string value; | |
760 | |
761 const size_t directive_size = directive.size(); | |
762 | |
763 void* iter = NULL; | |
764 while (EnumerateHeader(&iter, name, &value)) { | |
765 if (value.size() > directive_size + 1 && | |
766 LowerCaseEqualsASCII(value.begin(), | |
767 value.begin() + directive_size, | |
768 directive.begin()) && | |
769 value[directive_size] == '=') { | |
770 int64 seconds; | |
771 base::StringToInt64( | |
772 StringPiece(value.begin() + directive_size + 1, value.end()), | |
773 &seconds); | |
774 *result = TimeDelta::FromSeconds(seconds); | |
775 return true; | |
776 } | |
777 } | |
778 | |
779 return false; | |
780 } | |
781 | |
756 void HttpResponseHeaders::AddHeader(std::string::const_iterator name_begin, | 782 void HttpResponseHeaders::AddHeader(std::string::const_iterator name_begin, |
757 std::string::const_iterator name_end, | 783 std::string::const_iterator name_end, |
758 std::string::const_iterator values_begin, | 784 std::string::const_iterator values_begin, |
759 std::string::const_iterator values_end) { | 785 std::string::const_iterator values_end) { |
760 // If the header can be coalesced, then we should split it up. | 786 // If the header can be coalesced, then we should split it up. |
761 if (values_begin == values_end || | 787 if (values_begin == values_end || |
762 HttpUtil::IsNonCoalescingHeader(name_begin, name_end)) { | 788 HttpUtil::IsNonCoalescingHeader(name_begin, name_end)) { |
763 AddToParsed(name_begin, name_end, values_begin, values_end); | 789 AddToParsed(name_begin, name_end, values_begin, values_end); |
764 } else { | 790 } else { |
765 HttpUtil::ValuesIterator it(values_begin, values_end, ','); | 791 HttpUtil::ValuesIterator it(values_begin, values_end, ','); |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1085 TimeDelta corrected_received_age = std::max(apparent_age, age_value); | 1111 TimeDelta corrected_received_age = std::max(apparent_age, age_value); |
1086 TimeDelta response_delay = response_time - request_time; | 1112 TimeDelta response_delay = response_time - request_time; |
1087 TimeDelta corrected_initial_age = corrected_received_age + response_delay; | 1113 TimeDelta corrected_initial_age = corrected_received_age + response_delay; |
1088 TimeDelta resident_time = current_time - response_time; | 1114 TimeDelta resident_time = current_time - response_time; |
1089 TimeDelta current_age = corrected_initial_age + resident_time; | 1115 TimeDelta current_age = corrected_initial_age + resident_time; |
1090 | 1116 |
1091 return current_age; | 1117 return current_age; |
1092 } | 1118 } |
1093 | 1119 |
1094 bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const { | 1120 bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const { |
1095 std::string name = "cache-control"; | 1121 return GetCacheControlDirective("max-age", result); |
1096 std::string value; | |
1097 | |
1098 const char kMaxAgePrefix[] = "max-age="; | |
1099 const size_t kMaxAgePrefixLen = arraysize(kMaxAgePrefix) - 1; | |
1100 | |
1101 void* iter = NULL; | |
1102 while (EnumerateHeader(&iter, name, &value)) { | |
1103 if (value.size() > kMaxAgePrefixLen) { | |
1104 if (LowerCaseEqualsASCII(value.begin(), | |
1105 value.begin() + kMaxAgePrefixLen, | |
1106 kMaxAgePrefix)) { | |
1107 int64 seconds; | |
1108 base::StringToInt64(StringPiece(value.begin() + kMaxAgePrefixLen, | |
1109 value.end()), | |
1110 &seconds); | |
1111 *result = TimeDelta::FromSeconds(seconds); | |
1112 return true; | |
1113 } | |
1114 } | |
1115 } | |
1116 | |
1117 return false; | |
1118 } | 1122 } |
1119 | 1123 |
1120 bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const { | 1124 bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const { |
1121 std::string value; | 1125 std::string value; |
1122 if (!EnumerateHeader(NULL, "Age", &value)) | 1126 if (!EnumerateHeader(NULL, "Age", &value)) |
1123 return false; | 1127 return false; |
1124 | 1128 |
1125 int64 seconds; | 1129 int64 seconds; |
1126 base::StringToInt64(value, &seconds); | 1130 base::StringToInt64(value, &seconds); |
1127 *result = TimeDelta::FromSeconds(seconds); | 1131 *result = TimeDelta::FromSeconds(seconds); |
1128 return true; | 1132 return true; |
1129 } | 1133 } |
1130 | 1134 |
1131 bool HttpResponseHeaders::GetDateValue(Time* result) const { | 1135 bool HttpResponseHeaders::GetDateValue(Time* result) const { |
1132 return GetTimeValuedHeader("Date", result); | 1136 return GetTimeValuedHeader("Date", result); |
1133 } | 1137 } |
1134 | 1138 |
1135 bool HttpResponseHeaders::GetLastModifiedValue(Time* result) const { | 1139 bool HttpResponseHeaders::GetLastModifiedValue(Time* result) const { |
1136 return GetTimeValuedHeader("Last-Modified", result); | 1140 return GetTimeValuedHeader("Last-Modified", result); |
1137 } | 1141 } |
1138 | 1142 |
1139 bool HttpResponseHeaders::GetExpiresValue(Time* result) const { | 1143 bool HttpResponseHeaders::GetExpiresValue(Time* result) const { |
1140 return GetTimeValuedHeader("Expires", result); | 1144 return GetTimeValuedHeader("Expires", result); |
1141 } | 1145 } |
1142 | 1146 |
1147 bool HttpResponseHeaders::GetStaleWhileRevalidateValue( | |
1148 TimeDelta* result) const { | |
1149 return GetCacheControlDirective("stale-while-revalidate", result); | |
1150 } | |
1151 | |
1143 bool HttpResponseHeaders::GetTimeValuedHeader(const std::string& name, | 1152 bool HttpResponseHeaders::GetTimeValuedHeader(const std::string& name, |
1144 Time* result) const { | 1153 Time* result) const { |
1145 std::string value; | 1154 std::string value; |
1146 if (!EnumerateHeader(NULL, name, &value)) | 1155 if (!EnumerateHeader(NULL, name, &value)) |
1147 return false; | 1156 return false; |
1148 | 1157 |
1149 // When parsing HTTP dates it's beneficial to default to GMT because: | 1158 // When parsing HTTP dates it's beneficial to default to GMT because: |
1150 // 1. RFC2616 3.3.1 says times should always be specified in GMT | 1159 // 1. RFC2616 3.3.1 says times should always be specified in GMT |
1151 // 2. Only counter-example incorrectly appended "UTC" (crbug.com/153759) | 1160 // 2. Only counter-example incorrectly appended "UTC" (crbug.com/153759) |
1152 // 3. When adjusting cookie expiration times for clock skew | 1161 // 3. When adjusting cookie expiration times for clock skew |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1385 return true; | 1394 return true; |
1386 } | 1395 } |
1387 | 1396 |
1388 bool HttpResponseHeaders::IsChunkEncoded() const { | 1397 bool HttpResponseHeaders::IsChunkEncoded() const { |
1389 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. | 1398 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. |
1390 return GetHttpVersion() >= HttpVersion(1, 1) && | 1399 return GetHttpVersion() >= HttpVersion(1, 1) && |
1391 HasHeaderValue("Transfer-Encoding", "chunked"); | 1400 HasHeaderValue("Transfer-Encoding", "chunked"); |
1392 } | 1401 } |
1393 | 1402 |
1394 } // namespace net | 1403 } // namespace net |
OLD | NEW |