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 scoped_ptr<WebSocketDeflatePredictor> predictor); 45 virtual ~WebSocketDeflateStream(); 46 47 // WebSocketStream functions. 48 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 49 const CompletionCallback& callback) OVERRIDE; 50 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 51 const CompletionCallback& callback) OVERRIDE; 52 virtual void Close() OVERRIDE; 53 virtual std::string GetSubProtocol() const OVERRIDE; 54 virtual std::string GetExtensions() const OVERRIDE; 55 56 private: 57 enum ReadingState { 58 READING_COMPRESSED_MESSAGE, 59 READING_UNCOMPRESSED_MESSAGE, 60 NOT_READING, 61 }; 62 63 enum WritingState { 64 WRITING_COMPRESSED_MESSAGE, 65 WRITING_UNCOMPRESSED_MESSAGE, 66 WRITING_POSSIBLY_COMPRESSED_MESSAGE, 67 NOT_WRITING, 68 }; 69 70 void OnReadComplete(ScopedVector<WebSocketFrame>* frames, 71 const CompletionCallback& callback, 72 int result); 73 74 // This function deflates |frames| and stores the result to |frames| itself. 75 int Deflate(ScopedVector<WebSocketFrame>* frames); 76 void OnMessageStart(const ScopedVector<WebSocketFrame>& frames, size_t index); 77 int AppendCompressedFrame(const WebSocketFrameHeader& header, 78 ScopedVector<WebSocketFrame>* frames_to_write); 79 int AppendPossiblyCompressedMessage( 80 ScopedVector<WebSocketFrame>* frames, 81 ScopedVector<WebSocketFrame>* frames_to_write); 82 83 // This function inflates |frames| and stores the result to |frames| itself. 84 int Inflate(ScopedVector<WebSocketFrame>* frames); 85 86 int InflateAndReadIfNecessary(ScopedVector<WebSocketFrame>* frames, 87 const CompletionCallback& callback); 88 89 const scoped_ptr<WebSocketStream> stream_; 90 WebSocketDeflater deflater_; 91 WebSocketInflater inflater_; 92 ReadingState reading_state_; 93 WritingState writing_state_; 94 WebSocketFrameHeader::OpCode current_reading_opcode_; 95 WebSocketFrameHeader::OpCode current_writing_opcode_; 96 scoped_ptr<WebSocketDeflatePredictor> predictor_; 97 98 DISALLOW_COPY_AND_ASSIGN(WebSocketDeflateStream); 99 }; 100 101 } // namespace net 102 103 #endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 104