| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_ |
| #define NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/compiler_specific.h" |
| #include "net/spdy/buffered_spdy_framer.h" |
| #include "net/spdy/spdy_alt_svc_wire_format.h" |
| #include "net/spdy/spdy_protocol.h" |
| #include "net/tools/balsa/balsa_headers.h" |
| #include "net/tools/balsa/balsa_visitor_interface.h" |
| #include "net/tools/flip_server/output_ordering.h" |
| #include "net/tools/flip_server/sm_connection.h" |
| #include "net/tools/flip_server/sm_interface.h" |
| |
| namespace net { |
| |
| class FlipAcceptor; |
| class MemoryCache; |
| |
| class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface { |
| public: |
| SpdySM(SMConnection* connection, |
| SMInterface* sm_http_interface, |
| EpollServer* epoll_server, |
| MemoryCache* memory_cache, |
| FlipAcceptor* acceptor, |
| SpdyMajorVersion spdy_version); |
| ~SpdySM() override; |
| |
| void InitSMInterface(SMInterface* sm_http_interface, |
| int32_t server_idx) override {} |
| |
| void InitSMConnection(SMConnectionPoolInterface* connection_pool, |
| SMInterface* sm_interface, |
| EpollServer* epoll_server, |
| int fd, |
| std::string server_ip, |
| std::string server_port, |
| std::string remote_ip, |
| bool use_ssl) override; |
| |
| // Create new SPDY framer after reusing SpdySM and negotiating new version |
| void CreateFramer(SpdyMajorVersion spdy_version); |
| |
| private: |
| void set_is_request() override {} |
| SMInterface* NewConnectionInterface(); |
| // virtual for tests |
| virtual SMInterface* FindOrMakeNewSMConnectionInterface( |
| const std::string& server_ip, |
| const std::string& server_port); |
| int SpdyHandleNewStream(SpdyStreamId stream_id, |
| SpdyPriority priority, |
| const SpdyHeaderBlock& headers, |
| std::string& http_data, |
| bool* is_https_scheme); |
| |
| // BufferedSpdyFramerVisitorInterface: |
| void OnError(SpdyFramer::SpdyError error_code) override {} |
| void OnStreamError(SpdyStreamId stream_id, |
| const std::string& description) override {} |
| // Called after all the header data for SYN_STREAM control frame is received. |
| void OnSynStream(SpdyStreamId stream_id, |
| SpdyStreamId associated_stream_id, |
| SpdyPriority priority, |
| bool fin, |
| bool unidirectional, |
| const SpdyHeaderBlock& headers) override; |
| |
| // Called after all the header data for SYN_REPLY control frame is received. |
| void OnSynReply(SpdyStreamId stream_id, |
| bool fin, |
| const SpdyHeaderBlock& headers) override; |
| |
| // Called after all the header data for HEADERS control frame is received. |
| void OnHeaders(SpdyStreamId stream_id, |
| bool has_priority, |
| int weight, |
| SpdyStreamId parent_stream_id, |
| bool exclusive, |
| bool fin, |
| const SpdyHeaderBlock& headers) override; |
| |
| // Called when data frame header is received. |
| void OnDataFrameHeader(SpdyStreamId stream_id, |
| size_t length, |
| bool fin) override {} |
| |
| // Called when data is received. |
| // |stream_id| The stream receiving data. |
| // |data| A buffer containing the data received. |
| // |len| The length of the data buffer. |
| void OnStreamFrameData(SpdyStreamId stream_id, |
| const char* data, |
| size_t len) override; |
| |
| // Called when the other side has finished sending data on this stream. |
| // |stream_id| The stream that was receivin data. |
| void OnStreamEnd(SpdyStreamId stream_id) override; |
| |
| // Called when padding is received (padding length field or padding octets). |
| // |stream_id| The stream receiving data. |
| // |len| The number of padding octets. |
| void OnStreamPadding(SpdyStreamId stream_id, size_t len) override; |
| |
| // Called when a SETTINGS frame is received. |
| // |clear_persisted| True if the respective flag is set on the SETTINGS frame. |
| void OnSettings(bool clear_persisted) override {} |
| |
| // Called when an individual setting within a SETTINGS frame has been parsed |
| // and validated. |
| void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {} |
| |
| // Called when a PING frame has been parsed. |
| void OnPing(SpdyPingId unique_id, bool is_ack) override {} |
| |
| // Called when a RST_STREAM frame has been parsed. |
| void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override; |
| |
| // Called when a GOAWAY frame has been parsed. |
| void OnGoAway(SpdyStreamId last_accepted_stream_id, |
| SpdyGoAwayStatus status, |
| base::StringPiece debug_data) override {} |
| |
| // Called when a WINDOW_UPDATE frame has been parsed. |
| void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {} |
| |
| // Called when a PUSH_PROMISE frame has been parsed. |
| void OnPushPromise(SpdyStreamId stream_id, |
| SpdyStreamId promised_stream_id, |
| const SpdyHeaderBlock& headers) override {} |
| |
| // Called when an ALTSVC frame has been parsed. |
| void OnAltSvc(SpdyStreamId stream_id, |
| base::StringPiece origin, |
| const SpdyAltSvcWireFormat::AlternativeServiceVector& |
| altsvc_vector) override {} |
| |
| bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override; |
| |
| public: |
| size_t ProcessReadInput(const char* data, size_t len) override; |
| size_t ProcessWriteInput(const char* data, size_t len) override; |
| bool MessageFullyRead() const override; |
| void SetStreamID(uint32_t stream_id) override {} |
| bool Error() const override; |
| const char* ErrorAsString() const override; |
| void Reset() override {} |
| void ResetForNewInterface(int32_t server_idx) override; |
| void ResetForNewConnection() override; |
| // SMInterface's Cleanup is currently only called by SMConnection after a |
| // protocol message as been fully read. Spdy's SMInterface does not need |
| // to do any cleanup at this time. |
| // TODO(klindsay) This method is probably not being used properly and |
| // some logic review and method renaming is probably in order. |
| void Cleanup() override {} |
| // Send a settings frame |
| int PostAcceptHook() override; |
| void NewStream(uint32_t stream_id, |
| uint32_t priority, |
| const std::string& filename) override; |
| void AddToOutputOrder(const MemCacheIter& mci); |
| void SendEOF(uint32_t stream_id) override; |
| void SendErrorNotFound(uint32_t stream_id) override; |
| size_t SendSynStream(uint32_t stream_id, |
| const BalsaHeaders& headers) override; |
| size_t SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) override; |
| void SendDataFrame(uint32_t stream_id, |
| const char* data, |
| int64_t len, |
| uint32_t flags, |
| bool compress) override; |
| BufferedSpdyFramer* spdy_framer() { return buffered_spdy_framer_.get(); } |
| |
| const OutputOrdering& output_ordering() const { |
| return client_output_ordering_; |
| } |
| |
| static std::string forward_ip_header() { return forward_ip_header_; } |
| static void set_forward_ip_header(const std::string& value) { |
| forward_ip_header_ = value; |
| } |
| SpdyMajorVersion spdy_version() const { |
| DCHECK(buffered_spdy_framer_); |
| return buffered_spdy_framer_->protocol_version(); |
| } |
| |
| private: |
| void SendEOFImpl(uint32_t stream_id); |
| void SendErrorNotFoundImpl(uint32_t stream_id); |
| void KillStream(uint32_t stream_id); |
| void CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers); |
| size_t SendSynStreamImpl(uint32_t stream_id, const BalsaHeaders& headers); |
| size_t SendSynReplyImpl(uint32_t stream_id, const BalsaHeaders& headers); |
| void SendDataFrameImpl(uint32_t stream_id, |
| const char* data, |
| int64_t len, |
| SpdyDataFlags flags, |
| bool compress); |
| void EnqueueDataFrame(DataFrame* df); |
| void GetOutput() override; |
| |
| private: |
| std::unique_ptr<BufferedSpdyFramer> buffered_spdy_framer_; |
| bool valid_spdy_session_; // True if we have seen valid data on this session. |
| // Use this to fail fast when junk is sent to our |
| // port. |
| |
| SMConnection* connection_; |
| OutputList* client_output_list_; |
| OutputOrdering client_output_ordering_; |
| uint32_t next_outgoing_stream_id_; |
| EpollServer* epoll_server_; |
| FlipAcceptor* acceptor_; |
| MemoryCache* memory_cache_; |
| std::vector<SMInterface*> server_interface_list; |
| std::vector<int32_t> unused_server_interface_list; |
| typedef std::map<uint32_t, SMInterface*> StreamToSmif; |
| StreamToSmif stream_to_smif_; |
| bool close_on_error_; |
| |
| static std::string forward_ip_header_; |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_ |