Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: net/websockets/websocket_frame.cc

Issue 10825444: Add a function that calculates the size of WebSocket frame header. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/websockets/websocket_frame.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/websockets/websocket_frame.h" 5 #include "net/websockets/websocket_frame.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/rand_util.h" 9 #include "base/rand_util.h"
10 #include "net/base/big_endian.h" 10 #include "net/base/big_endian.h"
(...skipping 24 matching lines...) Expand all
35 const WebSocketFrameHeader::OpCode WebSocketFrameHeader::kOpCodeClose = 0x8; 35 const WebSocketFrameHeader::OpCode WebSocketFrameHeader::kOpCodeClose = 0x8;
36 const WebSocketFrameHeader::OpCode WebSocketFrameHeader::kOpCodePing = 0x9; 36 const WebSocketFrameHeader::OpCode WebSocketFrameHeader::kOpCodePing = 0x9;
37 const WebSocketFrameHeader::OpCode WebSocketFrameHeader::kOpCodePong = 0xA; 37 const WebSocketFrameHeader::OpCode WebSocketFrameHeader::kOpCodePong = 0xA;
38 38
39 WebSocketFrameChunk::WebSocketFrameChunk() : final_chunk(false) { 39 WebSocketFrameChunk::WebSocketFrameChunk() : final_chunk(false) {
40 } 40 }
41 41
42 WebSocketFrameChunk::~WebSocketFrameChunk() { 42 WebSocketFrameChunk::~WebSocketFrameChunk() {
43 } 43 }
44 44
45 int GetWebSocketFrameHeaderSize(const WebSocketFrameHeader& header) {
46 int extended_length_size = 0;
47 if (header.payload_length > kMaxPayloadLengthWithoutExtendedLengthField &&
48 header.payload_length <= kuint16max) {
49 extended_length_size = 2;
50 } else if (header.payload_length > kuint16max) {
51 extended_length_size = 8;
52 }
53
54 int header_size =
mmenke 2012/08/20 16:33:46 optional: May want to just return this, rather th
Yuta Kitamura 2012/08/21 04:22:21 Done.
55 WebSocketFrameHeader::kBaseHeaderSize +
56 extended_length_size +
57 (header.masked ? WebSocketFrameHeader::kMaskingKeyLength : 0);
58 return header_size;
59 }
60
45 int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header, 61 int WriteWebSocketFrameHeader(const WebSocketFrameHeader& header,
46 const WebSocketMaskingKey* masking_key, 62 const WebSocketMaskingKey* masking_key,
47 char* buffer, 63 char* buffer,
48 int buffer_size) { 64 int buffer_size) {
49 DCHECK((header.opcode & kOpCodeMask) == header.opcode) 65 DCHECK((header.opcode & kOpCodeMask) == header.opcode)
50 << "header.opcode must fit to kOpCodeMask."; 66 << "header.opcode must fit to kOpCodeMask.";
51 DCHECK(header.payload_length <= static_cast<uint64>(kint64max)) 67 DCHECK(header.payload_length <= static_cast<uint64>(kint64max))
52 << "WebSocket specification doesn't allow a frame longer than " 68 << "WebSocket specification doesn't allow a frame longer than "
53 << "kint64max (0x7FFFFFFFFFFFFFFF) bytes."; 69 << "kint64max (0x7FFFFFFFFFFFFFFF) bytes.";
54 DCHECK_GE(buffer_size, 0); 70 DCHECK_GE(buffer_size, 0);
55 71
56 // WebSocket frame format is as follows: 72 // WebSocket frame format is as follows:
57 // - Common header (2 bytes) 73 // - Common header (2 bytes)
58 // - Optional extended payload length 74 // - Optional extended payload length
59 // (2 or 8 bytes, present if actual payload length is more than 125 bytes) 75 // (2 or 8 bytes, present if actual payload length is more than 125 bytes)
60 // - Optional masking key (4 bytes, present if MASK bit is on) 76 // - Optional masking key (4 bytes, present if MASK bit is on)
61 // - Actual payload (XOR masked with masking key if MASK bit is on) 77 // - Actual payload (XOR masked with masking key if MASK bit is on)
62 // 78 //
63 // This function constructs frame header (the first three in the list 79 // This function constructs frame header (the first three in the list
64 // above). 80 // above).
65 81
66 size_t extended_length_size = 0; 82 int header_size = GetWebSocketFrameHeaderSize(header);
67 if (header.payload_length > kMaxPayloadLengthWithoutExtendedLengthField &&
68 header.payload_length <= kuint16max) {
69 extended_length_size = 2;
70 } else if (header.payload_length > kuint16max) {
71 extended_length_size = 8;
72 }
73 int header_size =
74 WebSocketFrameHeader::kBaseHeaderSize +
75 extended_length_size +
76 (header.masked ? WebSocketFrameHeader::kMaskingKeyLength : 0);
77 if (header_size > buffer_size) 83 if (header_size > buffer_size)
78 return ERR_INVALID_ARGUMENT; 84 return ERR_INVALID_ARGUMENT;
79 85
80 int buffer_index = 0; 86 int buffer_index = 0;
81 87
82 uint8 first_byte = 0u; 88 uint8 first_byte = 0u;
83 first_byte |= header.final ? kFinalBit : 0u; 89 first_byte |= header.final ? kFinalBit : 0u;
84 first_byte |= header.reserved1 ? kReserved1Bit : 0u; 90 first_byte |= header.reserved1 ? kReserved1Bit : 0u;
85 first_byte |= header.reserved2 ? kReserved2Bit : 0u; 91 first_byte |= header.reserved2 ? kReserved2Bit : 0u;
86 first_byte |= header.reserved3 ? kReserved3Bit : 0u; 92 first_byte |= header.reserved3 ? kReserved3Bit : 0u;
87 first_byte |= header.opcode & kOpCodeMask; 93 first_byte |= header.opcode & kOpCodeMask;
88 buffer[buffer_index++] = first_byte; 94 buffer[buffer_index++] = first_byte;
89 95
96 int extended_length_size = 0;
90 uint8 second_byte = 0u; 97 uint8 second_byte = 0u;
91 second_byte |= header.masked ? kMaskBit : 0u; 98 second_byte |= header.masked ? kMaskBit : 0u;
92 if (header.payload_length <= 99 if (header.payload_length <=
93 kMaxPayloadLengthWithoutExtendedLengthField) { 100 kMaxPayloadLengthWithoutExtendedLengthField) {
94 second_byte |= header.payload_length; 101 second_byte |= header.payload_length;
95 } else if (header.payload_length <= kuint16max) { 102 } else if (header.payload_length <= kuint16max) {
96 second_byte |= kPayloadLengthWithTwoByteExtendedLengthField; 103 second_byte |= kPayloadLengthWithTwoByteExtendedLengthField;
104 extended_length_size = 2;
97 } else { 105 } else {
98 second_byte |= kPayloadLengthWithEightByteExtendedLengthField; 106 second_byte |= kPayloadLengthWithEightByteExtendedLengthField;
107 extended_length_size = 8;
99 } 108 }
100 buffer[buffer_index++] = second_byte; 109 buffer[buffer_index++] = second_byte;
101 110
102 // Writes "extended payload length" field. 111 // Writes "extended payload length" field.
103 if (extended_length_size == 2u) { 112 if (extended_length_size == 2) {
104 uint16 payload_length_16 = static_cast<uint16>(header.payload_length); 113 uint16 payload_length_16 = static_cast<uint16>(header.payload_length);
105 WriteBigEndian(buffer + buffer_index, payload_length_16); 114 WriteBigEndian(buffer + buffer_index, payload_length_16);
106 buffer_index += sizeof(uint16); 115 buffer_index += sizeof(uint16);
107 } else if (extended_length_size == 8u) { 116 } else if (extended_length_size == 8) {
108 WriteBigEndian(buffer + buffer_index, header.payload_length); 117 WriteBigEndian(buffer + buffer_index, header.payload_length);
109 buffer_index += sizeof(uint64); 118 buffer_index += sizeof(uint64);
110 } 119 }
111 120
112 // Writes "masking key" field, if needed. 121 // Writes "masking key" field, if needed.
113 if (header.masked) { 122 if (header.masked) {
114 DCHECK(masking_key); 123 DCHECK(masking_key);
115 std::copy(masking_key->key, 124 std::copy(masking_key->key,
116 masking_key->key + WebSocketFrameHeader::kMaskingKeyLength, 125 masking_key->key + WebSocketFrameHeader::kMaskingKeyLength,
117 buffer + buffer_index); 126 buffer + buffer_index);
(...skipping 28 matching lines...) Expand all
146 // (4 or 8 bytes), instead of XOR'ing every byte. 155 // (4 or 8 bytes), instead of XOR'ing every byte.
147 size_t masking_key_offset = frame_offset % kMaskingKeyLength; 156 size_t masking_key_offset = frame_offset % kMaskingKeyLength;
148 for (int i = 0; i < data_size; ++i) { 157 for (int i = 0; i < data_size; ++i) {
149 data[i] ^= masking_key.key[masking_key_offset++]; 158 data[i] ^= masking_key.key[masking_key_offset++];
150 if (masking_key_offset == kMaskingKeyLength) 159 if (masking_key_offset == kMaskingKeyLength)
151 masking_key_offset = 0; 160 masking_key_offset = 0;
152 } 161 }
153 } 162 }
154 163
155 } // namespace net 164 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_frame.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698