| 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 26 matching lines...) Expand all Loading... |
| 37 class SpdyFramer; | 37 class SpdyFramer; |
| 38 class SpdyFrameBuilder; | 38 class SpdyFrameBuilder; |
| 39 class SpdyFramerTest; | 39 class SpdyFramerTest; |
| 40 | 40 |
| 41 namespace test { | 41 namespace test { |
| 42 | 42 |
| 43 class TestSpdyVisitor; | 43 class TestSpdyVisitor; |
| 44 | 44 |
| 45 } // namespace test | 45 } // namespace test |
| 46 | 46 |
| 47 // A datastructure for holding a set of headers from either a |
| 48 // SYN_STREAM or SYN_REPLY frame. |
| 49 typedef std::map<std::string, std::string> SpdyHeaderBlock; |
| 50 |
| 47 // A datastructure for holding the ID and flag fields for SETTINGS. | 51 // A datastructure for holding the ID and flag fields for SETTINGS. |
| 48 // Conveniently handles converstion to/from wire format. | 52 // Conveniently handles converstion to/from wire format. |
| 49 class NET_EXPORT_PRIVATE SettingsFlagsAndId { | 53 class NET_EXPORT_PRIVATE SettingsFlagsAndId { |
| 50 public: | 54 public: |
| 51 static SettingsFlagsAndId FromWireFormat(int version, uint32 wire); | 55 static SettingsFlagsAndId FromWireFormat(int version, uint32 wire); |
| 52 | 56 |
| 53 SettingsFlagsAndId() : flags_(0), id_(0) {} | 57 SettingsFlagsAndId() : flags_(0), id_(0) {} |
| 54 | 58 |
| 55 // TODO(hkhalil): restrict to enums instead of free-form ints. | 59 // TODO(hkhalil): restrict to enums instead of free-form ints. |
| 56 SettingsFlagsAndId(uint8 flags, uint32 id); | 60 SettingsFlagsAndId(uint8 flags, uint32 id); |
| 57 | 61 |
| 58 uint32 GetWireFormat(int version) const; | 62 uint32 GetWireFormat(int version) const; |
| 59 | 63 |
| 60 uint32 id() const { return id_; } | 64 uint32 id() const { return id_; } |
| 61 uint8 flags() const { return flags_; } | 65 uint8 flags() const { return flags_; } |
| 62 | 66 |
| 63 private: | 67 private: |
| 64 static void ConvertFlagsAndIdForSpdy2(uint32* val); | 68 static void ConvertFlagsAndIdForSpdy2(uint32* val); |
| 65 | 69 |
| 66 uint8 flags_; | 70 uint8 flags_; |
| 67 uint32 id_; | 71 uint32 id_; |
| 68 }; | 72 }; |
| 69 | 73 |
| 70 // SettingsMap has unique (flags, value) pair for given SpdySettingsIds ID. | 74 // SettingsMap has unique (flags, value) pair for given SpdySettingsIds ID. |
| 71 typedef std::pair<SpdySettingsFlags, uint32> SettingsFlagsAndValue; | 75 typedef std::pair<SpdySettingsFlags, uint32> SettingsFlagsAndValue; |
| 72 typedef std::map<SpdySettingsIds, SettingsFlagsAndValue> SettingsMap; | 76 typedef std::map<SpdySettingsIds, SettingsFlagsAndValue> SettingsMap; |
| 73 | 77 |
| 74 // A datastrcture for holding the contents of a CREDENTIAL frame. | 78 // A datastrcture for holding the contents of a CREDENTIAL frame. |
| 79 // TODO(hkhalil): Remove, use SpdyCredentialIR instead. |
| 75 struct NET_EXPORT_PRIVATE SpdyCredential { | 80 struct NET_EXPORT_PRIVATE SpdyCredential { |
| 76 SpdyCredential(); | 81 SpdyCredential(); |
| 77 ~SpdyCredential(); | 82 ~SpdyCredential(); |
| 78 | 83 |
| 79 uint16 slot; | 84 uint16 slot; |
| 80 std::vector<std::string> certs; | 85 std::vector<std::string> certs; |
| 81 std::string proof; | 86 std::string proof; |
| 82 }; | 87 }; |
| 83 | 88 |
| 84 // Scratch space necessary for processing SETTINGS frames. | 89 // Scratch space necessary for processing SETTINGS frames. |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 // through OnControlFrameHeaderData. (It is exposed here for unit test | 297 // through OnControlFrameHeaderData. (It is exposed here for unit test |
| 293 // purposes.) | 298 // purposes.) |
| 294 static const size_t kHeaderDataChunkMaxSize; | 299 static const size_t kHeaderDataChunkMaxSize; |
| 295 | 300 |
| 296 // Serializes a SpdyHeaderBlock. | 301 // Serializes a SpdyHeaderBlock. |
| 297 static void WriteHeaderBlock(SpdyFrameBuilder* frame, | 302 static void WriteHeaderBlock(SpdyFrameBuilder* frame, |
| 298 const int spdy_version, | 303 const int spdy_version, |
| 299 const SpdyHeaderBlock* headers); | 304 const SpdyHeaderBlock* headers); |
| 300 | 305 |
| 301 // Retrieve serialized length of SpdyHeaderBlock. | 306 // Retrieve serialized length of SpdyHeaderBlock. |
| 307 // TODO(hkhalil): Change to const reference instead of const pointer. |
| 302 static size_t GetSerializedLength(const int spdy_version, | 308 static size_t GetSerializedLength(const int spdy_version, |
| 303 const SpdyHeaderBlock* headers); | 309 const SpdyHeaderBlock* headers); |
| 304 | 310 |
| 305 // Create a new Framer, provided a SPDY version. | 311 // Create a new Framer, provided a SPDY version. |
| 306 explicit SpdyFramer(int version); | 312 explicit SpdyFramer(int version); |
| 307 virtual ~SpdyFramer(); | 313 virtual ~SpdyFramer(); |
| 308 | 314 |
| 309 // Set callbacks to be called from the framer. A visitor must be set, or | 315 // Set callbacks to be called from the framer. A visitor must be set, or |
| 310 // else the framer will likely crash. It is acceptable for the visitor | 316 // else the framer will likely crash. It is acceptable for the visitor |
| 311 // to do nothing. If this is called multiple times, only the last visitor | 317 // to do nothing. If this is called multiple times, only the last visitor |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. | 359 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. |
| 354 // |compressed| specifies whether the frame should be compressed. | 360 // |compressed| specifies whether the frame should be compressed. |
| 355 // |headers| is the header block to include in the frame. | 361 // |headers| is the header block to include in the frame. |
| 356 SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id, | 362 SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id, |
| 357 SpdyStreamId associated_stream_id, | 363 SpdyStreamId associated_stream_id, |
| 358 SpdyPriority priority, | 364 SpdyPriority priority, |
| 359 uint8 credential_slot, | 365 uint8 credential_slot, |
| 360 SpdyControlFlags flags, | 366 SpdyControlFlags flags, |
| 361 bool compressed, | 367 bool compressed, |
| 362 const SpdyHeaderBlock* headers); | 368 const SpdyHeaderBlock* headers); |
| 369 SpdySerializedFrame* SerializeSynStream(const SpdySynStreamIR& syn_stream); |
| 363 | 370 |
| 364 // Create a SpdySynReplyControlFrame. | 371 // Create a SpdySynReplyControlFrame. |
| 365 // |stream_id| is the stream for this frame. | 372 // |stream_id| is the stream for this frame. |
| 366 // |flags| is the flags to use with the data. | 373 // |flags| is the flags to use with the data. |
| 367 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. | 374 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. |
| 368 // |compressed| specifies whether the frame should be compressed. | 375 // |compressed| specifies whether the frame should be compressed. |
| 369 // |headers| is the header block to include in the frame. | 376 // |headers| is the header block to include in the frame. |
| 370 SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id, | 377 SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id, |
| 371 SpdyControlFlags flags, | 378 SpdyControlFlags flags, |
| 372 bool compressed, | 379 bool compressed, |
| 373 const SpdyHeaderBlock* headers); | 380 const SpdyHeaderBlock* headers); |
| 381 SpdySerializedFrame* SerializeSynReply(const SpdySynReplyIR& syn_reply); |
| 374 | 382 |
| 375 SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, | 383 SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, |
| 376 SpdyRstStreamStatus status) const; | 384 SpdyRstStreamStatus status) const; |
| 385 SpdySerializedFrame* SerializeRstStream( |
| 386 const SpdyRstStreamIR& rst_stream) const; |
| 377 | 387 |
| 378 // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is | 388 // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is |
| 379 // used to communicate name/value pairs relevant to the communication channel. | 389 // used to communicate name/value pairs relevant to the communication channel. |
| 380 SpdySettingsControlFrame* CreateSettings(const SettingsMap& values) const; | 390 SpdySettingsControlFrame* CreateSettings(const SettingsMap& values) const; |
| 391 SpdySerializedFrame* SerializeSettings(const SpdySettingsIR& settings) const; |
| 381 | 392 |
| 382 // Creates an instance of SpdyPingControlFrame. The unique_id is used to | 393 // Creates an instance of SpdyPingControlFrame. The unique_id is used to |
| 383 // identify the ping request/response. | 394 // identify the ping request/response. |
| 384 SpdyPingControlFrame* CreatePingFrame(uint32 unique_id) const; | 395 SpdyPingControlFrame* CreatePingFrame(uint32 unique_id) const; |
| 396 SpdySerializedFrame* SerializePing(const SpdyPingIR& ping) const; |
| 385 | 397 |
| 386 // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used | 398 // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used |
| 387 // prior to the shutting down of the TCP connection, and includes the | 399 // prior to the shutting down of the TCP connection, and includes the |
| 388 // stream_id of the last stream the sender of the frame is willing to process | 400 // stream_id of the last stream the sender of the frame is willing to process |
| 389 // to completion. | 401 // to completion. |
| 390 SpdyGoAwayControlFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id, | 402 SpdyGoAwayControlFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id, |
| 391 SpdyGoAwayStatus status) const; | 403 SpdyGoAwayStatus status) const; |
| 404 SpdySerializedFrame* SerializeGoAway(const SpdyGoAwayIR& goaway) const; |
| 392 | 405 |
| 393 // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used | 406 // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used |
| 394 // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The | 407 // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The |
| 395 // arguments are the same as for CreateSynReply. | 408 // arguments are the same as for CreateSynReply. |
| 396 SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id, | 409 SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id, |
| 397 SpdyControlFlags flags, | 410 SpdyControlFlags flags, |
| 398 bool compressed, | 411 bool compressed, |
| 399 const SpdyHeaderBlock* headers); | 412 const SpdyHeaderBlock* headers); |
| 413 SpdySerializedFrame* SerializeHeaders(const SpdyHeadersIR& headers); |
| 400 | 414 |
| 401 // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE | 415 // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE |
| 402 // frame is used to implement per stream flow control in SPDY. | 416 // frame is used to implement per stream flow control in SPDY. |
| 403 SpdyWindowUpdateControlFrame* CreateWindowUpdate( | 417 SpdyWindowUpdateControlFrame* CreateWindowUpdate( |
| 404 SpdyStreamId stream_id, | 418 SpdyStreamId stream_id, |
| 405 uint32 delta_window_size) const; | 419 uint32 delta_window_size) const; |
| 420 SpdySerializedFrame* SerializeWindowUpdate( |
| 421 const SpdyWindowUpdateIR& window_update) const; |
| 406 | 422 |
| 407 // Creates an instance of SpdyCredentialControlFrame. The CREDENTIAL | 423 // Creates an instance of SpdyCredentialControlFrame. The CREDENTIAL |
| 408 // frame is used to send a client certificate to the server when | 424 // frame is used to send a client certificate to the server when |
| 409 // request more than one origin are sent over the same SPDY session. | 425 // request more than one origin are sent over the same SPDY session. |
| 410 SpdyCredentialControlFrame* CreateCredentialFrame( | 426 SpdyCredentialControlFrame* CreateCredentialFrame( |
| 411 const SpdyCredential& credential) const; | 427 const SpdyCredential& credential) const; |
| 428 SpdySerializedFrame* SerializeCredential( |
| 429 const SpdyCredentialIR& credential) const; |
| 412 | 430 |
| 413 // Given a SpdySettingsControlFrame, extract the settings. | 431 // Given a SpdySettingsControlFrame, extract the settings. |
| 414 // Returns true on successful parse, false otherwise. | 432 // Returns true on successful parse, false otherwise. |
| 415 static bool ParseSettings(const SpdySettingsControlFrame* frame, | 433 static bool ParseSettings(const SpdySettingsControlFrame* frame, |
| 416 SettingsMap* settings); | 434 SettingsMap* settings); |
| 417 | 435 |
| 418 // Given a SpdyCredentialControlFrame's payload, extract the credential. | 436 // Given a SpdyCredentialControlFrame's payload, extract the credential. |
| 419 // Returns true on successful parse, false otherwise. | 437 // Returns true on successful parse, false otherwise. |
| 420 // TODO(hkhalil): Implement CREDENTIAL frame parsing in SpdyFramer | 438 // TODO(hkhalil): Implement CREDENTIAL frame parsing in SpdyFramer |
| 421 // and eliminate this method. | 439 // and eliminate this method. |
| 422 static bool ParseCredentialData(const char* data, size_t len, | 440 static bool ParseCredentialData(const char* data, size_t len, |
| 423 SpdyCredential* credential); | 441 SpdyCredential* credential); |
| 424 | 442 |
| 425 // Create a data frame. | 443 // Create a data frame. |
| 426 // |stream_id| is the stream for this frame | 444 // |stream_id| is the stream for this frame |
| 427 // |data| is the data to be included in the frame. | 445 // |data| is the data to be included in the frame. |
| 428 // |len| is the length of the data | 446 // |len| is the length of the data |
| 429 // |flags| is the flags to use with the data. | 447 // |flags| is the flags to use with the data. |
| 430 // To mark this frame as the last data frame, enable DATA_FLAG_FIN. | 448 // To mark this frame as the last data frame, enable DATA_FLAG_FIN. |
| 431 SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id, const char* data, | 449 SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id, const char* data, |
| 432 uint32 len, SpdyDataFlags flags) const; | 450 uint32 len, SpdyDataFlags flags) const; |
| 451 SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const; |
| 433 | 452 |
| 434 // NOTES about frame compression. | 453 // NOTES about frame compression. |
| 435 // We want spdy to compress headers across the entire session. As long as | 454 // We want spdy to compress headers across the entire session. As long as |
| 436 // the session is over TCP, frames are sent serially. The client & server | 455 // the session is over TCP, frames are sent serially. The client & server |
| 437 // can each compress frames in the same order and then compress them in that | 456 // can each compress frames in the same order and then compress them in that |
| 438 // order, and the remote can do the reverse. However, we ultimately want | 457 // order, and the remote can do the reverse. However, we ultimately want |
| 439 // the creation of frames to be less sensitive to order so that they can be | 458 // the creation of frames to be less sensitive to order so that they can be |
| 440 // placed over a UDP based protocol and yet still benefit from some | 459 // placed over a UDP based protocol and yet still benefit from some |
| 441 // compression. We don't know of any good compression protocol which does | 460 // compression. We don't know of any good compression protocol which does |
| 442 // not build its state in a serial (stream based) manner.... For now, we're | 461 // not build its state in a serial (stream based) manner.... For now, we're |
| (...skipping 17 matching lines...) Expand all Loading... |
| 460 // type. This is useful for validating frame blocks. | 479 // type. This is useful for validating frame blocks. |
| 461 static size_t GetMinimumControlFrameSize(int version, SpdyControlType type); | 480 static size_t GetMinimumControlFrameSize(int version, SpdyControlType type); |
| 462 | 481 |
| 463 // Get the stream ID for the given control frame (SYN_STREAM, SYN_REPLY, and | 482 // Get the stream ID for the given control frame (SYN_STREAM, SYN_REPLY, and |
| 464 // HEADERS). If the control frame is NULL or of another type, this | 483 // HEADERS). If the control frame is NULL or of another type, this |
| 465 // function returns kInvalidStream. | 484 // function returns kInvalidStream. |
| 466 static SpdyStreamId GetControlFrameStreamId( | 485 static SpdyStreamId GetControlFrameStreamId( |
| 467 const SpdyControlFrame* control_frame); | 486 const SpdyControlFrame* control_frame); |
| 468 | 487 |
| 469 // For ease of testing and experimentation we can tweak compression on/off. | 488 // For ease of testing and experimentation we can tweak compression on/off. |
| 470 void set_enable_compression(bool value); | 489 void set_enable_compression(bool value) { |
| 490 enable_compression_ = value; |
| 491 } |
| 471 | 492 |
| 472 // Used only in log messages. | 493 // Used only in log messages. |
| 473 void set_display_protocol(const std::string& protocol) { | 494 void set_display_protocol(const std::string& protocol) { |
| 474 display_protocol_ = protocol; | 495 display_protocol_ = protocol; |
| 475 } | 496 } |
| 476 | 497 |
| 477 // For debugging. | 498 // For debugging. |
| 478 static const char* StateToString(int state); | 499 static const char* StateToString(int state); |
| 479 static const char* ErrorCodeToString(int error_code); | 500 static const char* ErrorCodeToString(int error_code); |
| 480 static const char* StatusCodeToString(int status_code); | 501 static const char* StatusCodeToString(int status_code); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 // data (pointer and length). Returns the number of bytes | 574 // data (pointer and length). Returns the number of bytes |
| 554 // read, and: | 575 // read, and: |
| 555 // *data is advanced the number of bytes read. | 576 // *data is advanced the number of bytes read. |
| 556 // *len is reduced by the number of bytes read. | 577 // *len is reduced by the number of bytes read. |
| 557 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, | 578 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, |
| 558 size_t max_bytes); | 579 size_t max_bytes); |
| 559 | 580 |
| 560 void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, | 581 void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, |
| 561 z_stream* out) const; | 582 z_stream* out) const; |
| 562 | 583 |
| 584 void SerializeNameValueBlock( |
| 585 SpdyFrameBuilder* builder, |
| 586 const SpdyFrameWithNameValueBlockIR& frame) const; |
| 587 |
| 563 // Set the error code and moves the framer into the error state. | 588 // Set the error code and moves the framer into the error state. |
| 564 void set_error(SpdyError error); | 589 void set_error(SpdyError error); |
| 565 | 590 |
| 566 // Given a frame, breakdown the variable payload length, the static header | 591 // Given a frame, breakdown the variable payload length, the static header |
| 567 // header length, and variable payload pointer. | 592 // header length, and variable payload pointer. |
| 568 bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length, | 593 bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length, |
| 569 int* header_length, const char** payload) const; | 594 int* header_length, const char** payload) const; |
| 570 | 595 |
| 571 // Returns a new SpdyControlFrame with the compressed payload of |frame|. | 596 // Returns a new SpdyControlFrame with the compressed payload of |frame|. |
| 572 SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame, | 597 SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 // starts with HTTP. If it does, we likely have an HTTP response. This | 659 // starts with HTTP. If it does, we likely have an HTTP response. This |
| 635 // isn't guaranteed though: we could have gotten a settings frame and then | 660 // isn't guaranteed though: we could have gotten a settings frame and then |
| 636 // corrupt data that just looks like HTTP, but deterministic checking requires | 661 // corrupt data that just looks like HTTP, but deterministic checking requires |
| 637 // a lot more state. | 662 // a lot more state. |
| 638 bool probable_http_response_; | 663 bool probable_http_response_; |
| 639 }; | 664 }; |
| 640 | 665 |
| 641 } // namespace net | 666 } // namespace net |
| 642 | 667 |
| 643 #endif // NET_SPDY_SPDY_FRAMER_H_ | 668 #endif // NET_SPDY_SPDY_FRAMER_H_ |
| OLD | NEW |