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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 109 |
110 int MapHttpResponseCode(int code) { | 110 int MapHttpResponseCode(int code) { |
111 if (HISTOGRAM_MIN_HTTP_RESPONSE_CODE <= code && | 111 if (HISTOGRAM_MIN_HTTP_RESPONSE_CODE <= code && |
112 code <= HISTOGRAM_MAX_HTTP_RESPONSE_CODE) | 112 code <= HISTOGRAM_MAX_HTTP_RESPONSE_CODE) |
113 return code; | 113 return code; |
114 return 0; | 114 return 0; |
115 } | 115 } |
116 | 116 |
117 } // namespace | 117 } // namespace |
118 | 118 |
| 119 const char HttpResponseHeaders::kXAutoLogin[] = "X-Auto-Login"; |
| 120 |
119 struct HttpResponseHeaders::ParsedHeader { | 121 struct HttpResponseHeaders::ParsedHeader { |
120 // A header "continuation" contains only a subsequent value for the | 122 // A header "continuation" contains only a subsequent value for the |
121 // preceding header. (Header values are comma separated.) | 123 // preceding header. (Header values are comma separated.) |
122 bool is_continuation() const { return name_begin == name_end; } | 124 bool is_continuation() const { return name_begin == name_end; } |
123 | 125 |
124 std::string::const_iterator name_begin; | 126 std::string::const_iterator name_begin; |
125 std::string::const_iterator name_end; | 127 std::string::const_iterator name_end; |
126 std::string::const_iterator value_begin; | 128 std::string::const_iterator value_begin; |
127 std::string::const_iterator value_end; | 129 std::string::const_iterator value_end; |
128 }; | 130 }; |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 HeaderSet empty_to_remove; | 324 HeaderSet empty_to_remove; |
323 MergeWithHeaders(new_raw_headers, empty_to_remove); | 325 MergeWithHeaders(new_raw_headers, empty_to_remove); |
324 } | 326 } |
325 | 327 |
326 void HttpResponseHeaders::Parse(const std::string& raw_input) { | 328 void HttpResponseHeaders::Parse(const std::string& raw_input) { |
327 raw_headers_.reserve(raw_input.size()); | 329 raw_headers_.reserve(raw_input.size()); |
328 | 330 |
329 // ParseStatusLine adds a normalized status line to raw_headers_ | 331 // ParseStatusLine adds a normalized status line to raw_headers_ |
330 std::string::const_iterator line_begin = raw_input.begin(); | 332 std::string::const_iterator line_begin = raw_input.begin(); |
331 std::string::const_iterator line_end = | 333 std::string::const_iterator line_end = |
332 find(line_begin, raw_input.end(), '\0'); | 334 std::find(line_begin, raw_input.end(), '\0'); |
333 // has_headers = true, if there is any data following the status line. | 335 // 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. | 336 // 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() && | 337 bool has_headers = (line_end != raw_input.end() && |
336 (line_end + 1) != raw_input.end() && | 338 (line_end + 1) != raw_input.end() && |
337 *(line_end + 1) != '\0'); | 339 *(line_end + 1) != '\0'); |
338 ParseStatusLine(line_begin, line_end, has_headers); | 340 ParseStatusLine(line_begin, line_end, has_headers); |
339 | 341 |
340 if (line_end == raw_input.end()) { | 342 if (line_end == raw_input.end()) { |
341 raw_headers_.push_back('\0'); | 343 raw_headers_.push_back('\0'); |
342 return; | 344 return; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 return std::string(raw_headers_.c_str()); | 452 return std::string(raw_headers_.c_str()); |
451 } | 453 } |
452 | 454 |
453 std::string HttpResponseHeaders::GetStatusText() const { | 455 std::string HttpResponseHeaders::GetStatusText() const { |
454 // GetStatusLine() is already normalized, so it has the format: | 456 // GetStatusLine() is already normalized, so it has the format: |
455 // <http_version> SP <response_code> SP <status_text> | 457 // <http_version> SP <response_code> SP <status_text> |
456 std::string status_text = GetStatusLine(); | 458 std::string status_text = GetStatusLine(); |
457 std::string::const_iterator begin = status_text.begin(); | 459 std::string::const_iterator begin = status_text.begin(); |
458 std::string::const_iterator end = status_text.end(); | 460 std::string::const_iterator end = status_text.end(); |
459 for (int i = 0; i < 2; ++i) | 461 for (int i = 0; i < 2; ++i) |
460 begin = find(begin, end, ' ') + 1; | 462 begin = std::find(begin, end, ' ') + 1; |
461 return std::string(begin, end); | 463 return std::string(begin, end); |
462 } | 464 } |
463 | 465 |
464 bool HttpResponseHeaders::EnumerateHeaderLines(void** iter, | 466 bool HttpResponseHeaders::EnumerateHeaderLines(void** iter, |
465 std::string* name, | 467 std::string* name, |
466 std::string* value) const { | 468 std::string* value) const { |
467 size_t i = reinterpret_cast<size_t>(*iter); | 469 size_t i = reinterpret_cast<size_t>(*iter); |
468 if (i == parsed_.size()) | 470 if (i == parsed_.size()) |
469 return false; | 471 return false; |
470 | 472 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 return HttpVersion(); | 552 return HttpVersion(); |
551 } | 553 } |
552 | 554 |
553 p += 4; | 555 p += 4; |
554 | 556 |
555 if (p >= line_end || *p != '/') { | 557 if (p >= line_end || *p != '/') { |
556 DVLOG(1) << "missing version"; | 558 DVLOG(1) << "missing version"; |
557 return HttpVersion(); | 559 return HttpVersion(); |
558 } | 560 } |
559 | 561 |
560 std::string::const_iterator dot = find(p, line_end, '.'); | 562 std::string::const_iterator dot = std::find(p, line_end, '.'); |
561 if (dot == line_end) { | 563 if (dot == line_end) { |
562 DVLOG(1) << "malformed version"; | 564 DVLOG(1) << "malformed version"; |
563 return HttpVersion(); | 565 return HttpVersion(); |
564 } | 566 } |
565 | 567 |
566 ++p; // from / to first digit. | 568 ++p; // from / to first digit. |
567 ++dot; // from . to second digit. | 569 ++dot; // from . to second digit. |
568 | 570 |
569 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { | 571 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { |
570 DVLOG(1) << "malformed version number"; | 572 DVLOG(1) << "malformed version number"; |
(...skipping 26 matching lines...) Expand all Loading... |
597 // Treat everything else like HTTP 1.0 | 599 // Treat everything else like HTTP 1.0 |
598 http_version_ = HttpVersion(1, 0); | 600 http_version_ = HttpVersion(1, 0); |
599 raw_headers_ = "HTTP/1.0"; | 601 raw_headers_ = "HTTP/1.0"; |
600 } | 602 } |
601 if (parsed_http_version_ != http_version_) { | 603 if (parsed_http_version_ != http_version_) { |
602 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." | 604 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." |
603 << http_version_.minor_value(); | 605 << http_version_.minor_value(); |
604 } | 606 } |
605 | 607 |
606 // TODO(eroman): this doesn't make sense if ParseVersion failed. | 608 // TODO(eroman): this doesn't make sense if ParseVersion failed. |
607 std::string::const_iterator p = find(line_begin, line_end, ' '); | 609 std::string::const_iterator p = std::find(line_begin, line_end, ' '); |
608 | 610 |
609 if (p == line_end) { | 611 if (p == line_end) { |
610 DVLOG(1) << "missing response status; assuming 200 OK"; | 612 DVLOG(1) << "missing response status; assuming 200 OK"; |
611 raw_headers_.append(" 200 OK"); | 613 raw_headers_.append(" 200 OK"); |
612 raw_headers_.push_back('\0'); | 614 raw_headers_.push_back('\0'); |
613 response_code_ = 200; | 615 response_code_ = 200; |
614 return; | 616 return; |
615 } | 617 } |
616 | 618 |
617 // Skip whitespace. | 619 // 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 | 1234 // We have all the values; let's verify that they make sense for a 206 |
1233 // response. | 1235 // response. |
1234 if (*first_byte_position < 0 || *last_byte_position < 0 || | 1236 if (*first_byte_position < 0 || *last_byte_position < 0 || |
1235 *instance_length < 0 || *instance_length - 1 < *last_byte_position) | 1237 *instance_length < 0 || *instance_length - 1 < *last_byte_position) |
1236 return false; | 1238 return false; |
1237 | 1239 |
1238 return true; | 1240 return true; |
1239 } | 1241 } |
1240 | 1242 |
1241 } // namespace net | 1243 } // namespace net |
OLD | NEW |