1 // Copyright 2013 The Chromium Authors 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 <stddef.h> 9 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 #include "base/memory/scoped_refptr.h" 15 #include "net/base/completion_once_callback.h" 16 #include "net/base/net_export.h" 17 #include "net/log/net_log_with_source.h" 18 #include "net/websockets/websocket_deflater.h" 19 #include "net/websockets/websocket_frame.h" 20 #include "net/websockets/websocket_inflater.h" 21 #include "net/websockets/websocket_stream.h" 22 23 namespace net { 24 25 class WebSocketDeflateParameters; 26 class WebSocketDeflatePredictor; 27 class IOBufferWithSize; 28 class NetLogWithSource; 29 30 // WebSocketDeflateStream is a WebSocketStream subclass. 31 // WebSocketDeflateStream is for permessage-deflate WebSocket extension[1]. 32 // 33 // WebSocketDeflateStream::ReadFrames and WriteFrames may change frame 34 // boundary. In particular, if a control frame is placed in the middle of 35 // data message frames, the control frame can overtake data frames. 36 // Say there are frames df1, df2 and cf, df1 and df2 are frames of a 37 // data message and cf is a control message frame. cf may arrive first and 38 // data frames may follow cf. 39 // Note that message boundary will be preserved, i.e. if the last frame of 40 // a message m1 is read / written before the last frame of a message m2, 41 // WebSocketDeflateStream will respect the order. 42 // 43 // [1]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-12 44 class NET_EXPORT_PRIVATE WebSocketDeflateStream : public WebSocketStream { 45 public: 46 WebSocketDeflateStream(std::unique_ptr<WebSocketStream> stream, 47 const WebSocketDeflateParameters& params, 48 std::unique_ptr<WebSocketDeflatePredictor> predictor); 49 50 WebSocketDeflateStream(const WebSocketDeflateStream&) = delete; 51 WebSocketDeflateStream& operator=(const WebSocketDeflateStream&) = delete; 52 53 ~WebSocketDeflateStream() override; 54 55 // WebSocketStream functions. 56 int ReadFrames(std::vector<std::unique_ptr<WebSocketFrame>>* frames, 57 CompletionOnceCallback callback) override; 58 int WriteFrames(std::vector<std::unique_ptr<WebSocketFrame>>* frames, 59 CompletionOnceCallback callback) override; 60 void Close() override; 61 std::string GetSubProtocol() const override; 62 std::string GetExtensions() const override; 63 const NetLogWithSource& GetNetLogWithSource() const override; 64 65 private: 66 enum ReadingState { 67 READING_COMPRESSED_MESSAGE, 68 READING_UNCOMPRESSED_MESSAGE, 69 NOT_READING, 70 }; 71 72 enum WritingState { 73 WRITING_COMPRESSED_MESSAGE, 74 WRITING_UNCOMPRESSED_MESSAGE, 75 WRITING_POSSIBLY_COMPRESSED_MESSAGE, 76 NOT_WRITING, 77 }; 78 79 // Handles asynchronous completion of ReadFrames() call on |stream_|. 80 void OnReadComplete(std::vector<std::unique_ptr<WebSocketFrame>>* frames, 81 int result); 82 83 // This function deflates |frames| and stores the result to |frames| itself. 84 int Deflate(std::vector<std::unique_ptr<WebSocketFrame>>* frames); 85 void OnMessageStart( 86 const std::vector<std::unique_ptr<WebSocketFrame>>& frames, 87 size_t index); 88 int AppendCompressedFrame( 89 const WebSocketFrameHeader& header, 90 std::vector<std::unique_ptr<WebSocketFrame>>* frames_to_write); 91 int AppendPossiblyCompressedMessage( 92 std::vector<std::unique_ptr<WebSocketFrame>>* frames, 93 std::vector<std::unique_ptr<WebSocketFrame>>* frames_to_write); 94 95 // This function inflates |frames| and stores the result to |frames| itself. 96 int Inflate(std::vector<std::unique_ptr<WebSocketFrame>>* frames); 97 98 int InflateAndReadIfNecessary( 99 std::vector<std::unique_ptr<WebSocketFrame>>* frames); 100 101 const std::unique_ptr<WebSocketStream> stream_; 102 WebSocketDeflater deflater_; 103 WebSocketInflater inflater_; 104 ReadingState reading_state_ = NOT_READING; 105 WritingState writing_state_ = NOT_WRITING; 106 WebSocketFrameHeader::OpCode current_reading_opcode_ = 107 WebSocketFrameHeader::kOpCodeText; 108 WebSocketFrameHeader::OpCode current_writing_opcode_ = 109 WebSocketFrameHeader::kOpCodeText; 110 std::unique_ptr<WebSocketDeflatePredictor> predictor_; 111 112 // User callback saved for asynchronous reads. 113 CompletionOnceCallback read_callback_; 114 115 // References of Deflater outputs kept until next WriteFrames(). 116 std::vector<scoped_refptr<IOBufferWithSize>> deflater_outputs_; 117 // References of Inflater outputs kept until next ReadFrames(). 118 std::vector<scoped_refptr<IOBufferWithSize>> inflater_outputs_; 119 }; 120 121 } // namespace net 122 123 #endif // NET_WEBSOCKETS_WEBSOCKET_DEFLATE_STREAM_H_ 124