| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_ |
| #define NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_ |
| |
| #include <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/scoped_vector.h" |
| #include "net/base/net_export.h" |
| #include "net/websockets/websocket_errors.h" |
| #include "net/websockets/websocket_frame.h" |
| |
| namespace net { |
| |
| // Parses WebSocket frames from byte stream. |
| // |
| // Specification of WebSocket frame format is available at |
| // <http://tools.ietf.org/html/rfc6455#section-5>. |
| |
| class NET_EXPORT WebSocketFrameParser { |
| public: |
| WebSocketFrameParser(); |
| ~WebSocketFrameParser(); |
| |
| // Decodes the given byte stream and stores parsed WebSocket frames in |
| // |frame_chunks|. |
| // |
| // If the parser encounters invalid payload length format, Decode() fails |
| // and returns false. Once Decode() has failed, the parser refuses to decode |
| // any more data and future invocations of Decode() will simply return false. |
| // |
| // Payload data of parsed WebSocket frames may be incomplete; see comments in |
| // websocket_frame.h for more details. |
| bool Decode(const char* data, |
| size_t length, |
| ScopedVector<WebSocketFrameChunk>* frame_chunks); |
| |
| // Returns WEB_SOCKET_OK if the parser has not failed to decode WebSocket |
| // frames. Otherwise returns WebSocketError which is defined in |
| // websocket_errors.h. We can convert net::WebSocketError to net::Error by |
| // using WebSocketErrorToNetError(). |
| WebSocketError websocket_error() const { return websocket_error_; } |
| |
| private: |
| // Tries to decode a frame header from |current_read_pos_|. |
| // If successful, this function updates |current_read_pos_|, |
| // |current_frame_header_|, and |masking_key_| (if available). |
| // This function may set |failed_| to true if it observes a corrupt frame. |
| // If there is not enough data in the remaining buffer to parse a frame |
| // header, this function returns without doing anything. |
| void DecodeFrameHeader(); |
| |
| // Decodes frame payload and creates a WebSocketFrameChunk object. |
| // This function updates |current_read_pos_| and |frame_offset_| after |
| // parsing. This function returns a frame object even if no payload data is |
| // available at this moment, so the receiver could make use of frame header |
| // information. If the end of frame is reached, this function clears |
| // |current_frame_header_|, |frame_offset_| and |masking_key_|. |
| scoped_ptr<WebSocketFrameChunk> DecodeFramePayload(bool first_chunk); |
| |
| // Internal buffer to store the data to parse. |
| std::vector<char> buffer_; |
| |
| // Position in |buffer_| where the next round of parsing starts. |
| size_t current_read_pos_; |
| |
| // Frame header and masking key of the current frame. |
| // |masking_key_| is filled with zeros if the current frame is not masked. |
| scoped_ptr<WebSocketFrameHeader> current_frame_header_; |
| WebSocketMaskingKey masking_key_; |
| |
| // Amount of payload data read so far for the current frame. |
| uint64 frame_offset_; |
| |
| WebSocketError websocket_error_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WebSocketFrameParser); |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_WEBSOCKETS_WEBSOCKET_FRAME_PARSER_H_ |