158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file. 458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#ifndef NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_H_ 658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_H_ 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <string> 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/callback.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/ref_counted.h" 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/scoped_vector.h" 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/websockets/websocket_frame_parser.h" 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/websockets/websocket_stream.h" 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace net { 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class ClientSocketHandle; 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class DrainableIOBuffer; 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class GrowableIOBuffer; 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class IOBufferWithSize; 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)struct WebSocketFrame; 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct WebSocketFrameChunk; 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Implementation of WebSocketStream for non-multiplexed ws:// connections (or 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// the physical side of a multiplexed ws:// connection). 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class NET_EXPORT_PRIVATE WebSocketBasicStream : public WebSocketStream { 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) typedef WebSocketMaskingKey (*WebSocketMaskingKeyGeneratorFunction)(); 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This class should not normally be constructed directly; see 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // WebSocketStream::CreateAndConnectStream() and 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // WebSocketBasicHandshakeStream::Upgrade(). 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebSocketBasicStream( 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ClientSocketHandle> connection, 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const scoped_refptr<GrowableIOBuffer>& http_read_buffer, 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& sub_protocol, 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& extensions); 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The destructor has to make sure the connection is closed when we finish so 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // that it does not get returned to the pool. 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~WebSocketBasicStream(); 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // WebSocketStream implementation. 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CompletionCallback& callback) OVERRIDE; 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CompletionCallback& callback) OVERRIDE; 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void Close() OVERRIDE; 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual std::string GetSubProtocol() const OVERRIDE; 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual std::string GetExtensions() const OVERRIDE; 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) //////////////////////////////////////////////////////////////////////////// 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Methods for testing only. 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static scoped_ptr<WebSocketBasicStream> CreateWebSocketBasicStreamForTesting( 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<ClientSocketHandle> connection, 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const scoped_refptr<GrowableIOBuffer>& http_read_buffer, 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& sub_protocol, 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& extensions, 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) WebSocketMaskingKeyGeneratorFunction key_generator_function); 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns OK or calls |callback| when the |buffer| is fully drained or 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // something has failed. 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int WriteEverything(const scoped_refptr<DrainableIOBuffer>& buffer, 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CompletionCallback& callback); 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Wraps the |callback| to continue writing until everything has been written. 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void OnWriteComplete(const scoped_refptr<DrainableIOBuffer>& buffer, 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CompletionCallback& callback, 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int result); 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Attempts to parse the output of a read as WebSocket frames. On success, 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // returns OK and places the frame(s) in |frames|. 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int HandleReadResult(int result, ScopedVector<WebSocketFrame>* frames); 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Converts the chunks in |frame_chunks| into frames and writes them to 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |frames|. |frame_chunks| is destroyed in the process. Returns 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // ERR_WS_PROTOCOL_ERROR if an invalid chunk was found. If one or more frames 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // was added to |frames|, then returns OK, otherwise returns ERR_IO_PENDING. 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int ConvertChunksToFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedVector<WebSocketFrame>* frames); 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Converts a |chunk| to a |frame|. |*frame| should be NULL on entry to this 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // method. If |chunk| is an incomplete control frame, or an empty middle 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // frame, then |*frame| may still be NULL on exit. If an invalid control frame 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is found, returns ERR_WS_PROTOCOL_ERROR and the stream is no longer 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // usable. Otherwise returns OK (even if frame is still NULL). 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int ConvertChunkToFrame(scoped_ptr<WebSocketFrameChunk> chunk, 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<WebSocketFrame>* frame); 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Creates a frame based on the value of |is_final_chunk|, |data| and 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |current_frame_header_|. Clears |current_frame_header_| if |is_final_chunk| 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is true. |data| may be NULL if the frame has an empty payload. A frame in 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the middle of a message with no data is not useful; in this case the 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // returned frame will be NULL. Otherwise, |current_frame_header_->opcode| is 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // set to Continuation after use if it was Text or Binary, in accordance with 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // WebSocket RFC6455 section 5.4. 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<WebSocketFrame> CreateFrame( 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool is_final_chunk, 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<IOBufferWithSize>& data); 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Adds |data_buffer| to the end of |incomplete_control_frame_body_|, applying 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // bounds checks. 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void AddToIncompleteControlFrameBody( 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<IOBufferWithSize>& data_buffer); 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Called when a read completes. Parses the result and (unless no complete 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // header has been received) calls |callback|. 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void OnReadComplete(ScopedVector<WebSocketFrame>* frames, 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CompletionCallback& callback, 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int result); 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Storage for pending reads. All active WebSockets spend all the time with a 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // call to ReadFrames() pending, so there is no benefit in trying to share 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // this between sockets. 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<IOBufferWithSize> read_buffer_; 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The connection, wrapped in a ClientSocketHandle so that we can prevent it 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // from being returned to the pool. 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<ClientSocketHandle> connection_; 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Frame header for the frame currently being received. Only non-NULL while we 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // are processing the frame. If the frame arrives in multiple chunks, it can 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // remain non-NULL until additional chunks arrive. If the header of the frame 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // was invalid, this is set to NULL, the channel is failed, and subsequent 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // chunks of the same frame will be ignored. 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<WebSocketFrameHeader> current_frame_header_; 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Although it should rarely happen in practice, a control frame can arrive 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // broken into chunks. This variable provides storage for a partial control 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // frame until the rest arrives. It will be NULL the rest of the time. 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<GrowableIOBuffer> incomplete_control_frame_body_; 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Only used during handshake. Some data may be left in this buffer after the 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // handshake, in which case it will be picked up during the first call to 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // ReadFrames(). The type is GrowableIOBuffer for compatibility with 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // net::HttpStreamParser, which is used to parse the handshake. 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<GrowableIOBuffer> http_read_buffer_; 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This keeps the current parse state (including any incomplete headers) and 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // parses frames. 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) WebSocketFrameParser parser_; 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The negotated sub-protocol, or empty for none. 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string sub_protocol_; 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The extensions negotiated with the remote server. 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string extensions_; 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This can be overridden in tests to make the output deterministic. We don't 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // use a Callback here because a function pointer is faster and good enough 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // for our purposes. 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) WebSocketMaskingKeyGeneratorFunction generate_websocket_masking_key_; 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace net 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif // NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_H_ 166