Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(622)

Unified Diff: net/websockets/websocket_channel.h

Issue 12764006: WebSocketChannel implementation (Closed) Base URL: http://git.chromium.org/chromium/src.git@web_socket_dispatcher
Patch Set: Add unit tests and fix bugs. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/websockets/websocket_channel.h
diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h
new file mode 100644
index 0000000000000000000000000000000000000000..52f596d3a0902340ecef650aabab4716470daaa7
--- /dev/null
+++ b/net/websockets/websocket_channel.h
@@ -0,0 +1,177 @@
+// Copyright 2013 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_WEBSOCKETS_WEBSOCKET_CHANNEL_H_
+#define NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+#include "net/websockets/websocket_frame.h"
+#include "net/websockets/websocket_stream.h"
+
+namespace net {
+
+class URLRequestContext;
+class WebSocketEventInterface;
+
+class NET_EXPORT WebSocketChannel {
+ public:
+ // Create a new WebSocketChannel with the specified parameters.
+ // SendAddChannelRequest() must be sent immediately afterwards to start the
+ // connection process.
+ WebSocketChannel(const GURL& socket_url,
+ scoped_ptr<WebSocketEventInterface> event_interface);
+ virtual ~WebSocketChannel();
+
+ // Start the connection process.
+ void SendAddChannelRequest(
+ const std::vector<std::string>& requested_protocols,
+ const GURL& origin,
+ URLRequestContext* url_request_context);
+
+ // Send a data frame to the remote side.
+ void SendFrame(bool fin,
+ WebSocketFrameHeader::OpCode op_code,
+ const std::vector<char>& data);
+
+ // Send "quota" units of flow control to the remote side.
+ void SendFlowControl(int64 quota);
+
+ // Send a "Drop Channel" message to the remote side.
+ void SendDropChannel(unsigned short reason, const std::string& reason_text);
+
+ // Start the connection process, using a different factory function from the
+ // default. This is used for testing.
+ void SendAddChannelRequestWithFactory(
+ const std::vector<std::string>& requested_protocols,
+ const GURL& origin,
+ URLRequestContext* url_request_context,
+ base::Callback<void(
+ const GURL&,
+ const std::vector<std::string>&,
+ const GURL&,
+ URLRequestContext*,
+ const WebSocketStream::SuccessCallback&,
+ const WebSocketStream::FailureCallback&)> factory) NET_EXPORT_PRIVATE;
+
+ private:
+ // We have a simple linear progression of states from CONSTRUCTED to CLOSED,
+ // except that the SEND_CLOSED and RECV_CLOSED states may be skipped in case
+ // of error.
+ enum State {
+ FRESHLY_CONSTRUCTED,
+ CONNECTING,
+ CONNECTED,
+ SEND_CLOSED,
+ RECV_CLOSED,
+ CLOSED, // also used for FAILED states.
+ };
+
+ // Success callback from WebSocketStream::CreateAndConnectStream()
+ void OnConnectSuccess(scoped_ptr<WebSocketStream> stream);
+
+ // Failure callback from WebSocketStream::CreateAndConnectStream()
+ void OnConnectFailure(unsigned short web_socket_error);
+
+ // Call WebSocketStream::WriteFrames() with the appropriate arguments
+ void WriteFrames();
+
+ // Callback from WebSocketStream::WriteFrames
+ void OnWriteDone(int result);
+
+ // Call WebSocketStream::ReadFrames() with the appropriate arguments
+ void ReadFrames();
+
+ // Callback from WebSocketStream::ReadFrames
+ void OnReadDone(int result);
+
+ // Process a single chunk that has been read from the stream.
+ void ProcessFrameChunk(scoped_ptr<WebSocketFrameChunk> chunk);
+
+ // Internal Send implementation.
+ void Send(bool fin,
+ WebSocketFrameHeader::OpCode op_code,
+ const std::vector<char>& data);
+
+ // Internal Send implementation (IOBufferWithSize version; used for control
+ // frames).
+ void SendIOBufferWithSize(bool fin,
+ WebSocketFrameHeader::OpCode op_code,
+ const scoped_refptr<IOBufferWithSize>& buffer);
+
+ // Internal method to fail a channel in a manner appropriate the current
+ // state. The suppled code and reason are sent back to the renderer; the
+ // server just gets a generic "going away" error (if it gets a close message
+ // at all).
+ void FailChannel(unsigned short code, const std::string& reason);
+
+ // Send a close frame to Start the WebSocket Closing Handshake, or to respond
+ // to a close frame from the server.
+ void SendClose(unsigned short code, const std::string& reason);
+
+ // Parse a Close frame. If no code is supplied, then "1005" is returned with
+ // empty reason_text. If the reason code is outside the valid range, then
+ // "1008" is returned. If the reason text is not valid UTF-8, then an empty
+ // string is returned instead.
+ void ParseClose(const IOBufferWithSize& buffer,
+ unsigned short* reason,
+ std::string* reason_text);
+
+ // The URL to which we connect.
+ const GURL socket_url_;
+
+ // The event_interface_ object to call back into.
+ const scoped_ptr<WebSocketEventInterface> event_interface_;
+
+ // The WebSocketStream to which we are sending/receiving data.
+ scoped_ptr<WebSocketStream> stream_;
+
+ // A data structure containing a vector of frames to be sent and the total
+ // number of bytes contained in the vector.
+ struct SendBuffer;
+ // Data that is currently pending write, or NULL if no write is pending.
+ scoped_ptr<SendBuffer> currently_sending_;
+ // Data that is queued up to write after the current write completes.
+ // Only non-NULL when such data actually exists.
+ scoped_ptr<SendBuffer> send_next_;
+ // Destination for the current call to WebSocketStream::ReadFrames
+ ScopedVector<WebSocketFrameChunk> read_frame_chunks_;
+ // Frame header for the current frame. Only non-NULL if we have had to
+ // fragment the frame to send to the renderer because not all the data is
+ // available yet.
+ scoped_ptr<WebSocketFrameHeader> current_frame_header_;
+ // Although it will almost never happen in practice, we can be passed an
+ // incomplete control frame, in which case we need to keep the data around
+ // long enough to reassemble it. This vector will be empty the rest of the
+ // time.
+ scoped_refptr<IOBufferWithSize> incomplete_control_frame_body_;
+ // The point at which we give the renderer a quota refresh (bytes).
+ int send_quota_low_water_mark_;
+ // The amount which we refresh the quota to when it reaches the
+ // low_water_mark (bytes).
+ int send_quota_high_water_mark_;
+ // The current amount of quota that the renderer has available for sending
+ // (bytes).
+ int current_send_quota_;
+ // The current state of the channel. Mainly used for sanity checking, but also
+ // used to track the close state.
+ State state_;
+ // We may be destroyed while callbacks are pending, so we need weak pointers
+ // for those callbacks.
+ base::WeakPtrFactory<WebSocketChannel> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebSocketChannel);
+};
+
+} // namespace net
+
+#endif // NET_WEBSOCKETS_WEBSOCKET_CHANNEL_H_

Powered by Google App Engine
This is Rietveld 408576698