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