| 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 | 
|---|