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 |