OLD | NEW |
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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 *masked ^= masking_key.key[masking_key_offset++]; | 34 *masked ^= masking_key.key[masking_key_offset++]; |
35 if (masking_key_offset == net::WebSocketFrameHeader::kMaskingKeyLength) | 35 if (masking_key_offset == net::WebSocketFrameHeader::kMaskingKeyLength) |
36 masking_key_offset = 0; | 36 masking_key_offset = 0; |
37 } | 37 } |
38 } | 38 } |
39 | 39 |
40 } // Unnamed namespace. | 40 } // Unnamed namespace. |
41 | 41 |
42 namespace net { | 42 namespace net { |
43 | 43 |
44 scoped_ptr<WebSocketFrameHeader> WebSocketFrameHeader::Clone() { | 44 scoped_ptr<WebSocketFrameHeader> WebSocketFrameHeader::Clone() const { |
45 scoped_ptr<WebSocketFrameHeader> ret(new WebSocketFrameHeader(opcode)); | 45 scoped_ptr<WebSocketFrameHeader> ret(new WebSocketFrameHeader(opcode)); |
46 ret->final = final; | 46 ret->CopyFrom(*this); |
47 ret->reserved1 = reserved1; | |
48 ret->reserved2 = reserved2; | |
49 ret->reserved3 = reserved3; | |
50 ret->opcode = opcode; | |
51 ret->masked = masked; | |
52 ret->payload_length = payload_length; | |
53 return ret.Pass(); | 47 return ret.Pass(); |
54 } | 48 } |
55 | 49 |
| 50 void WebSocketFrameHeader::CopyFrom(const WebSocketFrameHeader& source) { |
| 51 final = source.final; |
| 52 reserved1 = source.reserved1; |
| 53 reserved2 = source.reserved2; |
| 54 reserved3 = source.reserved3; |
| 55 opcode = source.opcode; |
| 56 masked = source.masked; |
| 57 payload_length = source.payload_length; |
| 58 } |
| 59 |
| 60 WebSocketFrame::WebSocketFrame(WebSocketFrameHeader::OpCode opcode) |
| 61 : header(opcode) {} |
| 62 |
| 63 WebSocketFrame::~WebSocketFrame() {} |
| 64 |
56 WebSocketFrameChunk::WebSocketFrameChunk() : final_chunk(false) {} | 65 WebSocketFrameChunk::WebSocketFrameChunk() : final_chunk(false) {} |
57 | 66 |
58 WebSocketFrameChunk::~WebSocketFrameChunk() {} | 67 WebSocketFrameChunk::~WebSocketFrameChunk() {} |
59 | 68 |
60 int GetWebSocketFrameHeaderSize(const WebSocketFrameHeader& header) { | 69 int GetWebSocketFrameHeaderSize(const WebSocketFrameHeader& header) { |
61 int extended_length_size = 0; | 70 int extended_length_size = 0; |
62 if (header.payload_length > kMaxPayloadLengthWithoutExtendedLengthField && | 71 if (header.payload_length > kMaxPayloadLengthWithoutExtendedLengthField && |
63 header.payload_length <= kuint16max) { | 72 header.payload_length <= kuint16max) { |
64 extended_length_size = 2; | 73 extended_length_size = 2; |
65 } else if (header.payload_length > kuint16max) { | 74 } else if (header.payload_length > kuint16max) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 DCHECK(aligned_begin < end); | 197 DCHECK(aligned_begin < end); |
189 MaskWebSocketFramePayloadByBytes( | 198 MaskWebSocketFramePayloadByBytes( |
190 masking_key, frame_offset % kMaskingKeyLength, data, aligned_begin); | 199 masking_key, frame_offset % kMaskingKeyLength, data, aligned_begin); |
191 const size_t end_modulus = reinterpret_cast<size_t>(end) % kPackedMaskKeySize; | 200 const size_t end_modulus = reinterpret_cast<size_t>(end) % kPackedMaskKeySize; |
192 char* const aligned_end = end - end_modulus; | 201 char* const aligned_end = end - end_modulus; |
193 // Guaranteed by the above check for small data_size. | 202 // Guaranteed by the above check for small data_size. |
194 DCHECK(aligned_end > aligned_begin); | 203 DCHECK(aligned_end > aligned_begin); |
195 // Create a version of the mask which is rotated by the appropriate offset | 204 // Create a version of the mask which is rotated by the appropriate offset |
196 // for our alignment. The "trick" here is that 0 XORed with the mask will | 205 // for our alignment. The "trick" here is that 0 XORed with the mask will |
197 // give the value of the mask for the appropriate byte. | 206 // give the value of the mask for the appropriate byte. |
198 char realigned_mask[kMaskingKeyLength] = { 0 }; | 207 char realigned_mask[kMaskingKeyLength] = {}; |
199 MaskWebSocketFramePayloadByBytes( | 208 MaskWebSocketFramePayloadByBytes( |
200 masking_key, | 209 masking_key, |
201 (frame_offset + aligned_begin - data) % kMaskingKeyLength, | 210 (frame_offset + aligned_begin - data) % kMaskingKeyLength, |
202 realigned_mask, | 211 realigned_mask, |
203 realigned_mask + kMaskingKeyLength); | 212 realigned_mask + kMaskingKeyLength); |
204 | 213 |
205 for (size_t i = 0; i < kPackedMaskKeySize; i += kMaskingKeyLength) { | 214 for (size_t i = 0; i < kPackedMaskKeySize; i += kMaskingKeyLength) { |
206 // memcpy() is allegedly blessed by the C++ standard for type-punning. | 215 // memcpy() is allegedly blessed by the C++ standard for type-punning. |
207 memcpy(reinterpret_cast<char*>(&packed_mask_key) + i, | 216 memcpy(reinterpret_cast<char*>(&packed_mask_key) + i, |
208 realigned_mask, | 217 realigned_mask, |
(...skipping 12 matching lines...) Expand all Loading... |
221 } | 230 } |
222 | 231 |
223 MaskWebSocketFramePayloadByBytes( | 232 MaskWebSocketFramePayloadByBytes( |
224 masking_key, | 233 masking_key, |
225 (frame_offset + (aligned_end - data)) % kMaskingKeyLength, | 234 (frame_offset + (aligned_end - data)) % kMaskingKeyLength, |
226 aligned_end, | 235 aligned_end, |
227 end); | 236 end); |
228 } | 237 } |
229 | 238 |
230 } // namespace net | 239 } // namespace net |
OLD | NEW |