OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 HeaderSet empty_to_remove; | 322 HeaderSet empty_to_remove; |
323 MergeWithHeaders(new_raw_headers, empty_to_remove); | 323 MergeWithHeaders(new_raw_headers, empty_to_remove); |
324 } | 324 } |
325 | 325 |
326 void HttpResponseHeaders::Parse(const std::string& raw_input) { | 326 void HttpResponseHeaders::Parse(const std::string& raw_input) { |
327 raw_headers_.reserve(raw_input.size()); | 327 raw_headers_.reserve(raw_input.size()); |
328 | 328 |
329 // ParseStatusLine adds a normalized status line to raw_headers_ | 329 // ParseStatusLine adds a normalized status line to raw_headers_ |
330 std::string::const_iterator line_begin = raw_input.begin(); | 330 std::string::const_iterator line_begin = raw_input.begin(); |
331 std::string::const_iterator line_end = | 331 std::string::const_iterator line_end = |
332 find(line_begin, raw_input.end(), '\0'); | 332 std::find(line_begin, raw_input.end(), '\0'); |
333 // has_headers = true, if there is any data following the status line. | 333 // has_headers = true, if there is any data following the status line. |
334 // Used by ParseStatusLine() to decide if a HTTP/0.9 is really a HTTP/1.0. | 334 // Used by ParseStatusLine() to decide if a HTTP/0.9 is really a HTTP/1.0. |
335 bool has_headers = (line_end != raw_input.end() && | 335 bool has_headers = (line_end != raw_input.end() && |
336 (line_end + 1) != raw_input.end() && | 336 (line_end + 1) != raw_input.end() && |
337 *(line_end + 1) != '\0'); | 337 *(line_end + 1) != '\0'); |
338 ParseStatusLine(line_begin, line_end, has_headers); | 338 ParseStatusLine(line_begin, line_end, has_headers); |
339 | 339 |
340 if (line_end == raw_input.end()) { | 340 if (line_end == raw_input.end()) { |
341 raw_headers_.push_back('\0'); | 341 raw_headers_.push_back('\0'); |
342 return; | 342 return; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 return std::string(raw_headers_.c_str()); | 450 return std::string(raw_headers_.c_str()); |
451 } | 451 } |
452 | 452 |
453 std::string HttpResponseHeaders::GetStatusText() const { | 453 std::string HttpResponseHeaders::GetStatusText() const { |
454 // GetStatusLine() is already normalized, so it has the format: | 454 // GetStatusLine() is already normalized, so it has the format: |
455 // <http_version> SP <response_code> SP <status_text> | 455 // <http_version> SP <response_code> SP <status_text> |
456 std::string status_text = GetStatusLine(); | 456 std::string status_text = GetStatusLine(); |
457 std::string::const_iterator begin = status_text.begin(); | 457 std::string::const_iterator begin = status_text.begin(); |
458 std::string::const_iterator end = status_text.end(); | 458 std::string::const_iterator end = status_text.end(); |
459 for (int i = 0; i < 2; ++i) | 459 for (int i = 0; i < 2; ++i) |
460 begin = find(begin, end, ' ') + 1; | 460 begin = std::find(begin, end, ' ') + 1; |
461 return std::string(begin, end); | 461 return std::string(begin, end); |
462 } | 462 } |
463 | 463 |
464 bool HttpResponseHeaders::EnumerateHeaderLines(void** iter, | 464 bool HttpResponseHeaders::EnumerateHeaderLines(void** iter, |
465 std::string* name, | 465 std::string* name, |
466 std::string* value) const { | 466 std::string* value) const { |
467 size_t i = reinterpret_cast<size_t>(*iter); | 467 size_t i = reinterpret_cast<size_t>(*iter); |
468 if (i == parsed_.size()) | 468 if (i == parsed_.size()) |
469 return false; | 469 return false; |
470 | 470 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 return HttpVersion(); | 550 return HttpVersion(); |
551 } | 551 } |
552 | 552 |
553 p += 4; | 553 p += 4; |
554 | 554 |
555 if (p >= line_end || *p != '/') { | 555 if (p >= line_end || *p != '/') { |
556 DVLOG(1) << "missing version"; | 556 DVLOG(1) << "missing version"; |
557 return HttpVersion(); | 557 return HttpVersion(); |
558 } | 558 } |
559 | 559 |
560 std::string::const_iterator dot = find(p, line_end, '.'); | 560 std::string::const_iterator dot = std::find(p, line_end, '.'); |
561 if (dot == line_end) { | 561 if (dot == line_end) { |
562 DVLOG(1) << "malformed version"; | 562 DVLOG(1) << "malformed version"; |
563 return HttpVersion(); | 563 return HttpVersion(); |
564 } | 564 } |
565 | 565 |
566 ++p; // from / to first digit. | 566 ++p; // from / to first digit. |
567 ++dot; // from . to second digit. | 567 ++dot; // from . to second digit. |
568 | 568 |
569 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { | 569 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { |
570 DVLOG(1) << "malformed version number"; | 570 DVLOG(1) << "malformed version number"; |
(...skipping 26 matching lines...) Expand all Loading... |
597 // Treat everything else like HTTP 1.0 | 597 // Treat everything else like HTTP 1.0 |
598 http_version_ = HttpVersion(1, 0); | 598 http_version_ = HttpVersion(1, 0); |
599 raw_headers_ = "HTTP/1.0"; | 599 raw_headers_ = "HTTP/1.0"; |
600 } | 600 } |
601 if (parsed_http_version_ != http_version_) { | 601 if (parsed_http_version_ != http_version_) { |
602 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." | 602 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." |
603 << http_version_.minor_value(); | 603 << http_version_.minor_value(); |
604 } | 604 } |
605 | 605 |
606 // TODO(eroman): this doesn't make sense if ParseVersion failed. | 606 // TODO(eroman): this doesn't make sense if ParseVersion failed. |
607 std::string::const_iterator p = find(line_begin, line_end, ' '); | 607 std::string::const_iterator p = std::find(line_begin, line_end, ' '); |
608 | 608 |
609 if (p == line_end) { | 609 if (p == line_end) { |
610 DVLOG(1) << "missing response status; assuming 200 OK"; | 610 DVLOG(1) << "missing response status; assuming 200 OK"; |
611 raw_headers_.append(" 200 OK"); | 611 raw_headers_.append(" 200 OK"); |
612 raw_headers_.push_back('\0'); | 612 raw_headers_.push_back('\0'); |
613 response_code_ = 200; | 613 response_code_ = 200; |
614 return; | 614 return; |
615 } | 615 } |
616 | 616 |
617 // Skip whitespace. | 617 // Skip whitespace. |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 // We have all the values; let's verify that they make sense for a 206 | 1232 // We have all the values; let's verify that they make sense for a 206 |
1233 // response. | 1233 // response. |
1234 if (*first_byte_position < 0 || *last_byte_position < 0 || | 1234 if (*first_byte_position < 0 || *last_byte_position < 0 || |
1235 *instance_length < 0 || *instance_length - 1 < *last_byte_position) | 1235 *instance_length < 0 || *instance_length - 1 < *last_byte_position) |
1236 return false; | 1236 return false; |
1237 | 1237 |
1238 return true; | 1238 return true; |
1239 } | 1239 } |
1240 | 1240 |
1241 } // namespace net | 1241 } // namespace net |
OLD | NEW |