1 // Copyright 2013 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. 4 5 #ifndef NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 6 #define NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_vector.h" 13 #include "net/base/completion_callback.h" 14 #include "net/base/net_export.h" 15 #include "net/websockets/websocket_deflater.h" 16 #include "net/websockets/websocket_frame.h" 17 #include "net/websockets/websocket_inflater.h" 18 #include "net/websockets/websocket_stream.h" 19 20 class GURL; 21 22 namespace net { 23 24 class WebSocketDeflatePredictor; 25 26 // WebSocketDeflateStream is a WebSocketStream subclass. 27 // WebSocketDeflateStream is for permessage-deflate WebSocket extension[1]. 28 // 29 // WebSocketDeflateStream::ReadFrames and WriteFrames may change frame 30 // boundary. In particular, if a control frame is placed in the middle of 31 // data message frames, the control frame can overtake data frames. 32 // Say there are frames df1, df2 and cf, df1 and df2 are frames of a 33 // data message and cf is a control message frame. cf may arrive first and 34 // data frames may follow cf. 35 // Note that message boundary will be preserved, i.e. if the last frame of 36 // a message m1 is read / written before the last frame of a message m2, 37 // WebSocketDeflateStream will respect the order. 38 // 39 // [1]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-12 40 class NET_EXPORT_PRIVATE WebSocketDeflateStream : public WebSocketStream { 41 public: 42 WebSocketDeflateStream(scoped_ptr<WebSocketStream> stream, 43 WebSocketDeflater::ContextTakeOverMode mode, 44 int client_window_bits, 45 scoped_ptr<WebSocketDeflatePredictor> predictor); 46 virtual ~WebSocketDeflateStream(); 47 48 // WebSocketStream functions. 49 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 50 const CompletionCallback& callback) OVERRIDE; 51 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 52 const CompletionCallback& callback) OVERRIDE; 53 virtual void Close() OVERRIDE; 54 virtual std::string GetSubProtocol() const OVERRIDE; 55 virtual std::string GetExtensions() const OVERRIDE; 56 57 private: 58 enum ReadingState { 59 READING_COMPRESSED_MESSAGE, 60 READING_UNCOMPRESSED_MESSAGE, 61 NOT_READING, 62 }; 63 64 enum WritingState { 65 WRITING_COMPRESSED_MESSAGE, 66 WRITING_UNCOMPRESSED_MESSAGE, 67 WRITING_POSSIBLY_COMPRESSED_MESSAGE, 68 NOT_WRITING, 69 }; 70 71 // Handles asynchronous completion of ReadFrames() call on |stream_|. 72 void OnReadComplete(ScopedVector<WebSocketFrame>* frames, 73 const CompletionCallback& callback, 74 int result); 75 76 // This function deflates |frames| and stores the result to |frames| itself. 77 int Deflate(ScopedVector<WebSocketFrame>* frames); 78 void OnMessageStart(const ScopedVector<WebSocketFrame>& frames, size_t index); 79 int AppendCompressedFrame(const WebSocketFrameHeader& header, 80 ScopedVector<WebSocketFrame>* frames_to_write); 81 int AppendPossiblyCompressedMessage( 82 ScopedVector<WebSocketFrame>* frames, 83 ScopedVector<WebSocketFrame>* frames_to_write); 84 85 // This function inflates |frames| and stores the result to |frames| itself. 86 int Inflate(ScopedVector<WebSocketFrame>* frames); 87 88 int InflateAndReadIfNecessary(ScopedVector<WebSocketFrame>* frames, 89 const CompletionCallback& callback); 90 91 const scoped_ptr<WebSocketStream> stream_; 92 WebSocketDeflater deflater_; 93 WebSocketInflater inflater_; 94 ReadingState reading_state_; 95 WritingState writing_state_; 96 WebSocketFrameHeader::OpCode current_reading_opcode_; 97 WebSocketFrameHeader::OpCode current_writing_opcode_; 98 scoped_ptr<WebSocketDeflatePredictor> predictor_; 99 100 DISALLOW_COPY_AND_ASSIGN(WebSocketDeflateStream); 101 }; 102 103 } // namespace net 104 105 #endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 106