Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / websockets / websocket_stream.h
blob713205a104dee617dcd3fe117ac9f693bdfa3c5a
1 // Copyright (c) 2012 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.
5 #ifndef NET_WEBSOCKETS_WEBSOCKET_STREAM_H_
6 #define NET_WEBSOCKETS_WEBSOCKET_STREAM_H_
8 #include <string>
9 #include <vector>
11 #include "base/basictypes.h"
12 #include "base/callback_forward.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/time/time.h"
17 #include "net/base/completion_callback.h"
18 #include "net/base/net_export.h"
19 #include "net/websockets/websocket_event_interface.h"
20 #include "net/websockets/websocket_handshake_request_info.h"
21 #include "net/websockets/websocket_handshake_response_info.h"
23 class GURL;
25 namespace base {
26 class Timer;
29 namespace url {
30 class Origin;
31 } // namespace url
33 namespace net {
35 class BoundNetLog;
36 class URLRequestContext;
37 struct WebSocketFrame;
38 class WebSocketHandshakeStreamCreateHelper;
40 // WebSocketStreamRequest is the caller's handle to the process of creation of a
41 // WebSocketStream. Deleting the object before the OnSuccess or OnFailure
42 // callbacks are called will cancel the request (and neither callback will be
43 // called). After OnSuccess or OnFailure have been called, this object may be
44 // safely deleted without side-effects.
45 class NET_EXPORT_PRIVATE WebSocketStreamRequest {
46 public:
47 virtual ~WebSocketStreamRequest();
50 // WebSocketStream is a transport-agnostic interface for reading and writing
51 // WebSocket frames. This class provides an abstraction for WebSocket streams
52 // based on various transport layers, such as normal WebSocket connections
53 // (WebSocket protocol upgraded from HTTP handshake), SPDY transports, or
54 // WebSocket connections with multiplexing extension. Subtypes of
55 // WebSocketStream are responsible for managing the underlying transport
56 // appropriately.
58 // All functions except Close() can be asynchronous. If an operation cannot
59 // be finished synchronously, the function returns ERR_IO_PENDING, and
60 // |callback| will be called when the operation is finished. Non-null |callback|
61 // must be provided to these functions.
63 class NET_EXPORT_PRIVATE WebSocketStream {
64 public:
65 // A concrete object derived from ConnectDelegate is supplied by the caller to
66 // CreateAndConnectStream() to receive the result of the connection.
67 class NET_EXPORT_PRIVATE ConnectDelegate {
68 public:
69 virtual ~ConnectDelegate();
70 // Called on successful connection. The parameter is an object derived from
71 // WebSocketStream.
72 virtual void OnSuccess(scoped_ptr<WebSocketStream> stream) = 0;
74 // Called on failure to connect.
75 // |message| contains defails of the failure.
76 virtual void OnFailure(const std::string& message) = 0;
78 // Called when the WebSocket Opening Handshake starts.
79 virtual void OnStartOpeningHandshake(
80 scoped_ptr<WebSocketHandshakeRequestInfo> request) = 0;
82 // Called when the WebSocket Opening Handshake ends.
83 virtual void OnFinishOpeningHandshake(
84 scoped_ptr<WebSocketHandshakeResponseInfo> response) = 0;
86 // Called when there is an SSL certificate error. Should call
87 // ssl_error_callbacks->ContinueSSLRequest() or
88 // ssl_error_callbacks->CancelSSLRequest().
89 virtual void OnSSLCertificateError(
90 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks>
91 ssl_error_callbacks,
92 const SSLInfo& ssl_info,
93 bool fatal) = 0;
96 // Create and connect a WebSocketStream of an appropriate type. The actual
97 // concrete type returned depends on whether multiplexing or SPDY are being
98 // used to communicate with the remote server. If the handshake completed
99 // successfully, then connect_delegate->OnSuccess() is called with a
100 // WebSocketStream instance. If it failed, then connect_delegate->OnFailure()
101 // is called with a WebSocket result code corresponding to the error. Deleting
102 // the returned WebSocketStreamRequest object will cancel the connection, in
103 // which case the |connect_delegate| object that the caller passed will be
104 // deleted without any of its methods being called. Unless cancellation is
105 // required, the caller should keep the WebSocketStreamRequest object alive
106 // until connect_delegate->OnSuccess() or OnFailure() have been called, then
107 // it is safe to delete.
108 static scoped_ptr<WebSocketStreamRequest> CreateAndConnectStream(
109 const GURL& socket_url,
110 const std::vector<std::string>& requested_subprotocols,
111 const url::Origin& origin,
112 URLRequestContext* url_request_context,
113 const BoundNetLog& net_log,
114 scoped_ptr<ConnectDelegate> connect_delegate);
116 // Derived classes must make sure Close() is called when the stream is not
117 // closed on destruction.
118 virtual ~WebSocketStream();
120 // Reads WebSocket frame data. This operation finishes when new frame data
121 // becomes available.
123 // |frames| remains owned by the caller and must be valid until the
124 // operation completes or Close() is called. |frames| must be empty on
125 // calling.
127 // This function should not be called while the previous call of ReadFrames()
128 // is still pending.
130 // Returns net::OK or one of the net::ERR_* codes.
132 // frames->size() >= 1 if the result is OK.
134 // Only frames with complete header information are inserted into |frames|. If
135 // the currently available bytes of a new frame do not form a complete frame
136 // header, then the implementation will buffer them until all the fields in
137 // the WebSocketFrameHeader object can be filled. If ReadFrames() is freshly
138 // called in this situation, it will return ERR_IO_PENDING exactly as if no
139 // data was available.
141 // Original frame boundaries are not preserved. In particular, if only part of
142 // a frame is available, then the frame will be split, and the available data
143 // will be returned immediately.
145 // When the socket is closed on the remote side, this method will return
146 // ERR_CONNECTION_CLOSED. It will not return OK with an empty vector.
148 // If the connection is closed in the middle of receiving an incomplete frame,
149 // ReadFrames may discard the incomplete frame. Since the renderer will
150 // discard any incomplete messages when the connection is closed, this makes
151 // no difference to the overall semantics.
153 // Implementations of ReadFrames() must be able to handle being deleted during
154 // the execution of callback.Run(). In practice this means that the method
155 // calling callback.Run() (and any calling methods in the same object) must
156 // return immediately without any further method calls or access to member
157 // variables. Implementors should write test(s) for this case.
159 // Extensions which use reserved header bits should clear them when they are
160 // set correctly. If the reserved header bits are set incorrectly, it is okay
161 // to leave it to the caller to report the error.
162 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
163 const CompletionCallback& callback) = 0;
165 // Writes WebSocket frame data.
167 // |frames| must be valid until the operation completes or Close() is called.
169 // This function must not be called while a previous call of WriteFrames() is
170 // still pending.
172 // This method will only return OK if all frames were written completely.
173 // Otherwise it will return an appropriate net error code.
175 // The callback implementation is permitted to delete this
176 // object. Implementations of WriteFrames() should be robust against
177 // this. This generally means returning to the event loop immediately after
178 // calling the callback.
179 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
180 const CompletionCallback& callback) = 0;
182 // Closes the stream. All pending I/O operations (if any) are cancelled
183 // at this point, so |frames| can be freed.
184 virtual void Close() = 0;
186 // The subprotocol that was negotiated for the stream. If no protocol was
187 // negotiated, then the empty string is returned.
188 virtual std::string GetSubProtocol() const = 0;
190 // The extensions that were negotiated for the stream. Since WebSocketStreams
191 // can be layered, this may be different from what this particular
192 // WebSocketStream implements. The primary purpose of this accessor is to make
193 // the data available to Javascript. The format of the string is identical to
194 // the contents of the Sec-WebSocket-Extensions header supplied by the server,
195 // with some canonicalisations applied (leading and trailing whitespace
196 // removed, multiple headers concatenated into one comma-separated list). See
197 // RFC6455 section 9.1 for the exact format specification. If no
198 // extensions were negotiated, the empty string is returned.
199 virtual std::string GetExtensions() const = 0;
201 protected:
202 WebSocketStream();
204 private:
205 DISALLOW_COPY_AND_ASSIGN(WebSocketStream);
208 // A helper function used in the implementation of CreateAndConnectStream() and
209 // WebSocketBasicHandshakeStream. It creates a WebSocketHandshakeResponseInfo
210 // object and dispatches it to the OnFinishOpeningHandshake() method of the
211 // supplied |connect_delegate|.
212 void WebSocketDispatchOnFinishOpeningHandshake(
213 WebSocketStream::ConnectDelegate* connect_delegate,
214 const GURL& gurl,
215 const scoped_refptr<HttpResponseHeaders>& headers,
216 base::Time response_time);
218 // Alternate version of WebSocketStream::CreateAndConnectStream() for testing
219 // use only. The differences are the use of a |create_helper| argument in place
220 // of |requested_subprotocols| and taking |timer| as the handshake timeout
221 // timer. Implemented in websocket_stream.cc.
222 NET_EXPORT_PRIVATE scoped_ptr<WebSocketStreamRequest>
223 CreateAndConnectStreamForTesting(
224 const GURL& socket_url,
225 scoped_ptr<WebSocketHandshakeStreamCreateHelper> create_helper,
226 const url::Origin& origin,
227 URLRequestContext* url_request_context,
228 const BoundNetLog& net_log,
229 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
230 scoped_ptr<base::Timer> timer);
232 } // namespace net
234 #endif // NET_WEBSOCKETS_WEBSOCKET_STREAM_H_