| OLD | NEW |
| 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 #ifndef NET_SPDY_SPDY_FRAMER_H_ | 5 #ifndef NET_SPDY_SPDY_FRAMER_H_ |
| 6 #define NET_SPDY_SPDY_FRAMER_H_ | 6 #define NET_SPDY_SPDY_FRAMER_H_ |
| 7 | 7 |
| 8 #include <list> | 8 #include <list> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. | 300 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. |
| 301 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. | 301 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. |
| 302 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. | 302 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. |
| 303 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. | 303 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. |
| 304 SPDY_COMPRESS_FAILURE, // There was an error compressing. | 304 SPDY_COMPRESS_FAILURE, // There was an error compressing. |
| 305 SPDY_GOAWAY_FRAME_CORRUPT, // GOAWAY frame could not be parsed. | 305 SPDY_GOAWAY_FRAME_CORRUPT, // GOAWAY frame could not be parsed. |
| 306 SPDY_RST_STREAM_FRAME_CORRUPT, // RST_STREAM frame could not be parsed. | 306 SPDY_RST_STREAM_FRAME_CORRUPT, // RST_STREAM frame could not be parsed. |
| 307 SPDY_INVALID_DATA_FRAME_FLAGS, // Data frame has invalid flags. | 307 SPDY_INVALID_DATA_FRAME_FLAGS, // Data frame has invalid flags. |
| 308 SPDY_INVALID_CONTROL_FRAME_FLAGS, // Control frame has invalid flags. | 308 SPDY_INVALID_CONTROL_FRAME_FLAGS, // Control frame has invalid flags. |
| 309 SPDY_UNEXPECTED_FRAME, // Frame received out of order. | 309 SPDY_UNEXPECTED_FRAME, // Frame received out of order. |
| 310 | 310 LAST_ERROR, // Must be the last entry in the enum. |
| 311 LAST_ERROR, // Must be the last entry in the enum. | |
| 312 }; | 311 }; |
| 313 | 312 |
| 314 // Constant for invalid (or unknown) stream IDs. | 313 // Constant for invalid (or unknown) stream IDs. |
| 315 static const SpdyStreamId kInvalidStream; | 314 static const SpdyStreamId kInvalidStream; |
| 316 | 315 |
| 317 // The maximum size of header data chunks delivered to the framer visitor | 316 // The maximum size of header data chunks delivered to the framer visitor |
| 318 // through OnControlFrameHeaderData. (It is exposed here for unit test | 317 // through OnControlFrameHeaderData. (It is exposed here for unit test |
| 319 // purposes.) | 318 // purposes.) |
| 320 static const size_t kHeaderDataChunkMaxSize; | 319 static const size_t kHeaderDataChunkMaxSize; |
| 321 | 320 |
| 322 // Serializes a SpdyHeaderBlock. | 321 // Serializes a SpdyHeaderBlock. |
| 323 static void WriteHeaderBlock(SpdyFrameBuilder* frame, | 322 static void WriteHeaderBlock(SpdyFrameBuilder* frame, |
| 324 const SpdyMajorVersion spdy_version, | 323 const SpdyMajorVersion spdy_version, |
| 325 const SpdyHeaderBlock* headers); | 324 const SpdyHeaderBlock* headers); |
| 326 | 325 |
| 327 // Retrieve serialized length of SpdyHeaderBlock. | 326 // Retrieve serialized length of SpdyHeaderBlock. |
| 328 // TODO(hkhalil): Remove, or move to quic code. | 327 // TODO(hkhalil): Remove, or move to quic code. |
| 329 static size_t GetSerializedLength( | 328 static size_t GetSerializedLength(const SpdyMajorVersion spdy_version, |
| 330 const SpdyMajorVersion spdy_version, | 329 const SpdyHeaderBlock* headers); |
| 331 const SpdyHeaderBlock* headers); | |
| 332 | 330 |
| 333 // Create a new Framer, provided a SPDY version. | 331 // Create a new Framer, provided a SPDY version. |
| 334 explicit SpdyFramer(SpdyMajorVersion version); | 332 explicit SpdyFramer(SpdyMajorVersion version); |
| 335 virtual ~SpdyFramer(); | 333 virtual ~SpdyFramer(); |
| 336 | 334 |
| 337 // Set callbacks to be called from the framer. A visitor must be set, or | 335 // Set callbacks to be called from the framer. A visitor must be set, or |
| 338 // else the framer will likely crash. It is acceptable for the visitor | 336 // else the framer will likely crash. It is acceptable for the visitor |
| 339 // to do nothing. If this is called multiple times, only the last visitor | 337 // to do nothing. If this is called multiple times, only the last visitor |
| 340 // will be used. | 338 // will be used. |
| 341 void set_visitor(SpdyFramerVisitorInterface* visitor) { | 339 void set_visitor(SpdyFramerVisitorInterface* visitor) { visitor_ = visitor; } |
| 342 visitor_ = visitor; | |
| 343 } | |
| 344 | 340 |
| 345 // Set debug callbacks to be called from the framer. The debug visitor is | 341 // Set debug callbacks to be called from the framer. The debug visitor is |
| 346 // completely optional and need not be set in order for normal operation. | 342 // completely optional and need not be set in order for normal operation. |
| 347 // If this is called multiple times, only the last visitor will be used. | 343 // If this is called multiple times, only the last visitor will be used. |
| 348 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor) { | 344 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor) { |
| 349 debug_visitor_ = debug_visitor; | 345 debug_visitor_ = debug_visitor; |
| 350 } | 346 } |
| 351 | 347 |
| 352 // Pass data into the framer for parsing. | 348 // Pass data into the framer for parsing. |
| 353 // Returns the number of bytes consumed. It is safe to pass more bytes in | 349 // Returns the number of bytes consumed. It is safe to pass more bytes in |
| 354 // than may be consumed. | 350 // than may be consumed. |
| 355 size_t ProcessInput(const char* data, size_t len); | 351 size_t ProcessInput(const char* data, size_t len); |
| 356 | 352 |
| 357 // Resets the framer state after a frame has been successfully decoded. | 353 // Resets the framer state after a frame has been successfully decoded. |
| 358 // TODO(mbelshe): can we make this private? | 354 // TODO(mbelshe): can we make this private? |
| 359 void Reset(); | 355 void Reset(); |
| 360 | 356 |
| 361 // Check the state of the framer. | 357 // Check the state of the framer. |
| 362 SpdyError error_code() const { return error_code_; } | 358 SpdyError error_code() const { return error_code_; } |
| 363 SpdyState state() const { return state_; } | 359 SpdyState state() const { return state_; } |
| 364 bool HasError() const { return state_ == SPDY_ERROR; } | 360 bool HasError() const { return state_ == SPDY_ERROR; } |
| 365 | 361 |
| 366 // Given a buffer containing a decompressed header block in SPDY | 362 // Given a buffer containing a decompressed header block in SPDY |
| 367 // serialized format, parse out a SpdyHeaderBlock, putting the results | 363 // serialized format, parse out a SpdyHeaderBlock, putting the results |
| 368 // in the given header block. | 364 // in the given header block. |
| 369 // Returns number of bytes consumed if successfully parsed, 0 otherwise. | 365 // Returns number of bytes consumed if successfully parsed, 0 otherwise. |
| 370 size_t ParseHeaderBlockInBuffer(const char* header_data, | 366 size_t ParseHeaderBlockInBuffer(const char* header_data, |
| 371 size_t header_length, | 367 size_t header_length, |
| 372 SpdyHeaderBlock* block) const; | 368 SpdyHeaderBlock* block) const; |
| 373 | 369 |
| 374 // Serialize a data frame. | 370 // Serialize a data frame. |
| 375 SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const; | 371 SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const; |
| 376 // Serializes the data frame header and optionally padding length fields, | 372 // Serializes the data frame header and optionally padding length fields, |
| 377 // excluding actual data payload and padding. | 373 // excluding actual data payload and padding. |
| 378 SpdySerializedFrame* SerializeDataFrameHeaderWithPaddingLengthField( | 374 SpdySerializedFrame* SerializeDataFrameHeaderWithPaddingLengthField( |
| 379 const SpdyDataIR& data) const; | 375 const SpdyDataIR& data) const; |
| 380 | 376 |
| 381 // Serializes a SYN_STREAM frame. | 377 // Serializes a SYN_STREAM frame. |
| 382 SpdySerializedFrame* SerializeSynStream(const SpdySynStreamIR& syn_stream); | 378 SpdySerializedFrame* SerializeSynStream(const SpdySynStreamIR& syn_stream); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 // using zlib anyway. | 442 // using zlib anyway. |
| 447 | 443 |
| 448 // Compresses a SpdyFrame. | 444 // Compresses a SpdyFrame. |
| 449 // On success, returns a new SpdyFrame with the payload compressed. | 445 // On success, returns a new SpdyFrame with the payload compressed. |
| 450 // Compression state is maintained as part of the SpdyFramer. | 446 // Compression state is maintained as part of the SpdyFramer. |
| 451 // Returned frame must be freed with "delete". | 447 // Returned frame must be freed with "delete". |
| 452 // On failure, returns NULL. | 448 // On failure, returns NULL. |
| 453 SpdyFrame* CompressFrame(const SpdyFrame& frame); | 449 SpdyFrame* CompressFrame(const SpdyFrame& frame); |
| 454 | 450 |
| 455 // For ease of testing and experimentation we can tweak compression on/off. | 451 // For ease of testing and experimentation we can tweak compression on/off. |
| 456 void set_enable_compression(bool value) { | 452 void set_enable_compression(bool value) { enable_compression_ = value; } |
| 457 enable_compression_ = value; | |
| 458 } | |
| 459 | 453 |
| 460 // Used only in log messages. | 454 // Used only in log messages. |
| 461 void set_display_protocol(const std::string& protocol) { | 455 void set_display_protocol(const std::string& protocol) { |
| 462 display_protocol_ = protocol; | 456 display_protocol_ = protocol; |
| 463 } | 457 } |
| 464 | 458 |
| 465 // Returns the (minimum) size of frames (sans variable-length portions). | 459 // Returns the (minimum) size of frames (sans variable-length portions). |
| 466 size_t GetDataFrameMinimumSize() const; | 460 size_t GetDataFrameMinimumSize() const; |
| 467 size_t GetControlFrameHeaderSize() const; | 461 size_t GetControlFrameHeaderSize() const; |
| 468 size_t GetSynStreamMinimumSize() const; | 462 size_t GetSynStreamMinimumSize() const; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 | 500 |
| 507 SpdyPriority GetLowestPriority() const { | 501 SpdyPriority GetLowestPriority() const { |
| 508 return spdy_version_ < SPDY3 ? 3 : 7; | 502 return spdy_version_ < SPDY3 ? 3 : 7; |
| 509 } | 503 } |
| 510 | 504 |
| 511 SpdyPriority GetHighestPriority() const { return 0; } | 505 SpdyPriority GetHighestPriority() const { return 0; } |
| 512 | 506 |
| 513 // Deliver the given control frame's compressed headers block to the visitor | 507 // Deliver the given control frame's compressed headers block to the visitor |
| 514 // in decompressed form, in chunks. Returns true if the visitor has | 508 // in decompressed form, in chunks. Returns true if the visitor has |
| 515 // accepted all of the chunks. | 509 // accepted all of the chunks. |
| 516 bool IncrementallyDecompressControlFrameHeaderData( | 510 bool IncrementallyDecompressControlFrameHeaderData(SpdyStreamId stream_id, |
| 517 SpdyStreamId stream_id, | 511 const char* data, |
| 518 const char* data, | 512 size_t len); |
| 519 size_t len); | |
| 520 | 513 |
| 521 protected: | 514 protected: |
| 522 // TODO(jgraettinger): Switch to test peer pattern. | 515 // TODO(jgraettinger): Switch to test peer pattern. |
| 523 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, BasicCompression); | 516 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, BasicCompression); |
| 524 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameSizesAreValidated); | 517 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameSizesAreValidated); |
| 525 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HeaderCompression); | 518 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HeaderCompression); |
| 526 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DecompressUncompressedFrame); | 519 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DecompressUncompressedFrame); |
| 527 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash); | 520 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash); |
| 528 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock); | 521 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock); |
| 529 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors); | 522 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors); |
| 530 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, | 523 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, |
| 531 UnclosedStreamDataCompressorsOneByteAtATime); | 524 UnclosedStreamDataCompressorsOneByteAtATime); |
| 532 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, | 525 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, |
| 533 UncompressLargerThanFrameBufferInitialSize); | 526 UncompressLargerThanFrameBufferInitialSize); |
| 534 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrame); | 527 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrame); |
| 535 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, | 528 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrameInSmallChunks); |
| 536 ReadLargeSettingsFrameInSmallChunks); | |
| 537 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameAtMaxSizeLimit); | 529 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameAtMaxSizeLimit); |
| 538 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameTooLarge); | 530 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameTooLarge); |
| 539 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, | 531 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, |
| 540 TooLargeHeadersFrameUsesContinuation); | 532 TooLargeHeadersFrameUsesContinuation); |
| 541 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, | 533 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, |
| 542 TooLargePushPromiseFrameUsesContinuation); | 534 TooLargePushPromiseFrameUsesContinuation); |
| 543 friend class net::HttpNetworkLayer; // This is temporary for the server. | 535 friend class net::HttpNetworkLayer; // This is temporary for the server. |
| 544 friend class net::HttpNetworkTransactionTest; | 536 friend class net::HttpNetworkTransactionTest; |
| 545 friend class net::HttpProxyClientSocketPoolTest; | 537 friend class net::HttpProxyClientSocketPoolTest; |
| 546 friend class net::SpdyHttpStreamTest; | 538 friend class net::SpdyHttpStreamTest; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 bool IncrementallyDeliverControlFrameHeaderData(SpdyStreamId stream_id, | 598 bool IncrementallyDeliverControlFrameHeaderData(SpdyStreamId stream_id, |
| 607 const char* data, | 599 const char* data, |
| 608 size_t len); | 600 size_t len); |
| 609 | 601 |
| 610 // Utility to copy the given data block to the current frame buffer, up | 602 // Utility to copy the given data block to the current frame buffer, up |
| 611 // to the given maximum number of bytes, and update the buffer | 603 // to the given maximum number of bytes, and update the buffer |
| 612 // data (pointer and length). Returns the number of bytes | 604 // data (pointer and length). Returns the number of bytes |
| 613 // read, and: | 605 // read, and: |
| 614 // *data is advanced the number of bytes read. | 606 // *data is advanced the number of bytes read. |
| 615 // *len is reduced by the number of bytes read. | 607 // *len is reduced by the number of bytes read. |
| 616 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, | 608 size_t UpdateCurrentFrameBuffer(const char** data, |
| 609 size_t* len, |
| 617 size_t max_bytes); | 610 size_t max_bytes); |
| 618 | 611 |
| 619 void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, | 612 void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, z_stream* out) const; |
| 620 z_stream* out) const; | |
| 621 | 613 |
| 622 void SerializeNameValueBlockWithoutCompression( | 614 void SerializeNameValueBlockWithoutCompression( |
| 623 SpdyFrameBuilder* builder, | 615 SpdyFrameBuilder* builder, |
| 624 const SpdyNameValueBlock& name_value_block) const; | 616 const SpdyNameValueBlock& name_value_block) const; |
| 625 | 617 |
| 626 // Compresses automatically according to enable_compression_. | 618 // Compresses automatically according to enable_compression_. |
| 627 void SerializeNameValueBlock( | 619 void SerializeNameValueBlock(SpdyFrameBuilder* builder, |
| 628 SpdyFrameBuilder* builder, | 620 const SpdyFrameWithNameValueBlockIR& frame); |
| 629 const SpdyFrameWithNameValueBlockIR& frame); | |
| 630 | 621 |
| 631 // Set the error code and moves the framer into the error state. | 622 // Set the error code and moves the framer into the error state. |
| 632 void set_error(SpdyError error); | 623 void set_error(SpdyError error); |
| 633 | 624 |
| 634 // The maximum size of the control frames that we support. | 625 // The maximum size of the control frames that we support. |
| 635 // This limit is arbitrary. We can enforce it here or at the application | 626 // This limit is arbitrary. We can enforce it here or at the application |
| 636 // layer. We chose the framing layer, but this can be changed (or removed) | 627 // layer. We chose the framing layer, but this can be changed (or removed) |
| 637 // if necessary later down the line. | 628 // if necessary later down the line. |
| 638 size_t GetControlFrameBufferMaxSize() const { | 629 size_t GetControlFrameBufferMaxSize() const { |
| 639 // The theoretical maximum for SPDY3 and earlier is (2^24 - 1) + | 630 // The theoretical maximum for SPDY3 and earlier is (2^24 - 1) + |
| 640 // 8, since the length field does not count the size of the | 631 // 8, since the length field does not count the size of the |
| 641 // header. | 632 // header. |
| 642 if (spdy_version_ == SPDY2) { | 633 if (spdy_version_ == SPDY2) { |
| 643 return 64 * 1024; | 634 return 64 * 1024; |
| 644 } | 635 } |
| 645 if (spdy_version_ == SPDY3) { | 636 if (spdy_version_ == SPDY3) { |
| 646 return 16 * 1024 * 1024; | 637 return 16 * 1024 * 1024; |
| 647 } | 638 } |
| 648 // Absolute maximum size of HTTP2 frame payload (section 4.2 "Frame size"). | 639 // Absolute maximum size of HTTP2 frame payload (section 4.2 "Frame size"). |
| 649 return (1<<14) - 1; | 640 return (1 << 14) - 1; |
| 650 } | 641 } |
| 651 | 642 |
| 652 // The size of the control frame buffer. | 643 // The size of the control frame buffer. |
| 653 // Since this is only used for control frame headers, the maximum control | 644 // Since this is only used for control frame headers, the maximum control |
| 654 // frame header size (SYN_STREAM) is sufficient; all remaining control | 645 // frame header size (SYN_STREAM) is sufficient; all remaining control |
| 655 // frame data is streamed to the visitor. | 646 // frame data is streamed to the visitor. |
| 656 static const size_t kControlFrameBufferSize; | 647 static const size_t kControlFrameBufferSize; |
| 657 | 648 |
| 658 SpdyState state_; | 649 SpdyState state_; |
| 659 SpdyState previous_state_; | 650 SpdyState previous_state_; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 // If a HEADERS frame is followed by a CONTINUATION frame, the FIN/END_STREAM | 727 // If a HEADERS frame is followed by a CONTINUATION frame, the FIN/END_STREAM |
| 737 // flag is still carried in the HEADERS frame. If it's set, flip this so that | 728 // flag is still carried in the HEADERS frame. If it's set, flip this so that |
| 738 // we know to terminate the stream when the entire header block has been | 729 // we know to terminate the stream when the entire header block has been |
| 739 // processed. | 730 // processed. |
| 740 bool end_stream_when_done_; | 731 bool end_stream_when_done_; |
| 741 }; | 732 }; |
| 742 | 733 |
| 743 } // namespace net | 734 } // namespace net |
| 744 | 735 |
| 745 #endif // NET_SPDY_SPDY_FRAMER_H_ | 736 #endif // NET_SPDY_SPDY_FRAMER_H_ |
| OLD | NEW |