blob: 3d1cfa0a63fe88c2c65ff1be7d80c757c0a618db [file] [log] [blame]
// 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 <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "net/spdy/buffered_spdy_framer.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,
SpdyPriority priority,
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.
// When the other side has finished sending data on this stream,
// this method will be called with a zero-length buffer.
void OnStreamFrameData(SpdyStreamId stream_id,
const char* data,
size_t len,
bool fin) 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 just before processing the payload of a frame containing header
// data. Should return an implementation of SpdyHeadersHandlerInterface that
// will receive headers for stream |stream_id|. The caller will not take
// ownership of the headers handler. The same instance should be returned
// for all header frames comprising a logical header block (i.e. until
// OnHeaderFrameEnd() is called with end_headers == true).
SpdyHeadersHandlerInterface* OnHeaderFrameStart(
SpdyStreamId stream_id) override;
// Called after processing the payload of a frame containing header data.
// |end_headers| is true if there will not be any subsequent CONTINUATION
// frames.
void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) 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 {}
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:
scoped_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_