|  | // 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 kWebSocketNormalClosure 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_ |