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
3// found in the LICENSE file.
4
5#ifndef NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_
6#define NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/compiler_specific.h"
13#include "base/memory/scoped_ptr.h"
14#include "net/spdy/buffered_spdy_framer.h"
15#include "net/spdy/spdy_protocol.h"
16#include "net/tools/balsa/balsa_headers.h"
17#include "net/tools/balsa/balsa_visitor_interface.h"
18#include "net/tools/flip_server/output_ordering.h"
19#include "net/tools/flip_server/sm_connection.h"
20#include "net/tools/flip_server/sm_interface.h"
21
22namespace net {
23
24class FlipAcceptor;
25class MemoryCache;
26
27class SpdySM : public BufferedSpdyFramerVisitorInterface, public SMInterface {
28 public:
29  SpdySM(SMConnection* connection,
30         SMInterface* sm_http_interface,
31         EpollServer* epoll_server,
32         MemoryCache* memory_cache,
33         FlipAcceptor* acceptor,
34         SpdyMajorVersion spdy_version);
35  virtual ~SpdySM();
36
37  virtual void InitSMInterface(SMInterface* sm_http_interface,
38                               int32 server_idx) OVERRIDE {}
39
40  virtual void InitSMConnection(SMConnectionPoolInterface* connection_pool,
41                                SMInterface* sm_interface,
42                                EpollServer* epoll_server,
43                                int fd,
44                                std::string server_ip,
45                                std::string server_port,
46                                std::string remote_ip,
47                                bool use_ssl) OVERRIDE;
48
49  // Create new SPDY framer after reusing SpdySM and negotiating new version
50  void CreateFramer(SpdyMajorVersion spdy_version);
51
52 private:
53  virtual void set_is_request() OVERRIDE {}
54  SMInterface* NewConnectionInterface();
55  // virtual for tests
56  virtual SMInterface* FindOrMakeNewSMConnectionInterface(
57      const std::string& server_ip,
58      const std::string& server_port);
59  int SpdyHandleNewStream(SpdyStreamId stream_id,
60                          SpdyPriority priority,
61                          const SpdyHeaderBlock& headers,
62                          std::string& http_data,
63                          bool* is_https_scheme);
64
65  // BufferedSpdyFramerVisitorInterface:
66  virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE {}
67  virtual void OnStreamError(SpdyStreamId stream_id,
68                             const std::string& description) OVERRIDE {}
69  // Called after all the header data for SYN_STREAM control frame is received.
70  virtual void OnSynStream(SpdyStreamId stream_id,
71                           SpdyStreamId associated_stream_id,
72                           SpdyPriority priority,
73                           bool fin,
74                           bool unidirectional,
75                           const SpdyHeaderBlock& headers) OVERRIDE;
76
77  // Called after all the header data for SYN_REPLY control frame is received.
78  virtual void OnSynReply(SpdyStreamId stream_id,
79                          bool fin,
80                          const SpdyHeaderBlock& headers) OVERRIDE;
81
82  // Called after all the header data for HEADERS control frame is received.
83  virtual void OnHeaders(SpdyStreamId stream_id,
84                         bool fin,
85                         const SpdyHeaderBlock& headers) OVERRIDE;
86
87  // Called when data frame header is received.
88  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
89                                 size_t length,
90                                 bool fin) OVERRIDE {}
91
92  // Called when data is received.
93  // |stream_id| The stream receiving data.
94  // |data| A buffer containing the data received.
95  // |len| The length of the data buffer.
96  // When the other side has finished sending data on this stream,
97  // this method will be called with a zero-length buffer.
98  virtual void OnStreamFrameData(SpdyStreamId stream_id,
99                                 const char* data,
100                                 size_t len,
101                                 bool fin) OVERRIDE;
102
103  // Called when a SETTINGS frame is received.
104  // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
105  virtual void OnSettings(bool clear_persisted) OVERRIDE {}
106
107  // Called when an individual setting within a SETTINGS frame has been parsed
108  // and validated.
109  virtual void OnSetting(SpdySettingsIds id,
110                         uint8 flags,
111                         uint32 value) OVERRIDE {}
112
113  // Called when a PING frame has been parsed.
114  virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
115
116  // Called when a RST_STREAM frame has been parsed.
117  virtual void OnRstStream(SpdyStreamId stream_id,
118                           SpdyRstStreamStatus status) OVERRIDE;
119
120  // Called when a GOAWAY frame has been parsed.
121  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
122                        SpdyGoAwayStatus status) OVERRIDE {}
123
124  // Called when a WINDOW_UPDATE frame has been parsed.
125  virtual void OnWindowUpdate(SpdyStreamId stream_id,
126                              uint32 delta_window_size) OVERRIDE {}
127
128  // Called when a PUSH_PROMISE frame has been parsed.
129  virtual void OnPushPromise(SpdyStreamId stream_id,
130                             SpdyStreamId promised_stream_id,
131                             const SpdyHeaderBlock& headers) OVERRIDE {}
132
133  virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE;
134
135 public:
136  virtual size_t ProcessReadInput(const char* data, size_t len) OVERRIDE;
137  virtual size_t ProcessWriteInput(const char* data, size_t len) OVERRIDE;
138  virtual bool MessageFullyRead() const OVERRIDE;
139  virtual void SetStreamID(uint32 stream_id) OVERRIDE {}
140  virtual bool Error() const OVERRIDE;
141  virtual const char* ErrorAsString() const OVERRIDE;
142  virtual void Reset() OVERRIDE {}
143  virtual void ResetForNewInterface(int32 server_idx) OVERRIDE;
144  virtual void ResetForNewConnection() OVERRIDE;
145  // SMInterface's Cleanup is currently only called by SMConnection after a
146  // protocol message as been fully read. Spdy's SMInterface does not need
147  // to do any cleanup at this time.
148  // TODO(klindsay) This method is probably not being used properly and
149  // some logic review and method renaming is probably in order.
150  virtual void Cleanup() OVERRIDE {}
151  // Send a settings frame
152  virtual int PostAcceptHook() OVERRIDE;
153  virtual void NewStream(uint32 stream_id,
154                         uint32 priority,
155                         const std::string& filename) OVERRIDE;
156  void AddToOutputOrder(const MemCacheIter& mci);
157  virtual void SendEOF(uint32 stream_id) OVERRIDE;
158  virtual void SendErrorNotFound(uint32 stream_id) OVERRIDE;
159  virtual size_t SendSynStream(uint32 stream_id,
160                               const BalsaHeaders& headers) OVERRIDE;
161  virtual size_t SendSynReply(uint32 stream_id,
162                              const BalsaHeaders& headers) OVERRIDE;
163  virtual void SendDataFrame(uint32 stream_id,
164                             const char* data,
165                             int64 len,
166                             uint32 flags,
167                             bool compress) OVERRIDE;
168  BufferedSpdyFramer* spdy_framer() { return buffered_spdy_framer_.get(); }
169
170  const OutputOrdering& output_ordering() const {
171    return client_output_ordering_;
172  }
173
174  static std::string forward_ip_header() { return forward_ip_header_; }
175  static void set_forward_ip_header(const std::string& value) {
176    forward_ip_header_ = value;
177  }
178  SpdyMajorVersion spdy_version() const {
179    DCHECK(buffered_spdy_framer_);
180    return buffered_spdy_framer_->protocol_version();
181  }
182
183 private:
184  void SendEOFImpl(uint32 stream_id);
185  void SendErrorNotFoundImpl(uint32 stream_id);
186  void KillStream(uint32 stream_id);
187  void CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers);
188  size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers);
189  size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers);
190  void SendDataFrameImpl(uint32 stream_id,
191                         const char* data,
192                         int64 len,
193                         SpdyDataFlags flags,
194                         bool compress);
195  void EnqueueDataFrame(DataFrame* df);
196  virtual void GetOutput() OVERRIDE;
197
198 private:
199  scoped_ptr<BufferedSpdyFramer> buffered_spdy_framer_;
200  bool valid_spdy_session_;  // True if we have seen valid data on this session.
201                             // Use this to fail fast when junk is sent to our
202                             // port.
203
204  SMConnection* connection_;
205  OutputList* client_output_list_;
206  OutputOrdering client_output_ordering_;
207  uint32 next_outgoing_stream_id_;
208  EpollServer* epoll_server_;
209  FlipAcceptor* acceptor_;
210  MemoryCache* memory_cache_;
211  std::vector<SMInterface*> server_interface_list;
212  std::vector<int32> unused_server_interface_list;
213  typedef std::map<uint32, SMInterface*> StreamToSmif;
214  StreamToSmif stream_to_smif_;
215  bool close_on_error_;
216
217  static std::string forward_ip_header_;
218};
219
220}  // namespace net
221
222#endif  // NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_H_
223