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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 i = k; | 304 i = k; |
305 } | 305 } |
306 new_raw_headers.push_back('\0'); | 306 new_raw_headers.push_back('\0'); |
307 | 307 |
308 // Make this object hold the new data. | 308 // Make this object hold the new data. |
309 raw_headers_.clear(); | 309 raw_headers_.clear(); |
310 parsed_.clear(); | 310 parsed_.clear(); |
311 Parse(new_raw_headers); | 311 Parse(new_raw_headers); |
312 } | 312 } |
313 | 313 |
314 void HttpResponseHeaders::MergeWithHeadersWithValue( | |
315 const std::string& raw_headers, | |
316 const std::string& header_to_remove_name, | |
317 const std::string& header_to_remove_value) { | |
318 std::string header_to_remove_name_lowercase(header_to_remove_name); | |
319 StringToLowerASCII(&header_to_remove_name_lowercase); | |
320 | |
321 std::string new_raw_headers(raw_headers); | |
322 for (size_t i = 0; i < parsed_.size(); ++i) { | |
323 DCHECK(!parsed_[i].is_continuation()); | |
324 | |
325 // Locate the start of the next header. | |
326 size_t k = i; | |
327 while (++k < parsed_.size() && parsed_[k].is_continuation()) {} | |
328 --k; | |
329 | |
330 std::string name(parsed_[i].name_begin, parsed_[i].name_end); | |
331 StringToLowerASCII(&name); | |
332 std::string value(parsed_[i].value_begin, parsed_[i].value_end); | |
333 if (name != header_to_remove_name_lowercase || | |
334 value != header_to_remove_value) { | |
335 // It's ok to preserve this header in the final result. | |
336 new_raw_headers.append(parsed_[i].name_begin, parsed_[k].value_end); | |
337 new_raw_headers.push_back('\0'); | |
338 } | |
339 | |
340 i = k; | |
341 } | |
342 new_raw_headers.push_back('\0'); | |
343 | |
344 // Make this object hold the new data. | |
345 raw_headers_.clear(); | |
346 parsed_.clear(); | |
347 Parse(new_raw_headers); | |
348 } | |
349 | |
350 void HttpResponseHeaders::RemoveHeader(const std::string& name) { | 314 void HttpResponseHeaders::RemoveHeader(const std::string& name) { |
351 // Copy up to the null byte. This just copies the status line. | 315 // Copy up to the null byte. This just copies the status line. |
352 std::string new_raw_headers(raw_headers_.c_str()); | 316 std::string new_raw_headers(raw_headers_.c_str()); |
353 new_raw_headers.push_back('\0'); | 317 new_raw_headers.push_back('\0'); |
354 | 318 |
355 std::string lowercase_name(name); | 319 std::string lowercase_name(name); |
356 StringToLowerASCII(&lowercase_name); | 320 StringToLowerASCII(&lowercase_name); |
357 HeaderSet to_remove; | 321 HeaderSet to_remove; |
358 to_remove.insert(lowercase_name); | 322 to_remove.insert(lowercase_name); |
359 MergeWithHeaders(new_raw_headers, to_remove); | 323 MergeWithHeaders(new_raw_headers, to_remove); |
360 } | 324 } |
361 | 325 |
362 void HttpResponseHeaders::RemoveHeaderWithValue(const std::string& name, | 326 void HttpResponseHeaders::RemoveHeaderLine(const std::string& name, |
363 const std::string& value) { | 327 const std::string& value) { |
364 // Copy up to the null byte. This just copies the status line. | 328 std::string name_lowercase(name); |
365 std::string new_raw_headers(raw_headers_.c_str()); | 329 StringToLowerASCII(&name_lowercase); |
| 330 |
| 331 std::string new_raw_headers(GetStatusLine()); |
366 new_raw_headers.push_back('\0'); | 332 new_raw_headers.push_back('\0'); |
367 | 333 |
368 MergeWithHeadersWithValue(new_raw_headers, name, value); | 334 new_raw_headers.reserve(raw_headers_.size()); |
| 335 |
| 336 void* iter = NULL; |
| 337 std::string old_header_name; |
| 338 std::string old_header_value; |
| 339 while (EnumerateHeaderLines(&iter, &old_header_name, &old_header_value)) { |
| 340 std::string old_header_name_lowercase(name); |
| 341 StringToLowerASCII(&old_header_name_lowercase); |
| 342 |
| 343 if (name_lowercase == old_header_name_lowercase && |
| 344 value == old_header_value) |
| 345 continue; |
| 346 |
| 347 new_raw_headers.append(old_header_name); |
| 348 new_raw_headers.push_back(':'); |
| 349 new_raw_headers.push_back(' '); |
| 350 new_raw_headers.append(old_header_value); |
| 351 new_raw_headers.push_back('\0'); |
| 352 } |
| 353 new_raw_headers.push_back('\0'); |
| 354 |
| 355 // Make this object hold the new data. |
| 356 raw_headers_.clear(); |
| 357 parsed_.clear(); |
| 358 Parse(new_raw_headers); |
369 } | 359 } |
370 | 360 |
371 void HttpResponseHeaders::AddHeader(const std::string& header) { | 361 void HttpResponseHeaders::AddHeader(const std::string& header) { |
372 CheckDoesNotHaveEmbededNulls(header); | 362 CheckDoesNotHaveEmbededNulls(header); |
373 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 2]); | 363 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 2]); |
374 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]); | 364 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]); |
375 // Don't copy the last null. | 365 // Don't copy the last null. |
376 std::string new_raw_headers(raw_headers_, 0, raw_headers_.size() - 1); | 366 std::string new_raw_headers(raw_headers_, 0, raw_headers_.size() - 1); |
377 new_raw_headers.append(header); | 367 new_raw_headers.append(header); |
378 new_raw_headers.push_back('\0'); | 368 new_raw_headers.push_back('\0'); |
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 return true; | 1347 return true; |
1358 } | 1348 } |
1359 | 1349 |
1360 bool HttpResponseHeaders::IsChunkEncoded() const { | 1350 bool HttpResponseHeaders::IsChunkEncoded() const { |
1361 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. | 1351 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. |
1362 return GetHttpVersion() >= HttpVersion(1, 1) && | 1352 return GetHttpVersion() >= HttpVersion(1, 1) && |
1363 HasHeaderValue("Transfer-Encoding", "chunked"); | 1353 HasHeaderValue("Transfer-Encoding", "chunked"); |
1364 } | 1354 } |
1365 | 1355 |
1366 } // namespace net | 1356 } // namespace net |
OLD | NEW |