summaryrefslogtreecommitdiffstats
path: root/net/flip/flip_session.h
diff options
context:
space:
mode:
Diffstat (limited to 'net/flip/flip_session.h')
-rw-r--r--net/flip/flip_session.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/net/flip/flip_session.h b/net/flip/flip_session.h
new file mode 100644
index 0000000..b608ddb
--- /dev/null
+++ b/net/flip/flip_session.h
@@ -0,0 +1,216 @@
+// Copyright (c) 2009 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_FLIP_FLIP_SESSION_H_
+#define NET_FLIP_FLIP_SESSION_H_
+
+#include <deque>
+#include <list>
+#include <map>
+#include <queue>
+#include <string>
+
+#include "base/ref_counted.h"
+#include "net/base/io_buffer.h"
+#include "net/base/load_states.h"
+#include "net/base/net_errors.h"
+#include "net/base/upload_data_stream.h"
+#include "net/flip/flip_framer.h"
+#include "net/flip/flip_protocol.h"
+#include "net/flip/flip_session_pool.h"
+#include "net/socket/client_socket.h"
+#include "net/socket/client_socket_handle.h"
+#include "testing/platform_test.h"
+
+namespace net {
+
+class FlipStreamImpl;
+class HttpNetworkSession;
+class HttpRequestInfo;
+class HttpResponseInfo;
+
+// A callback interface for HTTP content retrieved from the Flip stream.
+class FlipDelegate {
+ public:
+ virtual ~FlipDelegate() {}
+ virtual const HttpRequestInfo* request() = 0;
+ virtual const UploadDataStream* data() = 0;
+
+ virtual void OnRequestSent(int status) = 0;
+ virtual void OnResponseReceived(HttpResponseInfo* response) = 0;
+ virtual void OnDataReceived(const char* buffer, int bytes) = 0;
+ virtual void OnClose(int status) = 0;
+ virtual void OnCancel() = 0;
+};
+
+class PrioritizedIOBuffer {
+ public:
+ PrioritizedIOBuffer() : buffer_(0), priority_(0) {}
+ PrioritizedIOBuffer(IOBufferWithSize* buffer, int priority)
+ : buffer_(buffer),
+ priority_(priority),
+ position_(++order_) {
+ }
+
+ IOBuffer* buffer() const { return buffer_; }
+
+ int size() const { return buffer_->size(); }
+
+ void release() { buffer_ = NULL; }
+
+ int priority() { return priority_; }
+
+ // Supports sorting.
+ bool operator<(const PrioritizedIOBuffer& other) const {
+ if (priority_ != other.priority_)
+ return priority_ > other.priority_;
+ return position_ >= other.position_;
+ }
+
+ private:
+ scoped_refptr<IOBufferWithSize> buffer_;
+ int priority_;
+ int position_;
+ static int order_; // Maintains a FIFO order for equal priorities.
+};
+
+class FlipSession : public base::RefCounted<FlipSession>,
+ public flip::FlipFramerVisitorInterface {
+ public:
+ // Factory for finding open sessions.
+ // TODO(mbelshe): Break this out into a connection pool class?
+ static FlipSession* GetFlipSession(const HostResolver::RequestInfo&,
+ HttpNetworkSession* session);
+ virtual ~FlipSession();
+
+ // Get the domain for this FlipSession.
+ std::string domain() { return domain_; }
+
+ // Connect the FLIP Socket.
+ // Returns net::Error::OK on success.
+ // Note that this call does not wait for the connect to complete. Callers can
+ // immediately start using the FlipSession while it connects.
+ net::Error Connect(const std::string& group_name,
+ const HostResolver::RequestInfo& host, int priority);
+
+ // Create a new stream.
+ // FlipDelegate must remain valid until the stream is either cancelled by the
+ // creator via CancelStream or the FlipDelegate OnClose or OnCancel callbacks
+ // have been made.
+ // Once the stream is created, the delegate should wait for a callback.
+ int CreateStream(FlipDelegate* delegate);
+
+ // Cancel a stream.
+ bool CancelStream(int id);
+
+ // Check if a stream is active.
+ bool IsStreamActive(int id);
+
+ // The LoadState is used for informing the user of the current network
+ // status, such as "resolving host", "connecting", etc.
+ LoadState GetLoadState() const;
+ protected:
+ friend class FlipNetworkTransactionTest;
+ friend class FlipSessionPool;
+
+ // Provide access to the framer for testing.
+ flip::FlipFramer* GetFramer() { return &flip_framer_; }
+
+ // Create a new FlipSession.
+ // |host| is the hostname that this session connects to.
+ FlipSession(std::string host, HttpNetworkSession* session);
+
+ // Closes all open streams. Used as part of shutdown.
+ void CloseAllStreams(net::Error code);
+
+ private:
+ // FlipFramerVisitorInterface
+ virtual void OnError(flip::FlipFramer*);
+ virtual void OnStreamFrameData(flip::FlipStreamId stream_id,
+ const char* data,
+ uint32 len);
+ virtual void OnControl(const flip::FlipControlFrame* frame);
+ virtual void OnLameDuck();
+
+ // Control frame handlers.
+ void OnSyn(const flip::FlipSynStreamControlFrame* frame,
+ const flip::FlipHeaderBlock* headers);
+ void OnSynReply(const flip::FlipSynReplyControlFrame* frame,
+ const flip::FlipHeaderBlock* headers);
+ void OnFin(const flip::FlipFinStreamControlFrame* frame);
+
+ // IO Callbacks
+ void OnSocketConnect(int result);
+ void OnReadComplete(int result);
+ void OnWriteComplete(int result);
+
+ // Start reading from the socket.
+ void ReadSocket();
+
+ // Write current data to the socket.
+ void WriteSocketLater();
+ void WriteSocket();
+
+ // Get a new stream id.
+ int GetNewStreamId();
+
+ // Track active streams in the active stream list.
+ FlipStreamImpl* ActivateStream(int id, FlipDelegate* delegate);
+ void DeactivateStream(int id);
+
+ // Check if we have a pending pushed-stream for this url
+ // Returns the stream if found (and returns it from the pending
+ // list), returns NULL otherwise.
+ FlipStreamImpl* GetPushStream(std::string url);
+
+ // Callbacks for the Flip session.
+ CompletionCallbackImpl<FlipSession> connect_callback_;
+ CompletionCallbackImpl<FlipSession> read_callback_;
+ CompletionCallbackImpl<FlipSession> write_callback_;
+
+ // The domain this session is connected to.
+ std::string domain_;
+
+ scoped_refptr<HttpNetworkSession> session_;
+
+ // The socket handle for this session.
+ ClientSocketHandle connection_;
+ bool connection_started_;
+
+ // The read buffer used to read data from the socket.
+ enum { kReadBufferSize = (4 * 1024) };
+ scoped_refptr<net::MovableIOBuffer> read_buffer_;
+ int read_buffer_bytes_read_; // bytes left in the buffer from prior read.
+ bool read_pending_;
+
+ int stream_hi_water_mark_; // The next stream id to use.
+
+ typedef std::map<int, FlipStreamImpl*> ActiveStreamMap;
+ typedef std::list<FlipStreamImpl*> ActiveStreamList;
+ ActiveStreamMap active_streams_;
+
+ ActiveStreamList pushed_streams_;
+
+ // As we gather data to be sent, we put it into the output queue.
+ typedef std::priority_queue<PrioritizedIOBuffer> OutputQueue;
+ OutputQueue queue_;
+
+ // TODO(mbelshe): this is ugly!!
+ // The packet we are currently sending.
+ PrioritizedIOBuffer in_flight_write_;
+ bool delayed_write_pending_;
+ bool write_pending_;
+
+ // Flip Frame state.
+ flip::FlipFramer flip_framer_;
+
+ // This is our weak session pool - one session per domain.
+ static scoped_ptr<FlipSessionPool> session_pool_;
+ static bool disable_compression_;
+};
+
+} // namespace net
+
+#endif // NET_FLIP_FLIP_SESSION_H_
+