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

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 2414293002: Deprecates --spdy_framer_use_new_methods4. (Closed)
Patch Set: Created 4 years, 2 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/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_decoder_adapter.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 #include "net/spdy/spdy_framer.h" 5 #include "net/spdy/spdy_framer.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cctype>
10 #include <ios> 11 #include <ios>
11 #include <iterator> 12 #include <iterator>
12 #include <list> 13 #include <list>
13 #include <memory> 14 #include <memory>
14 #include <new> 15 #include <new>
15 #include <string> 16 #include <string>
16 #include <vector> 17 #include <vector>
17 18
18 #include "base/lazy_instance.h" 19 #include "base/lazy_instance.h"
19 #include "base/logging.h" 20 #include "base/logging.h"
20 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
21 #include "base/metrics/histogram_macros.h" 22 #include "base/metrics/histogram_macros.h"
23 #include "base/strings/string_util.h"
22 #include "net/quic/core/quic_flags.h" 24 #include "net/quic/core/quic_flags.h"
23 #include "net/spdy/hpack/hpack_constants.h" 25 #include "net/spdy/hpack/hpack_constants.h"
24 #include "net/spdy/spdy_bitmasks.h" 26 #include "net/spdy/spdy_bitmasks.h"
25 #include "net/spdy/spdy_bug_tracker.h" 27 #include "net/spdy/spdy_bug_tracker.h"
26 #include "net/spdy/spdy_flags.h" 28 #include "net/spdy/spdy_flags.h"
27 #include "net/spdy/spdy_frame_builder.h" 29 #include "net/spdy/spdy_frame_builder.h"
28 #include "net/spdy/spdy_frame_reader.h" 30 #include "net/spdy/spdy_frame_reader.h"
29 #include "net/spdy/spdy_framer_decoder_adapter.h" 31 #include "net/spdy/spdy_framer_decoder_adapter.h"
30 #include "net/spdy/spdy_headers_block_parser.h" 32 #include "net/spdy/spdy_headers_block_parser.h"
31 #include "third_party/zlib/zlib.h" 33 #include "third_party/zlib/zlib.h"
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 // manner that resists the length of the compressed data from compromising 1399 // manner that resists the length of the compressed data from compromising
1398 // cookie data. 1400 // cookie data.
1399 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, 1401 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
1400 z_stream* z) const { 1402 z_stream* z) const {
1401 const size_t length_length = 4; 1403 const size_t length_length = 4;
1402 WriteLengthZ(headers->size(), length_length, kZStandardData, z); 1404 WriteLengthZ(headers->size(), length_length, kZStandardData, z);
1403 1405
1404 SpdyHeaderBlock::const_iterator it; 1406 SpdyHeaderBlock::const_iterator it;
1405 for (it = headers->begin(); it != headers->end(); ++it) { 1407 for (it = headers->begin(); it != headers->end(); ++it) {
1406 WriteLengthZ(it->first.size(), length_length, kZStandardData, z); 1408 WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
1407 WriteZ(it->first, kZStandardData, z);
1408 1409
1409 if (it->first == "cookie") { 1410 std::string lowercase_key = base::ToLowerASCII(it->first);
1411 WriteZ(lowercase_key, kZStandardData, z);
1412
1413 if (lowercase_key == "cookie") {
1410 // We require the cookie values (save for the last) to end with a 1414 // We require the cookie values (save for the last) to end with a
1411 // semicolon and (save for the first) to start with a space. This is 1415 // semicolon and (save for the first) to start with a space. This is
1412 // typically the format that we are given them in but we reserialize them 1416 // typically the format that we are given them in but we reserialize them
1413 // to be sure. 1417 // to be sure.
1414 1418
1415 std::vector<base::StringPiece> cookie_values; 1419 std::vector<base::StringPiece> cookie_values;
1416 size_t cookie_length = 0; 1420 size_t cookie_length = 0;
1417 base::StringPiece cookie_data(it->second); 1421 base::StringPiece cookie_data(it->second);
1418 1422
1419 for (;;) { 1423 for (;;) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 cookie = cookie_values[i].as_string(); 1461 cookie = cookie_values[i].as_string();
1458 } else if (i == 0) { 1462 } else if (i == 0) {
1459 cookie = cookie_values[i].as_string() + ";"; 1463 cookie = cookie_values[i].as_string() + ";";
1460 } else if (i < cookie_values.size() - 1) { 1464 } else if (i < cookie_values.size() - 1) {
1461 cookie = " " + cookie_values[i].as_string() + ";"; 1465 cookie = " " + cookie_values[i].as_string() + ";";
1462 } else { 1466 } else {
1463 cookie = " " + cookie_values[i].as_string(); 1467 cookie = " " + cookie_values[i].as_string();
1464 } 1468 }
1465 WriteZ(cookie, kZCookieData, z); 1469 WriteZ(cookie, kZCookieData, z);
1466 } 1470 }
1467 } else if (it->first == "accept" || 1471 } else if (lowercase_key == "accept" ||
1468 it->first == "accept-charset" || 1472 lowercase_key == "accept-charset" ||
1469 it->first == "accept-encoding" || 1473 lowercase_key == "accept-encoding" ||
1470 it->first == "accept-language" || 1474 lowercase_key == "accept-language" ||
1471 it->first == "host" || 1475 lowercase_key == "host" ||
1472 it->first == "version" || 1476 lowercase_key == "version" ||
1473 it->first == "method" || 1477 lowercase_key == "method" ||
1474 it->first == "scheme" || 1478 lowercase_key == "scheme" ||
1475 it->first == ":host" || 1479 lowercase_key == ":host" ||
1476 it->first == ":version" || 1480 lowercase_key == ":version" ||
1477 it->first == ":method" || 1481 lowercase_key == ":method" ||
1478 it->first == ":scheme" || 1482 lowercase_key == ":scheme" ||
1479 it->first == "user-agent") { 1483 lowercase_key == "user-agent") {
1480 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); 1484 WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
1481 WriteZ(it->second, kZStandardData, z); 1485 WriteZ(it->second, kZStandardData, z);
1482 } else { 1486 } else {
1483 // Non-whitelisted headers are Huffman compressed in their own block, but 1487 // Non-whitelisted headers are Huffman compressed in their own block, but
1484 // don't match against the window. 1488 // don't match against the window.
1485 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); 1489 WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
1486 WriteZ(it->second, kZHuffmanOnlyData, z); 1490 WriteZ(it->second, kZHuffmanOnlyData, z);
1487 } 1491 }
1488 } 1492 }
1489 1493
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 break; 1693 break;
1690 default: 1694 default:
1691 #ifndef NDEBUG 1695 #ifndef NDEBUG
1692 LOG(FATAL) << "Invalid control frame type: " << current_frame_type_; 1696 LOG(FATAL) << "Invalid control frame type: " << current_frame_type_;
1693 #else 1697 #else
1694 set_error(SPDY_INVALID_CONTROL_FRAME); 1698 set_error(SPDY_INVALID_CONTROL_FRAME);
1695 return original_len - len; 1699 return original_len - len;
1696 #endif 1700 #endif
1697 } 1701 }
1698 1702
1699 if (use_new_methods_ && current_frame_type_ != CONTINUATION) { 1703 if (current_frame_type_ != CONTINUATION) {
1700 header_handler_ = visitor_->OnHeaderFrameStart(current_frame_stream_id_); 1704 header_handler_ = visitor_->OnHeaderFrameStart(current_frame_stream_id_);
1701 if (header_handler_ == nullptr) { 1705 if (header_handler_ == nullptr) {
1702 SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; 1706 SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr";
1703 set_error(SPDY_INTERNAL_FRAMER_ERROR); 1707 set_error(SPDY_INTERNAL_FRAMER_ERROR);
1704 return original_len - len; 1708 return original_len - len;
1705 } 1709 }
1706 if (protocol_version() == SPDY3) { 1710 if (protocol_version() == SPDY3) {
1707 header_parser_.reset( 1711 header_parser_.reset(
1708 new SpdyHeadersBlockParser(protocol_version(), header_handler_)); 1712 new SpdyHeadersBlockParser(protocol_version(), header_handler_));
1709 } else { 1713 } else {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 remaining_data_length_ -= process_bytes; 1763 remaining_data_length_ -= process_bytes;
1760 1764
1761 // Handle the case that there is no futher data in this frame. 1765 // Handle the case that there is no futher data in this frame.
1762 if (remaining_data_length_ == remaining_padding_payload_length_ && 1766 if (remaining_data_length_ == remaining_padding_payload_length_ &&
1763 processed_successfully) { 1767 processed_successfully) {
1764 if (expect_continuation_ == 0) { 1768 if (expect_continuation_ == 0) {
1765 if (is_hpack_header_block) { 1769 if (is_hpack_header_block) {
1766 size_t compressed_len = 0; 1770 size_t compressed_len = 0;
1767 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( 1771 if (GetHpackDecoder()->HandleControlFrameHeadersComplete(
1768 &compressed_len)) { 1772 &compressed_len)) {
1769 if (use_new_methods_) { 1773 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true);
1770 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); 1774 if (state_ == SPDY_ERROR) {
1771 if (state_ == SPDY_ERROR) { 1775 return data_len;
1772 return data_len;
1773 }
1774 } else {
1775 // TODO(jgraettinger): To be removed with migration to
1776 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a
1777 // SPDY3 block, delivered via reentrant call to
1778 // ProcessControlFrameHeaderBlock().
1779 DeliverHpackBlockAsSpdy3Block(compressed_len);
1780 return process_bytes;
1781 } 1776 }
1782 } else { 1777 } else {
1783 set_error(SPDY_DECOMPRESS_FAILURE); 1778 set_error(SPDY_DECOMPRESS_FAILURE);
1784 processed_successfully = false; 1779 processed_successfully = false;
1785 } 1780 }
1786 } else { 1781 } else {
1787 if (use_new_methods_) { 1782 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true);
1788 visitor_->OnHeaderFrameEnd(current_frame_stream_id_, true); 1783 if (state_ == SPDY_ERROR) {
1789 if (state_ == SPDY_ERROR) { 1784 return data_len;
1790 return data_len;
1791 }
1792 } else {
1793 // The complete header block has been delivered. We send a zero-length
1794 // OnControlFrameHeaderData() to indicated this.
1795 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, nullptr,
1796 0);
1797 } 1785 }
1798 } 1786 }
1799 } 1787 }
1800 if (processed_successfully) { 1788 if (processed_successfully) {
1801 CHANGE_STATE(SPDY_CONSUME_PADDING); 1789 CHANGE_STATE(SPDY_CONSUME_PADDING);
1802 } 1790 }
1803 } 1791 }
1804 1792
1805 // Handle error. 1793 // Handle error.
1806 if (!processed_successfully) { 1794 if (!processed_successfully) {
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 // Read each header. 2341 // Read each header.
2354 for (uint32_t index = 0; index < num_headers; ++index) { 2342 for (uint32_t index = 0; index < num_headers; ++index) {
2355 base::StringPiece temp; 2343 base::StringPiece temp;
2356 2344
2357 // Read header name. 2345 // Read header name.
2358 if (!reader.ReadStringPiece32(&temp)) { 2346 if (!reader.ReadStringPiece32(&temp)) {
2359 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " 2347 DVLOG(1) << "Unable to read header name (" << index + 1 << " of "
2360 << num_headers << ")."; 2348 << num_headers << ").";
2361 return false; 2349 return false;
2362 } 2350 }
2351 const char* begin = temp.data();
2352 const char* end = begin;
2353 std::advance(end, temp.size());
2354 if (protocol_version_ == HTTP2 && std::any_of(begin, end, isupper)) {
2355 DVLOG(1) << "Malformed header: Header name " << temp
2356 << " contains upper-case characters.";
2357 return false;
2358 }
2363 std::string name = temp.as_string(); 2359 std::string name = temp.as_string();
2364 2360
2365 // Read header value. 2361 // Read header value.
2366 if (!reader.ReadStringPiece32(&temp)) { 2362 if (!reader.ReadStringPiece32(&temp)) {
2367 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " 2363 DVLOG(1) << "Unable to read header value (" << index + 1 << " of "
2368 << num_headers << ")."; 2364 << num_headers << ").";
2369 return false; 2365 return false;
2370 } 2366 }
2371 std::string value = temp.as_string(); 2367 std::string value = temp.as_string();
2372 2368
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
3294 } 3290 }
3295 3291
3296 // Inflate will generate a Z_BUF_ERROR if it runs out of input 3292 // Inflate will generate a Z_BUF_ERROR if it runs out of input
3297 // without producing any output. The input is consumed and 3293 // without producing any output. The input is consumed and
3298 // buffered internally by zlib so we can detect this condition by 3294 // buffered internally by zlib so we can detect this condition by
3299 // checking if avail_in is 0 after the call to inflate. 3295 // checking if avail_in is 0 after the call to inflate.
3300 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0)); 3296 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
3301 if ((rv == Z_OK) || input_exhausted) { 3297 if ((rv == Z_OK) || input_exhausted) {
3302 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; 3298 size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
3303 if (decompressed_len > 0) { 3299 if (decompressed_len > 0) {
3304 if (use_new_methods_) { 3300 processed_successfully = header_parser_->HandleControlFrameHeadersData(
3305 processed_successfully = 3301 stream_id, buffer, decompressed_len);
3306 header_parser_->HandleControlFrameHeadersData(stream_id, buffer, 3302 if (header_parser_->get_error() ==
3307 decompressed_len); 3303 SpdyHeadersBlockParser::NEED_MORE_DATA) {
3308 if (header_parser_->get_error() == 3304 processed_successfully = true;
3309 SpdyHeadersBlockParser::NEED_MORE_DATA) {
3310 processed_successfully = true;
3311 }
3312 } else {
3313 processed_successfully = visitor_->OnControlFrameHeaderData(
3314 stream_id, buffer, decompressed_len);
3315 } 3305 }
3316 } 3306 }
3317 if (!processed_successfully) { 3307 if (!processed_successfully) {
3318 // Assume that the problem was the header block was too large for the 3308 // Assume that the problem was the header block was too large for the
3319 // visitor. 3309 // visitor.
3320 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 3310 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
3321 } 3311 }
3322 } else { 3312 } else {
3323 DLOG(WARNING) << "inflate failure: " << rv << " " << len; 3313 DLOG(WARNING) << "inflate failure: " << rv << " " << len;
3324 set_error(SPDY_DECOMPRESS_FAILURE); 3314 set_error(SPDY_DECOMPRESS_FAILURE);
3325 processed_successfully = false; 3315 processed_successfully = false;
3326 } 3316 }
3327 } 3317 }
3328 return processed_successfully; 3318 return processed_successfully;
3329 } 3319 }
3330 3320
3331 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( 3321 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
3332 SpdyStreamId stream_id, const char* data, size_t len) { 3322 SpdyStreamId stream_id, const char* data, size_t len) {
3333 bool read_successfully = true; 3323 bool read_successfully = true;
3334 while (read_successfully && len > 0) { 3324 while (read_successfully && len > 0) {
3335 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); 3325 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
3336 if (use_new_methods_) { 3326 read_successfully = header_parser_->HandleControlFrameHeadersData(
3337 read_successfully = header_parser_->HandleControlFrameHeadersData( 3327 stream_id, data, bytes_to_deliver);
3338 stream_id, data, bytes_to_deliver); 3328 if (header_parser_->get_error() == SpdyHeadersBlockParser::NEED_MORE_DATA) {
3339 if (header_parser_->get_error() == 3329 read_successfully = true;
3340 SpdyHeadersBlockParser::NEED_MORE_DATA) {
3341 read_successfully = true;
3342 }
3343 } else {
3344 read_successfully =
3345 visitor_->OnControlFrameHeaderData(stream_id, data, bytes_to_deliver);
3346 } 3330 }
3347 data += bytes_to_deliver; 3331 data += bytes_to_deliver;
3348 len -= bytes_to_deliver; 3332 len -= bytes_to_deliver;
3349 if (!read_successfully) { 3333 if (!read_successfully) {
3350 // Assume that the problem was the header block was too large for the 3334 // Assume that the problem was the header block was too large for the
3351 // visitor. 3335 // visitor.
3352 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 3336 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
3353 } 3337 }
3354 } 3338 }
3355 return read_successfully; 3339 return read_successfully;
(...skipping 30 matching lines...) Expand all
3386 } 3370 }
3387 3371
3388 void SpdyFramer::SerializeHeaderBlockWithoutCompression( 3372 void SpdyFramer::SerializeHeaderBlockWithoutCompression(
3389 SpdyFrameBuilder* builder, 3373 SpdyFrameBuilder* builder,
3390 const SpdyHeaderBlock& header_block) const { 3374 const SpdyHeaderBlock& header_block) const {
3391 // Serialize number of headers. 3375 // Serialize number of headers.
3392 builder->WriteUInt32(header_block.size()); 3376 builder->WriteUInt32(header_block.size());
3393 3377
3394 // Serialize each header. 3378 // Serialize each header.
3395 for (const auto& header : header_block) { 3379 for (const auto& header : header_block) {
3396 builder->WriteStringPiece32(header.first); 3380 builder->WriteStringPiece32(base::ToLowerASCII(header.first));
3397 builder->WriteStringPiece32(header.second); 3381 builder->WriteStringPiece32(header.second);
3398 } 3382 }
3399 } 3383 }
3400 3384
3401 void SpdyFramer::SerializeHeaderBlock(SpdyFrameBuilder* builder, 3385 void SpdyFramer::SerializeHeaderBlock(SpdyFrameBuilder* builder,
3402 const SpdyFrameWithHeaderBlockIR& frame) { 3386 const SpdyFrameWithHeaderBlockIR& frame) {
3403 if (!enable_compression_) { 3387 if (!enable_compression_) {
3404 return SerializeHeaderBlockWithoutCompression(builder, 3388 return SerializeHeaderBlockWithoutCompression(builder,
3405 frame.header_block()); 3389 frame.header_block());
3406 } 3390 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3450 #else 3434 #else
3451 WriteHeaderBlockToZ(&frame.header_block(), compressor); 3435 WriteHeaderBlockToZ(&frame.header_block(), compressor);
3452 #endif // defined(USE_SYSTEM_ZLIB) 3436 #endif // defined(USE_SYSTEM_ZLIB)
3453 3437
3454 int compressed_size = compressed_max_size - compressor->avail_out; 3438 int compressed_size = compressed_max_size - compressor->avail_out;
3455 builder->Seek(compressed_size); 3439 builder->Seek(compressed_size);
3456 builder->RewriteLength(*this); 3440 builder->RewriteLength(*this);
3457 } 3441 }
3458 3442
3459 } // namespace net 3443 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_decoder_adapter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698