Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Side by Side Diff: net/http/http_response_headers.cc

Issue 527883002: Modified to resolve TODO in parseversion in http_response_headers.cc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Modified to include overflow logic and other comments Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_response_headers.h ('k') | net/http/http_response_headers_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 bool HttpResponseHeaders::HasHeader(const base::StringPiece& name) const { 613 bool HttpResponseHeaders::HasHeader(const base::StringPiece& name) const {
614 return FindHeader(0, name) != std::string::npos; 614 return FindHeader(0, name) != std::string::npos;
615 } 615 }
616 616
617 HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) { 617 HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) {
618 } 618 }
619 619
620 HttpResponseHeaders::~HttpResponseHeaders() { 620 HttpResponseHeaders::~HttpResponseHeaders() {
621 } 621 }
622 622
623 // Function to parse HTTP Version in accordance to
624 // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
625 // if input string is valid, returns corresponding number in value
626 // else returns false
627 bool HttpResponseHeaders::ParseVersionInternal(
628 std::string::const_iterator begin,
629 std::string::const_iterator end,
630 uint32* value) {
631 std::string error_msg;
632 if(!base::StringToUint(StringPiece(begin, end), value)) {
633 if(*value == 0) {
634 if(begin == end) {
635 error_msg = "Empty String!!!";
636 } else if(!(*begin >= '0' && *begin <= '9')) {
637 error_msg = "Invalid char at beginning!!!";
638 } else {
639 error_msg = "Underflow!!!";
640 }
641 } else if(*value == 0xFFFFFFFF) {
642 error_msg = "Overflow!!!";
643 } else if(!(*(end-1) >= '0' && *(end-1) <= '9')) {
644 error_msg = "Invalid char at end!!!";
645 } else {
646 error_msg = "Invalid value!!!";
647 }
648 DVLOG(1) << error_msg;
649 return false;
650 }
651 return true;
652 }
653
623 // Note: this implementation implicitly assumes that line_end points at a valid 654 // Note: this implementation implicitly assumes that line_end points at a valid
624 // sentinel character (such as '\0'). 655 // sentinel character (such as '\0').
625 // static 656 // static
626 HttpVersion HttpResponseHeaders::ParseVersion( 657 HttpVersion HttpResponseHeaders::ParseVersion(
627 std::string::const_iterator line_begin, 658 std::string::const_iterator line_begin,
628 std::string::const_iterator line_end) { 659 std::string::const_iterator line_end) {
629 std::string::const_iterator p = line_begin; 660 std::string::const_iterator p = line_begin;
630 661
631 // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
632 // TODO: (1*DIGIT apparently means one or more digits, but we only handle 1).
633 // TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1.
634
635 if ((line_end - p < 4) || !LowerCaseEqualsASCII(p, p + 4, "http")) { 662 if ((line_end - p < 4) || !LowerCaseEqualsASCII(p, p + 4, "http")) {
636 DVLOG(1) << "missing status line"; 663 DVLOG(1) << "missing status line";
637 return HttpVersion(); 664 return HttpVersion();
638 } 665 }
639 666
640 p += 4; 667 p += 4;
641 668
642 if (p >= line_end || *p != '/') { 669 if (p >= line_end || *p != '/') {
643 DVLOG(1) << "missing version"; 670 DVLOG(1) << "missing version";
644 return HttpVersion(); 671 return HttpVersion();
645 } 672 }
646 673
647 std::string::const_iterator dot = std::find(p, line_end, '.'); 674 std::string::const_iterator dot = std::find(p, line_end, '.');
648 if (dot == line_end) { 675 std::string::const_iterator end_of_minor = dot+1;
649 DVLOG(1) << "malformed version"; 676
677 // find end of minor.
678 while(*end_of_minor != ' ')
679 end_of_minor++;
680
681 ++p; // from / to first digit.
682 uint32 major = 0;
683 uint32 minor = 0;
684
685 if (ParseVersionInternal(p, dot, &major) &&
686 ParseVersionInternal(dot + 1, end_of_minor, &minor)) {
687 DVLOG(1) << "ParseVersion success!!!";
688 return HttpVersion(major, minor);
689 } else {
690 DVLOG(1) << "ParseVersion fail!!!";
650 return HttpVersion(); 691 return HttpVersion();
651 } 692 }
652
653 ++p; // from / to first digit.
654 ++dot; // from . to second digit.
655
656 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) {
657 DVLOG(1) << "malformed version number";
658 return HttpVersion();
659 }
660
661 uint16 major = *p - '0';
662 uint16 minor = *dot - '0';
663
664 return HttpVersion(major, minor);
665 } 693 }
666 694
667 // Note: this implementation implicitly assumes that line_end points at a valid 695 // Note: this implementation implicitly assumes that line_end points at a valid
668 // sentinel character (such as '\0'). 696 // sentinel character (such as '\0').
669 void HttpResponseHeaders::ParseStatusLine( 697 void HttpResponseHeaders::ParseStatusLine(
670 std::string::const_iterator line_begin, 698 std::string::const_iterator line_begin,
671 std::string::const_iterator line_end, 699 std::string::const_iterator line_end,
672 bool has_headers) { 700 bool has_headers) {
673 // Extract the version number 701 // Extract the version number
674 parsed_http_version_ = ParseVersion(line_begin, line_end); 702 parsed_http_version_ = ParseVersion(line_begin, line_end);
675 703
676 // Clamp the version number to one of: {0.9, 1.0, 1.1} 704 //Allow mulitple digits in major and minor values of HTTP Version.
677 if (parsed_http_version_ == HttpVersion(0, 9) && !has_headers) { 705 //If parseVersion failed, keep version as 1.0 as per old logic
678 http_version_ = HttpVersion(0, 9); 706 //If version is 0.9 and has headers, keep version as 1.0 as per old logic
679 raw_headers_ = "HTTP/0.9"; 707 //If version is 0.9 and has no headers, keep version as 0.9 as per old logic
680 } else if (parsed_http_version_ >= HttpVersion(1, 1)) { 708 //Else in all other cases, http_version will be same as parsed_http_version
681 http_version_ = HttpVersion(1, 1); 709 if (parsed_http_version_ == HttpVersion()) {
682 raw_headers_ = "HTTP/1.1";
683 } else {
684 // Treat everything else like HTTP 1.0
685 http_version_ = HttpVersion(1, 0); 710 http_version_ = HttpVersion(1, 0);
686 raw_headers_ = "HTTP/1.0"; 711 raw_headers_ = "HTTP/1.0";
712 } else if (parsed_http_version_ == HttpVersion(0, 9) && has_headers) {
713 http_version_ = HttpVersion(1, 0);
714 raw_headers_ = "HTTP/1.0";
715 } else {
716 http_version_ = parsed_http_version_;
717 raw_headers_ = "HTTP/";
718 raw_headers_.append(base::UintToString(http_version_.major_value()));
719 raw_headers_.append(".");
720 raw_headers_.append(base::UintToString(http_version_.minor_value()));
687 } 721 }
688 if (parsed_http_version_ != http_version_) { 722 if (parsed_http_version_ != http_version_) {
689 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." 723 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "."
690 << http_version_.minor_value(); 724 << http_version_.minor_value();
691 } 725 }
692 726
693 // TODO(eroman): this doesn't make sense if ParseVersion failed. 727 // TODO(eroman): this doesn't make sense if ParseVersion failed.
694 std::string::const_iterator p = std::find(line_begin, line_end, ' '); 728 std::string::const_iterator p = std::find(line_begin, line_end, ' ');
695 729
696 if (p == line_end) { 730 if (p == line_end) {
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 return true; 1431 return true;
1398 } 1432 }
1399 1433
1400 bool HttpResponseHeaders::IsChunkEncoded() const { 1434 bool HttpResponseHeaders::IsChunkEncoded() const {
1401 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. 1435 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies.
1402 return GetHttpVersion() >= HttpVersion(1, 1) && 1436 return GetHttpVersion() >= HttpVersion(1, 1) &&
1403 HasHeaderValue("Transfer-Encoding", "chunked"); 1437 HasHeaderValue("Transfer-Encoding", "chunked");
1404 } 1438 }
1405 1439
1406 } // namespace net 1440 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_response_headers.h ('k') | net/http/http_response_headers_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698