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 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1085 TimeDelta corrected_received_age = std::max(apparent_age, age_value); | 1085 TimeDelta corrected_received_age = std::max(apparent_age, age_value); |
1086 TimeDelta response_delay = response_time - request_time; | 1086 TimeDelta response_delay = response_time - request_time; |
1087 TimeDelta corrected_initial_age = corrected_received_age + response_delay; | 1087 TimeDelta corrected_initial_age = corrected_received_age + response_delay; |
1088 TimeDelta resident_time = current_time - response_time; | 1088 TimeDelta resident_time = current_time - response_time; |
1089 TimeDelta current_age = corrected_initial_age + resident_time; | 1089 TimeDelta current_age = corrected_initial_age + resident_time; |
1090 | 1090 |
1091 return current_age; | 1091 return current_age; |
1092 } | 1092 } |
1093 | 1093 |
1094 bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const { | 1094 bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const { |
1095 std::string name = "cache-control"; | 1095 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 } | 1096 } |
1119 | 1097 |
1120 bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const { | 1098 bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const { |
1121 std::string value; | 1099 std::string value; |
1122 if (!EnumerateHeader(NULL, "Age", &value)) | 1100 if (!EnumerateHeader(NULL, "Age", &value)) |
1123 return false; | 1101 return false; |
1124 | 1102 |
1125 int64 seconds; | 1103 int64 seconds; |
1126 base::StringToInt64(value, &seconds); | 1104 base::StringToInt64(value, &seconds); |
1127 *result = TimeDelta::FromSeconds(seconds); | 1105 *result = TimeDelta::FromSeconds(seconds); |
1128 return true; | 1106 return true; |
1129 } | 1107 } |
1130 | 1108 |
1131 bool HttpResponseHeaders::GetDateValue(Time* result) const { | 1109 bool HttpResponseHeaders::GetDateValue(Time* result) const { |
1132 return GetTimeValuedHeader("Date", result); | 1110 return GetTimeValuedHeader("Date", result); |
1133 } | 1111 } |
1134 | 1112 |
1135 bool HttpResponseHeaders::GetLastModifiedValue(Time* result) const { | 1113 bool HttpResponseHeaders::GetLastModifiedValue(Time* result) const { |
1136 return GetTimeValuedHeader("Last-Modified", result); | 1114 return GetTimeValuedHeader("Last-Modified", result); |
1137 } | 1115 } |
1138 | 1116 |
1139 bool HttpResponseHeaders::GetExpiresValue(Time* result) const { | 1117 bool HttpResponseHeaders::GetExpiresValue(Time* result) const { |
1140 return GetTimeValuedHeader("Expires", result); | 1118 return GetTimeValuedHeader("Expires", result); |
1141 } | 1119 } |
1142 | 1120 |
1121 bool HttpResponseHeaders::GetStaleWhileRevalidateValue( | |
rvargas (doing something else)
2014/07/28 19:24:00
Please add HttpResponseHeaders unit tests to make
Adam Rice
2014/07/29 17:04:45
Done. I didn't add as many tests as for max-age as
rvargas (doing something else)
2014/07/29 19:21:22
The tests look great, thanks.
| |
1122 TimeDelta* result) const { | |
1123 return GetCacheControlDirective("stale-while-revalidate", result); | |
1124 } | |
1125 | |
1126 bool HttpResponseHeaders::GetCacheControlDirective(const StringPiece& directive, | |
1127 TimeDelta* result) const { | |
1128 StringPiece name("cache-control"); | |
1129 std::string value; | |
1130 | |
1131 const size_t directive_size = directive.size(); | |
rvargas (doing something else)
2014/07/28 19:24:00
nit: no const
Adam Rice
2014/07/29 17:04:45
May I ask why? const clarifies for the reader that
rvargas (doing something else)
2014/07/29 19:21:22
To me it goes with the overall spirit of not going
Adam Rice
2014/07/30 02:00:59
Okay, you're the owner so I took it out. For me, a
| |
1132 | |
1133 void* iter = NULL; | |
1134 while (EnumerateHeader(&iter, name, &value)) { | |
1135 if (value.size() > directive_size + 1 && | |
rvargas (doing something else)
2014/07/28 19:24:01
This '+ 1' is a slight change from the previous co
Adam Rice
2014/07/29 17:04:45
I added unit tests for GetMaxAgeValue() and verifi
| |
1136 LowerCaseEqualsASCII(value.begin(), | |
1137 value.begin() + directive_size, | |
1138 directive.begin()) && | |
1139 value[directive_size] == '=') { | |
1140 int64 seconds; | |
1141 base::StringToInt64( | |
1142 StringPiece(value.begin() + directive_size + 1, value.end()), | |
1143 &seconds); | |
1144 *result = TimeDelta::FromSeconds(seconds); | |
1145 return true; | |
1146 } | |
1147 } | |
1148 | |
1149 return false; | |
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 |