1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_WEBSOCKETS_WEBSOCKET_FRAME_HANDLER_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_WEBSOCKETS_WEBSOCKET_FRAME_HANDLER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <deque>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass IOBuffer;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass IOBufferWithSize;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Handles WebSocket frame messages.
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebSocketFrameHandler {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct FrameInfo {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* frame_start;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int frame_length;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* message_start;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int message_length;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebSocketFrameHandler();
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~WebSocketFrameHandler();
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Appends WebSocket raw data on connection.
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For sending, this is data from WebKit.
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For receiving, this is data from network.
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AppendData(const char* data, int len);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Updates current IOBuffer.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If |buffered| is true, it tries to find WebSocket frames.
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Otherwise, it just picks the first buffer in |pending_buffers_|.
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns available size of data, 0 if no more data or current buffer was
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // not released, and negative if some error occurred.
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int UpdateCurrentBuffer(bool buffered);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Gets current IOBuffer.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For sending, this is data to network.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For receiving, this is data to WebKit.
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns NULL just after ReleaseCurrentBuffer() was called.
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IOBuffer* GetCurrentBuffer() { return current_buffer_.get(); }
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetCurrentBufferSize() const { return current_buffer_size_; }
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns original buffer size of current IOBuffer.
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This might differ from GetCurrentBufferSize() if frame message is
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // compressed or decompressed.
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetOriginalBufferSize() const { return original_current_buffer_size_; }
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Releases current IOBuffer.
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReleaseCurrentBuffer();
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Parses WebSocket frame in [|buffer|, |buffer|+|size|), fills frame
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // information in |frame_info|, and returns number of bytes for
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // complete WebSocket frames.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static int ParseWebSocketFrame(const char* buffer, int size,
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 std::vector<FrameInfo>* frame_info);
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::deque< scoped_refptr<IOBufferWithSize> > PendingDataQueue;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<IOBuffer> current_buffer_;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int current_buffer_size_;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int original_current_buffer_size_;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Deque of IOBuffers in pending.
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PendingDataQueue pending_buffers_;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(WebSocketFrameHandler);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // NET_WEBSOCKETS_WEBSOCKET_FRAME_HANDLER_H_
83