1// Copyright (c) 2011 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_
6#define NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "net/spdy/spdy_framer.h"
13#include "net/spdy/spdy_protocol.h"
14#include "net/tools/flip_server/balsa_headers.h"
15#include "net/tools/flip_server/balsa_visitor_interface.h"
16#include "net/tools/flip_server/output_ordering.h"
17#include "net/tools/flip_server/sm_connection.h"
18#include "net/tools/flip_server/sm_interface.h"
19
20namespace net {
21
22class BalsaFrame;
23class FlipAcceptor;
24class MemoryCache;
25
26class SpdySM : public spdy::SpdyFramerVisitorInterface,
27               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  virtual ~SpdySM();
35
36  virtual void InitSMInterface(SMInterface* sm_http_interface,
37                               int32 server_idx) {}
38
39  virtual void InitSMConnection(SMConnectionPoolInterface* connection_pool,
40                                SMInterface* sm_interface,
41                                EpollServer* epoll_server,
42                                int fd,
43                                std::string server_ip,
44                                std::string server_port,
45                                std::string remote_ip,
46                                bool use_ssl);
47
48  static bool disable_data_compression() { return disable_data_compression_; }
49  static void set_disable_data_compression(bool value) {
50    disable_data_compression_ = value;
51  }
52
53 private:
54  virtual void set_is_request() {}
55  virtual void OnError(spdy::SpdyFramer* framer) {}
56  SMInterface* NewConnectionInterface();
57  SMInterface* FindOrMakeNewSMConnectionInterface(std::string server_ip,
58                                                  std::string server_port);
59  int SpdyHandleNewStream(const spdy::SpdyControlFrame* frame,
60                          std::string &http_data,
61                          bool *is_https_scheme);
62
63  // SpdyFramerVisitor interface.
64  virtual void OnControl(const spdy::SpdyControlFrame* frame);
65  virtual bool OnControlFrameHeaderData(spdy::SpdyStreamId stream_id,
66                                        const char* header_data,
67                                        size_t len);
68  virtual void OnDataFrameHeader(const spdy::SpdyDataFrame* frame);
69  virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
70                                 const char* data, size_t len);
71
72 public:
73  virtual size_t ProcessReadInput(const char* data, size_t len);
74  virtual size_t ProcessWriteInput(const char* data, size_t len);
75  virtual bool MessageFullyRead() const;
76  virtual void SetStreamID(uint32 stream_id) {}
77  virtual bool Error() const;
78  virtual const char* ErrorAsString() const;
79  virtual void Reset() {}
80  virtual void ResetForNewInterface(int32 server_idx);
81  virtual void ResetForNewConnection();
82  // SMInterface's Cleanup is currently only called by SMConnection after a
83  // protocol message as been fully read. Spdy's SMInterface does not need
84  // to do any cleanup at this time.
85  // TODO (klindsay) This method is probably not being used properly and
86  // some logic review and method renaming is probably in order.
87  virtual void Cleanup() {}
88  // Send a settings frame
89  virtual int PostAcceptHook();
90  virtual void NewStream(uint32 stream_id,
91                         uint32 priority,
92                         const std::string& filename);
93  void AddToOutputOrder(const MemCacheIter& mci);
94  virtual void SendEOF(uint32 stream_id);
95  virtual void SendErrorNotFound(uint32 stream_id);
96  void SendOKResponse(uint32 stream_id, std::string* output);
97  virtual size_t SendSynStream(uint32 stream_id, const BalsaHeaders& headers);
98  virtual size_t SendSynReply(uint32 stream_id, const BalsaHeaders& headers);
99  virtual void SendDataFrame(uint32 stream_id, const char* data, int64 len,
100                             uint32 flags, bool compress);
101  spdy::SpdyFramer* spdy_framer() { return spdy_framer_; }
102
103  static std::string forward_ip_header() { return forward_ip_header_; }
104  static void set_forward_ip_header(std::string value) {
105    forward_ip_header_ = value;
106  }
107
108 private:
109  void SendEOFImpl(uint32 stream_id);
110  void SendErrorNotFoundImpl(uint32 stream_id);
111  void SendOKResponseImpl(uint32 stream_id, std::string* output);
112  void KillStream(uint32 stream_id);
113  void CopyHeaders(spdy::SpdyHeaderBlock& dest, const BalsaHeaders& headers);
114  size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers);
115  size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers);
116  void SendDataFrameImpl(uint32 stream_id, const char* data, int64 len,
117                         spdy::SpdyDataFlags flags, bool compress);
118  void EnqueueDataFrame(DataFrame* df);
119  virtual void GetOutput();
120 private:
121  uint64 seq_num_;
122  spdy::SpdyFramer* spdy_framer_;
123  bool valid_spdy_session_;  // True if we have seen valid data on this session.
124                             // Use this to fail fast when junk is sent to our
125                             // port.
126
127  SMConnection* connection_;
128  OutputList* client_output_list_;
129  OutputOrdering client_output_ordering_;
130  uint32 next_outgoing_stream_id_;
131  EpollServer* epoll_server_;
132  FlipAcceptor* acceptor_;
133  MemoryCache* memory_cache_;
134  std::vector<SMInterface*> server_interface_list;
135  std::vector<int32> unused_server_interface_list;
136  typedef std::map<uint32, SMInterface*> StreamToSmif;
137  StreamToSmif stream_to_smif_;
138  bool close_on_error_;
139
140  static bool disable_data_compression_;
141  static std::string forward_ip_header_;
142};
143
144}  // namespace net
145
146#endif  // NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_
147
148