14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string> 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_vector.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/completion_callback.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/net_export.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_deflater.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_frame.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_inflater.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/websockets/websocket_stream.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class GURL; 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace net { 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebSocketDeflatePredictor; 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// WebSocketDeflateStream is a WebSocketStream subclass. 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// WebSocketDeflateStream is for permessage-deflate WebSocket extension[1]. 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// WebSocketDeflateStream::ReadFrames and WriteFrames may change frame 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// boundary. In particular, if a control frame is placed in the middle of 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// data message frames, the control frame can overtake data frames. 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Say there are frames df1, df2 and cf, df1 and df2 are frames of a 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// data message and cf is a control message frame. cf may arrive first and 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// data frames may follow cf. 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Note that message boundary will be preserved, i.e. if the last frame of 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// a message m1 is read / written before the last frame of a message m2, 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// WebSocketDeflateStream will respect the order. 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// [1]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-12 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class NET_EXPORT_PRIVATE WebSocketDeflateStream : public WebSocketStream { 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WebSocketDeflateStream(scoped_ptr<WebSocketStream> stream, 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WebSocketDeflater::ContextTakeOverMode mode, 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int client_window_bits, 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<WebSocketDeflatePredictor> predictor); 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~WebSocketDeflateStream(); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // WebSocketStream functions. 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CompletionCallback& callback) OVERRIDE; 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CompletionCallback& callback) OVERRIDE; 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Close() OVERRIDE; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual std::string GetSubProtocol() const OVERRIDE; 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual std::string GetExtensions() const OVERRIDE; 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) enum ReadingState { 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) READING_COMPRESSED_MESSAGE, 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) READING_UNCOMPRESSED_MESSAGE, 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOT_READING, 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) enum WritingState { 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WRITING_COMPRESSED_MESSAGE, 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WRITING_UNCOMPRESSED_MESSAGE, 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WRITING_POSSIBLY_COMPRESSED_MESSAGE, 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOT_WRITING, 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Handles asynchronous completion of ReadFrames() call on |stream_|. 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void OnReadComplete(ScopedVector<WebSocketFrame>* frames, 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CompletionCallback& callback, 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int result); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This function deflates |frames| and stores the result to |frames| itself. 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int Deflate(ScopedVector<WebSocketFrame>* frames); 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void OnMessageStart(const ScopedVector<WebSocketFrame>& frames, size_t index); 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int AppendCompressedFrame(const WebSocketFrameHeader& header, 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ScopedVector<WebSocketFrame>* frames_to_write); 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int AppendPossiblyCompressedMessage( 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ScopedVector<WebSocketFrame>* frames, 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ScopedVector<WebSocketFrame>* frames_to_write); 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This function inflates |frames| and stores the result to |frames| itself. 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int Inflate(ScopedVector<WebSocketFrame>* frames); 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int InflateAndReadIfNecessary(ScopedVector<WebSocketFrame>* frames, 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CompletionCallback& callback); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_ptr<WebSocketStream> stream_; 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketDeflater deflater_; 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketInflater inflater_; 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ReadingState reading_state_; 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WritingState writing_state_; 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketFrameHeader::OpCode current_reading_opcode_; 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebSocketFrameHeader::OpCode current_writing_opcode_; 981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<WebSocketDeflatePredictor> predictor_; 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WebSocketDeflateStream); 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace net 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 106