diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-08-15 21:46:11 +0200 |
---|---|---|
committer | Zeno Albisser <zeno.albisser@digia.com> | 2013-08-15 21:46:11 +0200 |
commit | 679147eead574d186ebf3069647b4c23e8ccace6 (patch) | |
tree | fc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/net/websockets/websocket_frame.h | |
download | qtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz |
Initial import.
Diffstat (limited to 'chromium/net/websockets/websocket_frame.h')
-rw-r--r-- | chromium/net/websockets/websocket_frame.h | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/chromium/net/websockets/websocket_frame.h b/chromium/net/websockets/websocket_frame.h new file mode 100644 index 00000000000..8c04f7dce44 --- /dev/null +++ b/chromium/net/websockets/websocket_frame.h @@ -0,0 +1,175 @@ +// 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_H_ +#define NET_WEBSOCKETS_WEBSOCKET_FRAME_H_ + +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/net_export.h" + +namespace net { + +class IOBufferWithSize; + +// Represents a WebSocket frame header. +// +// Members of this class correspond to each element in WebSocket frame header +// (see http://tools.ietf.org/html/rfc6455#section-5.2). +struct NET_EXPORT WebSocketFrameHeader { + typedef int OpCode; + + // Originally these constants were static const int, but to make it possible + // to use them in a switch statement they were changed to an enum. + enum OpCodeEnum { + kOpCodeContinuation = 0x0, + kOpCodeText = 0x1, + kOpCodeBinary = 0x2, + kOpCodeDataUnused = 0x3, + kOpCodeClose = 0x8, + kOpCodePing = 0x9, + kOpCodePong = 0xA, + kOpCodeControlUnused = 0xB, + }; + + // Return true if |opcode| is one of the data opcodes known to this + // implementation. + static bool IsKnownDataOpCode(OpCode opcode) { + return opcode == kOpCodeContinuation || opcode == kOpCodeText || + opcode == kOpCodeBinary; + } + + // Return true if |opcode| is one of the control opcodes known to this + // implementation. + static bool IsKnownControlOpCode(OpCode opcode) { + return opcode == kOpCodeClose || opcode == kOpCodePing || + opcode == kOpCodePong; + } + + // These values must be a compile-time constant. "enum hack" is used here + // to make MSVC happy. + enum { + kBaseHeaderSize = 2, + kMaximumExtendedLengthSize = 8, + kMaskingKeyLength = 4 + }; + + // Constructor to avoid a lot of repetitive initialisation. + explicit WebSocketFrameHeader(OpCode opCode) + : final(false), + reserved1(false), + reserved2(false), + reserved3(false), + opcode(opCode), + masked(false), + payload_length(0) {} + + // Create a clone of this object on the heap. + scoped_ptr<WebSocketFrameHeader> Clone(); + + // Members below correspond to each item in WebSocket frame header. + // See <http://tools.ietf.org/html/rfc6455#section-5.2> for details. + bool final; + bool reserved1; + bool reserved2; + bool reserved3; + OpCode opcode; + bool masked; + uint64 payload_length; + + private: + DISALLOW_COPY_AND_ASSIGN(WebSocketFrameHeader); +}; + +// Contains payload data of part of a WebSocket frame. +// +// Payload of a WebSocket frame may be divided into multiple chunks. +// You need to look at |final_chunk| member variable to detect the end of a +// series of chunk objects of a WebSocket frame. +// +// Frame dissection is necessary to handle WebSocket frame stream containing +// abritrarily large frames in the browser process. Because the server may send +// a huge frame that doesn't fit in the memory, we cannot store the entire +// payload data in the memory. +// +// Users of this struct should treat WebSocket frames as a data stream; it's +// important to keep the frame data flowing, especially in the browser process. +// Users should not let the data stuck somewhere in the pipeline. +// +// This struct is used for reading WebSocket frame data (created by +// WebSocketFrameParser). To construct WebSocket frames, use functions below. +struct NET_EXPORT WebSocketFrameChunk { + WebSocketFrameChunk(); + ~WebSocketFrameChunk(); + + // Non-null |header| is provided only if this chunk is the first part of + // a series of chunks. + scoped_ptr<WebSocketFrameHeader> header; + + // Indicates this part is the last chunk of a frame. + bool final_chunk; + + // |data| is always unmasked even if the frame is masked. |data| might be + // null in the first chunk. + scoped_refptr<IOBufferWithSize> data; +}; + +// Contains four-byte data representing "masking key" of WebSocket frames. +struct WebSocketMaskingKey { + char key[WebSocketFrameHeader::kMaskingKeyLength]; +}; + +// Returns the size of WebSocket frame header. The size of WebSocket frame +// header varies from 2 bytes to 14 bytes depending on the payload length +// and maskedness. +NET_EXPORT int GetWebSocketFrameHeaderSize(const WebSocketFrameHeader& header); + +// Writes wire format of a WebSocket frame header into |output|, and returns +// the number of bytes written. +// +// WebSocket frame format is defined at: +// <http://tools.ietf.org/html/rfc6455#section-5.2>. This function writes +// everything but payload data in a WebSocket frame to |buffer|. +// +// If |header->masked| is true, |masking_key| must point to a valid +// WebSocketMaskingKey object containing the masking key for that frame +// (possibly generated by GenerateWebSocketMaskingKey() function below). +// Otherwise, |masking_key| must be NULL. +// +// |buffer| should have enough size to contain the frame header. +// GetWebSocketFrameHeaderSize() can be used to know the size of header +// beforehand. If the size of |buffer| is insufficient, this function returns +// ERR_INVALID_ARGUMENT and does not write any data to |buffer|. +NET_EXPORT int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header, + const WebSocketMaskingKey* masking_key, + char* buffer, + int buffer_size); + +// Generates a masking key suitable for use in a new WebSocket frame. +NET_EXPORT WebSocketMaskingKey GenerateWebSocketMaskingKey(); + +// Masks WebSocket frame payload. +// +// A client must mask every WebSocket frame by XOR'ing the frame payload +// with four-byte random data (masking key). This function applies the masking +// to the given payload data. +// +// This function masks |data| with |masking_key|, assuming |data| is partial +// data starting from |frame_offset| bytes from the beginning of the payload +// data. +// +// Since frame masking is a reversible operation, this function can also be +// used for unmasking a WebSocket frame. +NET_EXPORT void MaskWebSocketFramePayload( + const WebSocketMaskingKey& masking_key, + uint64 frame_offset, + char* data, + int data_size); + +} // namespace net + +#endif // NET_WEBSOCKETS_WEBSOCKET_FRAME_H_ |