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

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

Issue 8760010: Ensure HttpResponseHeaders::raw_headers_ always ends with 2 '\0' characters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_response_headers.h ('k') | no next file » | 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) 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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 // ParseStatusLine adds a normalized status line to raw_headers_ 383 // ParseStatusLine adds a normalized status line to raw_headers_
384 std::string::const_iterator line_begin = raw_input.begin(); 384 std::string::const_iterator line_begin = raw_input.begin();
385 std::string::const_iterator line_end = 385 std::string::const_iterator line_end =
386 std::find(line_begin, raw_input.end(), '\0'); 386 std::find(line_begin, raw_input.end(), '\0');
387 // has_headers = true, if there is any data following the status line. 387 // has_headers = true, if there is any data following the status line.
388 // Used by ParseStatusLine() to decide if a HTTP/0.9 is really a HTTP/1.0. 388 // Used by ParseStatusLine() to decide if a HTTP/0.9 is really a HTTP/1.0.
389 bool has_headers = (line_end != raw_input.end() && 389 bool has_headers = (line_end != raw_input.end() &&
390 (line_end + 1) != raw_input.end() && 390 (line_end + 1) != raw_input.end() &&
391 *(line_end + 1) != '\0'); 391 *(line_end + 1) != '\0');
392 ParseStatusLine(line_begin, line_end, has_headers); 392 ParseStatusLine(line_begin, line_end, has_headers);
393 raw_headers_.push_back('\0'); // terminate status line with a null
rvargas (doing something else) 2011/11/30 22:53:09 Nit: Start with uppercase and end with period.
393 394
394 if (line_end == raw_input.end()) { 395 if (line_end == raw_input.end()) {
395 raw_headers_.push_back('\0'); 396 raw_headers_.push_back('\0'); // ensure the headers end with a double null
rvargas (doing something else) 2011/11/30 22:53:09 ibid
397
398 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 2]);
399 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]);
396 return; 400 return;
397 } 401 }
398 402
399 // Including a terminating null byte. 403 // Including a terminating null byte.
400 size_t status_line_len = raw_headers_.size(); 404 size_t status_line_len = raw_headers_.size();
401 405
402 // Now, we add the rest of the raw headers to raw_headers_, and begin parsing 406 // Now, we add the rest of the raw headers to raw_headers_, and begin parsing
403 // it (to populate our parsed_ vector). 407 // it (to populate our parsed_ vector).
404 raw_headers_.append(line_end + 1, raw_input.end()); 408 raw_headers_.append(line_end + 1, raw_input.end());
405 409
406 // Adjust to point at the null byte following the status line 410 // Adjust to point at the null byte following the status line
407 line_end = raw_headers_.begin() + status_line_len - 1; 411 line_end = raw_headers_.begin() + status_line_len - 1;
408 412
409 HttpUtil::HeadersIterator headers(line_end + 1, raw_headers_.end(), 413 HttpUtil::HeadersIterator headers(line_end + 1, raw_headers_.end(),
410 std::string(1, '\0')); 414 std::string(1, '\0'));
411 while (headers.GetNext()) { 415 while (headers.GetNext()) {
412 AddHeader(headers.name_begin(), 416 AddHeader(headers.name_begin(),
413 headers.name_end(), 417 headers.name_end(),
414 headers.values_begin(), 418 headers.values_begin(),
415 headers.values_end()); 419 headers.values_end());
416 } 420 }
421
422 // Ensure the headers end with a double null.
423 while (raw_headers_.size() < 2 ||
424 raw_headers_[raw_headers_.size() - 2] != '\0' ||
425 raw_headers_[raw_headers_.size() - 1] != '\0') {
426 raw_headers_.push_back('\0');
427 }
428
429 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 2]);
430 DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]);
417 } 431 }
418 432
419 // Append all of our headers to the final output string. 433 // Append all of our headers to the final output string.
420 void HttpResponseHeaders::GetNormalizedHeaders(std::string* output) const { 434 void HttpResponseHeaders::GetNormalizedHeaders(std::string* output) const {
421 // copy up to the null byte. this just copies the status line. 435 // copy up to the null byte. this just copies the status line.
422 output->assign(raw_headers_.c_str()); 436 output->assign(raw_headers_.c_str());
423 437
424 // headers may appear multiple times (not necessarily in succession) in the 438 // headers may appear multiple times (not necessarily in succession) in the
425 // header data, so we build a map from header name to generated header lines. 439 // header data, so we build a map from header name to generated header lines.
426 // to preserve the order of the original headers, the actual values are kept 440 // to preserve the order of the original headers, the actual values are kept
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." 670 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "."
657 << http_version_.minor_value(); 671 << http_version_.minor_value();
658 } 672 }
659 673
660 // TODO(eroman): this doesn't make sense if ParseVersion failed. 674 // TODO(eroman): this doesn't make sense if ParseVersion failed.
661 std::string::const_iterator p = std::find(line_begin, line_end, ' '); 675 std::string::const_iterator p = std::find(line_begin, line_end, ' ');
662 676
663 if (p == line_end) { 677 if (p == line_end) {
664 DVLOG(1) << "missing response status; assuming 200 OK"; 678 DVLOG(1) << "missing response status; assuming 200 OK";
665 raw_headers_.append(" 200 OK"); 679 raw_headers_.append(" 200 OK");
666 raw_headers_.push_back('\0');
667 response_code_ = 200; 680 response_code_ = 200;
668 return; 681 return;
669 } 682 }
670 683
671 // Skip whitespace. 684 // Skip whitespace.
672 while (*p == ' ') 685 while (*p == ' ')
673 ++p; 686 ++p;
674 687
675 std::string::const_iterator code = p; 688 std::string::const_iterator code = p;
676 while (*p >= '0' && *p <= '9') 689 while (*p >= '0' && *p <= '9')
(...skipping 19 matching lines...) Expand all
696 --line_end; 709 --line_end;
697 710
698 if (p == line_end) { 711 if (p == line_end) {
699 DVLOG(1) << "missing response status text; assuming OK"; 712 DVLOG(1) << "missing response status text; assuming OK";
700 // Not super critical what we put here. Just use "OK" 713 // Not super critical what we put here. Just use "OK"
701 // even if it isn't descriptive of response_code_. 714 // even if it isn't descriptive of response_code_.
702 raw_headers_.append("OK"); 715 raw_headers_.append("OK");
703 } else { 716 } else {
704 raw_headers_.append(p, line_end); 717 raw_headers_.append(p, line_end);
705 } 718 }
706
707 raw_headers_.push_back('\0');
708 } 719 }
709 720
710 size_t HttpResponseHeaders::FindHeader(size_t from, 721 size_t HttpResponseHeaders::FindHeader(size_t from,
711 const std::string& search) const { 722 const std::string& search) const {
712 for (size_t i = from; i < parsed_.size(); ++i) { 723 for (size_t i = from; i < parsed_.size(); ++i) {
713 if (parsed_[i].is_continuation()) 724 if (parsed_[i].is_continuation())
714 continue; 725 continue;
715 const std::string::const_iterator& name_begin = parsed_[i].name_begin; 726 const std::string::const_iterator& name_begin = parsed_[i].name_begin;
716 const std::string::const_iterator& name_end = parsed_[i].name_end; 727 const std::string::const_iterator& name_end = parsed_[i].name_end;
717 if (static_cast<size_t>(name_end - name_begin) == search.size() && 728 if (static_cast<size_t>(name_end - name_begin) == search.size() &&
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 return true; 1302 return true;
1292 } 1303 }
1293 1304
1294 bool HttpResponseHeaders::IsChunkEncoded() const { 1305 bool HttpResponseHeaders::IsChunkEncoded() const {
1295 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. 1306 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies.
1296 return GetHttpVersion() >= HttpVersion(1, 1) && 1307 return GetHttpVersion() >= HttpVersion(1, 1) &&
1297 HasHeaderValue("Transfer-Encoding", "chunked"); 1308 HasHeaderValue("Transfer-Encoding", "chunked");
1298 } 1309 }
1299 1310
1300 } // namespace net 1311 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_response_headers.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698