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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 HttpResponseHeaders::HttpResponseHeaders(base::PickleIterator* iter) | 161 HttpResponseHeaders::HttpResponseHeaders(base::PickleIterator* iter) |
162 : response_code_(-1) { | 162 : response_code_(-1) { |
163 std::string raw_input; | 163 std::string raw_input; |
164 if (iter->ReadString(&raw_input)) | 164 if (iter->ReadString(&raw_input)) |
165 Parse(raw_input); | 165 Parse(raw_input); |
166 } | 166 } |
167 | 167 |
168 void HttpResponseHeaders::Persist(base::Pickle* pickle, | 168 void HttpResponseHeaders::Persist(base::Pickle* pickle, |
169 PersistOptions options) { | 169 PersistOptions options) { |
170 if (options == PERSIST_RAW) { | 170 if (options == PERSIST_RAW) { |
| 171 // To avoid unnecessary copy, we don't call PersistTo here. |
171 pickle->WriteString(raw_headers_); | 172 pickle->WriteString(raw_headers_); |
172 return; // Done. | 173 return; // Done. |
173 } | 174 } |
| 175 std::string blob; |
| 176 PersistTo(options, &blob); |
| 177 pickle->WriteString(blob); |
| 178 } |
| 179 |
| 180 void HttpResponseHeaders::PersistTo(PersistOptions options, |
| 181 std::string* output) { |
| 182 if (options == PERSIST_RAW) { |
| 183 *output = raw_headers_; |
| 184 return; // Done. |
| 185 } |
174 | 186 |
175 HeaderSet filter_headers; | 187 HeaderSet filter_headers; |
176 | 188 |
177 // Construct set of headers to filter out based on options. | 189 // Construct set of headers to filter out based on options. |
178 if ((options & PERSIST_SANS_NON_CACHEABLE) == PERSIST_SANS_NON_CACHEABLE) | 190 if ((options & PERSIST_SANS_NON_CACHEABLE) == PERSIST_SANS_NON_CACHEABLE) |
179 AddNonCacheableHeaders(&filter_headers); | 191 AddNonCacheableHeaders(&filter_headers); |
180 | 192 |
181 if ((options & PERSIST_SANS_COOKIES) == PERSIST_SANS_COOKIES) | 193 if ((options & PERSIST_SANS_COOKIES) == PERSIST_SANS_COOKIES) |
182 AddCookieHeaders(&filter_headers); | 194 AddCookieHeaders(&filter_headers); |
183 | 195 |
184 if ((options & PERSIST_SANS_CHALLENGES) == PERSIST_SANS_CHALLENGES) | 196 if ((options & PERSIST_SANS_CHALLENGES) == PERSIST_SANS_CHALLENGES) |
185 AddChallengeHeaders(&filter_headers); | 197 AddChallengeHeaders(&filter_headers); |
186 | 198 |
187 if ((options & PERSIST_SANS_HOP_BY_HOP) == PERSIST_SANS_HOP_BY_HOP) | 199 if ((options & PERSIST_SANS_HOP_BY_HOP) == PERSIST_SANS_HOP_BY_HOP) |
188 AddHopByHopHeaders(&filter_headers); | 200 AddHopByHopHeaders(&filter_headers); |
189 | 201 |
190 if ((options & PERSIST_SANS_RANGES) == PERSIST_SANS_RANGES) | 202 if ((options & PERSIST_SANS_RANGES) == PERSIST_SANS_RANGES) |
191 AddHopContentRangeHeaders(&filter_headers); | 203 AddHopContentRangeHeaders(&filter_headers); |
192 | 204 |
193 if ((options & PERSIST_SANS_SECURITY_STATE) == PERSIST_SANS_SECURITY_STATE) | 205 if ((options & PERSIST_SANS_SECURITY_STATE) == PERSIST_SANS_SECURITY_STATE) |
194 AddSecurityStateHeaders(&filter_headers); | 206 AddSecurityStateHeaders(&filter_headers); |
195 | 207 |
196 std::string blob; | 208 output->clear(); |
197 blob.reserve(raw_headers_.size()); | 209 output->reserve(raw_headers_.size()); |
198 | 210 |
199 // This copies the status line w/ terminator null. | 211 // This copies the status line w/ terminator null. |
200 // Note raw_headers_ has embedded nulls instead of \n, | 212 // Note raw_headers_ has embedded nulls instead of \n, |
201 // so this just copies the first header line. | 213 // so this just copies the first header line. |
202 blob.assign(raw_headers_.c_str(), strlen(raw_headers_.c_str()) + 1); | 214 output->assign(raw_headers_.c_str(), strlen(raw_headers_.c_str()) + 1); |
203 | 215 |
204 for (size_t i = 0; i < parsed_.size(); ++i) { | 216 for (size_t i = 0; i < parsed_.size(); ++i) { |
205 DCHECK(!parsed_[i].is_continuation()); | 217 DCHECK(!parsed_[i].is_continuation()); |
206 | 218 |
207 // Locate the start of the next header. | 219 // Locate the start of the next header. |
208 size_t k = i; | 220 size_t k = i; |
209 while (++k < parsed_.size() && parsed_[k].is_continuation()) {} | 221 while (++k < parsed_.size() && parsed_[k].is_continuation()) {} |
210 --k; | 222 --k; |
211 | 223 |
212 std::string header_name = base::ToLowerASCII( | 224 std::string header_name = base::ToLowerASCII( |
213 base::StringPiece(parsed_[i].name_begin, parsed_[i].name_end)); | 225 base::StringPiece(parsed_[i].name_begin, parsed_[i].name_end)); |
214 if (filter_headers.find(header_name) == filter_headers.end()) { | 226 if (filter_headers.find(header_name) == filter_headers.end()) { |
215 // Make sure there is a null after the value. | 227 // Make sure there is a null after the value. |
216 blob.append(parsed_[i].name_begin, parsed_[k].value_end); | 228 output->append(parsed_[i].name_begin, parsed_[k].value_end); |
217 blob.push_back('\0'); | 229 output->push_back('\0'); |
218 } | 230 } |
219 | 231 |
220 i = k; | 232 i = k; |
221 } | 233 } |
222 blob.push_back('\0'); | 234 output->push_back('\0'); |
223 | |
224 pickle->WriteString(blob); | |
225 } | 235 } |
226 | 236 |
227 void HttpResponseHeaders::Update(const HttpResponseHeaders& new_headers) { | 237 void HttpResponseHeaders::Update(const HttpResponseHeaders& new_headers) { |
228 DCHECK(new_headers.response_code() == 304 || | 238 DCHECK(new_headers.response_code() == 304 || |
229 new_headers.response_code() == 206); | 239 new_headers.response_code() == 206); |
230 | 240 |
231 // Copy up to the null byte. This just copies the status line. | 241 // Copy up to the null byte. This just copies the status line. |
232 std::string new_raw_headers(raw_headers_.c_str()); | 242 std::string new_raw_headers(raw_headers_.c_str()); |
233 new_raw_headers.push_back('\0'); | 243 new_raw_headers.push_back('\0'); |
234 | 244 |
(...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 return true; | 1475 return true; |
1466 } | 1476 } |
1467 | 1477 |
1468 bool HttpResponseHeaders::IsChunkEncoded() const { | 1478 bool HttpResponseHeaders::IsChunkEncoded() const { |
1469 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. | 1479 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. |
1470 return GetHttpVersion() >= HttpVersion(1, 1) && | 1480 return GetHttpVersion() >= HttpVersion(1, 1) && |
1471 HasHeaderValue("Transfer-Encoding", "chunked"); | 1481 HasHeaderValue("Transfer-Encoding", "chunked"); |
1472 } | 1482 } |
1473 | 1483 |
1474 } // namespace net | 1484 } // namespace net |
OLD | NEW |