1 // Copyright (c) 2012 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_FRAME_PARSER_H_ 6 #define NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_vector.h" 14 #include "net/base/net_export.h" 15 #include "net/websockets/websocket_errors.h" 16 #include "net/websockets/websocket_frame.h" 17 18 namespace net { 19 20 // Parses WebSocket frames from byte stream. 21 // 22 // Specification of WebSocket frame format is available at 23 // <http://tools.ietf.org/html/rfc6455#section-5>. 24 25 class NET_EXPORT WebSocketFrameParser { 26 public: 27 WebSocketFrameParser(); 28 ~WebSocketFrameParser(); 29 30 // Decodes the given byte stream and stores parsed WebSocket frames in 31 // |frame_chunks|. 32 // 33 // If the parser encounters invalid payload length format, Decode() fails 34 // and returns false. Once Decode() has failed, the parser refuses to decode 35 // any more data and future invocations of Decode() will simply return false. 36 // 37 // Payload data of parsed WebSocket frames may be incomplete; see comments in 38 // websocket_frame.h for more details. 39 bool Decode(const char* data, 40 size_t length, 41 ScopedVector<WebSocketFrameChunk>* frame_chunks); 42 43 // Returns kWebSocketNormalClosure if the parser has not failed to decode 44 // WebSocket frames. Otherwise returns WebSocketError which is defined in 45 // websocket_errors.h. We can convert net::WebSocketError to net::Error by 46 // using WebSocketErrorToNetError(). 47 WebSocketError websocket_error() const { return websocket_error_; } 48 49 private: 50 // Tries to decode a frame header from |current_read_pos_|. 51 // If successful, this function updates |current_read_pos_|, 52 // |current_frame_header_|, and |masking_key_| (if available). 53 // This function may set |failed_| to true if it observes a corrupt frame. 54 // If there is not enough data in the remaining buffer to parse a frame 55 // header, this function returns without doing anything. 56 void DecodeFrameHeader(); 57 58 // Decodes frame payload and creates a WebSocketFrameChunk object. 59 // This function updates |current_read_pos_| and |frame_offset_| after 60 // parsing. This function returns a frame object even if no payload data is 61 // available at this moment, so the receiver could make use of frame header 62 // information. If the end of frame is reached, this function clears 63 // |current_frame_header_|, |frame_offset_| and |masking_key_|. 64 scoped_ptr<WebSocketFrameChunk> DecodeFramePayload(bool first_chunk); 65 66 // Internal buffer to store the data to parse. 67 std::vector<char> buffer_; 68 69 // Position in |buffer_| where the next round of parsing starts. 70 size_t current_read_pos_; 71 72 // Frame header and masking key of the current frame. 73 // |masking_key_| is filled with zeros if the current frame is not masked. 74 scoped_ptr<WebSocketFrameHeader> current_frame_header_; 75 WebSocketMaskingKey masking_key_; 76 77 // Amount of payload data read so far for the current frame. 78 uint64 frame_offset_; 79 80 WebSocketError websocket_error_; 81 82 DISALLOW_COPY_AND_ASSIGN(WebSocketFrameParser); 83 }; 84 85 } // namespace net 86 87 #endif // NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_ 88