C++程序  |  148行  |  5.76 KB

// Copyright (c) 2011 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_
#define NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_

#include <map>
#include <string>
#include <vector>

#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_protocol.h"
#include "net/tools/flip_server/balsa_headers.h"
#include "net/tools/flip_server/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 BalsaFrame;
class FlipAcceptor;
class MemoryCache;

class SpdySM : public spdy::SpdyFramerVisitorInterface,
               public SMInterface {
 public:
  SpdySM(SMConnection* connection,
         SMInterface* sm_http_interface,
         EpollServer* epoll_server,
         MemoryCache* memory_cache,
         FlipAcceptor* acceptor);
  virtual ~SpdySM();

  virtual void InitSMInterface(SMInterface* sm_http_interface,
                               int32 server_idx) {}

  virtual 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);

  static bool disable_data_compression() { return disable_data_compression_; }
  static void set_disable_data_compression(bool value) {
    disable_data_compression_ = value;
  }

 private:
  virtual void set_is_request() {}
  virtual void OnError(spdy::SpdyFramer* framer) {}
  SMInterface* NewConnectionInterface();
  SMInterface* FindOrMakeNewSMConnectionInterface(std::string server_ip,
                                                  std::string server_port);
  int SpdyHandleNewStream(const spdy::SpdyControlFrame* frame,
                          std::string &http_data,
                          bool *is_https_scheme);

  // SpdyFramerVisitor interface.
  virtual void OnControl(const spdy::SpdyControlFrame* frame);
  virtual bool OnControlFrameHeaderData(spdy::SpdyStreamId stream_id,
                                        const char* header_data,
                                        size_t len);
  virtual void OnDataFrameHeader(const spdy::SpdyDataFrame* frame);
  virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
                                 const char* data, size_t len);

 public:
  virtual size_t ProcessReadInput(const char* data, size_t len);
  virtual size_t ProcessWriteInput(const char* data, size_t len);
  virtual bool MessageFullyRead() const;
  virtual void SetStreamID(uint32 stream_id) {}
  virtual bool Error() const;
  virtual const char* ErrorAsString() const;
  virtual void Reset() {}
  virtual void ResetForNewInterface(int32 server_idx);
  virtual void ResetForNewConnection();
  // 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.
  virtual void Cleanup() {}
  // Send a settings frame
  virtual int PostAcceptHook();
  virtual void NewStream(uint32 stream_id,
                         uint32 priority,
                         const std::string& filename);
  void AddToOutputOrder(const MemCacheIter& mci);
  virtual void SendEOF(uint32 stream_id);
  virtual void SendErrorNotFound(uint32 stream_id);
  void SendOKResponse(uint32 stream_id, std::string* output);
  virtual size_t SendSynStream(uint32 stream_id, const BalsaHeaders& headers);
  virtual size_t SendSynReply(uint32 stream_id, const BalsaHeaders& headers);
  virtual void SendDataFrame(uint32 stream_id, const char* data, int64 len,
                             uint32 flags, bool compress);
  spdy::SpdyFramer* spdy_framer() { return spdy_framer_; }

  static std::string forward_ip_header() { return forward_ip_header_; }
  static void set_forward_ip_header(std::string value) {
    forward_ip_header_ = value;
  }

 private:
  void SendEOFImpl(uint32 stream_id);
  void SendErrorNotFoundImpl(uint32 stream_id);
  void SendOKResponseImpl(uint32 stream_id, std::string* output);
  void KillStream(uint32 stream_id);
  void CopyHeaders(spdy::SpdyHeaderBlock& dest, const BalsaHeaders& headers);
  size_t SendSynStreamImpl(uint32 stream_id, const BalsaHeaders& headers);
  size_t SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers);
  void SendDataFrameImpl(uint32 stream_id, const char* data, int64 len,
                         spdy::SpdyDataFlags flags, bool compress);
  void EnqueueDataFrame(DataFrame* df);
  virtual void GetOutput();
 private:
  uint64 seq_num_;
  spdy::SpdyFramer* 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 next_outgoing_stream_id_;
  EpollServer* epoll_server_;
  FlipAcceptor* acceptor_;
  MemoryCache* memory_cache_;
  std::vector<SMInterface*> server_interface_list;
  std::vector<int32> unused_server_interface_list;
  typedef std::map<uint32, SMInterface*> StreamToSmif;
  StreamToSmif stream_to_smif_;
  bool close_on_error_;

  static bool disable_data_compression_;
  static std::string forward_ip_header_;
};

}  // namespace net

#endif  // NET_TOOLS_FLIP_SERVER_SPDY_INTERFACE_