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

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

Issue 14850012: Add missing status codes to WebSocketError enum. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Remove other mux status codes. Created 7 years, 7 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
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_parser.h" 5 #include "net/websockets/websocket_frame_parser.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 18 matching lines...) Expand all
29 const uint64 kPayloadLengthWithTwoByteExtendedLengthField = 126; 29 const uint64 kPayloadLengthWithTwoByteExtendedLengthField = 126;
30 const uint64 kPayloadLengthWithEightByteExtendedLengthField = 127; 30 const uint64 kPayloadLengthWithEightByteExtendedLengthField = 127;
31 31
32 } // Unnamed namespace. 32 } // Unnamed namespace.
33 33
34 namespace net { 34 namespace net {
35 35
36 WebSocketFrameParser::WebSocketFrameParser() 36 WebSocketFrameParser::WebSocketFrameParser()
37 : current_read_pos_(0), 37 : current_read_pos_(0),
38 frame_offset_(0), 38 frame_offset_(0),
39 websocket_error_(WEB_SOCKET_OK) { 39 websocket_error_(kWebSocketNormalClosure) {
40 std::fill(masking_key_.key, 40 std::fill(masking_key_.key,
41 masking_key_.key + WebSocketFrameHeader::kMaskingKeyLength, 41 masking_key_.key + WebSocketFrameHeader::kMaskingKeyLength,
42 '\0'); 42 '\0');
43 } 43 }
44 44
45 WebSocketFrameParser::~WebSocketFrameParser() { 45 WebSocketFrameParser::~WebSocketFrameParser() {
46 } 46 }
47 47
48 bool WebSocketFrameParser::Decode( 48 bool WebSocketFrameParser::Decode(
49 const char* data, 49 const char* data,
50 size_t length, 50 size_t length,
51 ScopedVector<WebSocketFrameChunk>* frame_chunks) { 51 ScopedVector<WebSocketFrameChunk>* frame_chunks) {
52 if (websocket_error_ != WEB_SOCKET_OK) 52 if (websocket_error_ != kWebSocketNormalClosure)
53 return false; 53 return false;
54 if (!length) 54 if (!length)
55 return true; 55 return true;
56 56
57 // TODO(yutak): Remove copy. 57 // TODO(yutak): Remove copy.
58 buffer_.insert(buffer_.end(), data, data + length); 58 buffer_.insert(buffer_.end(), data, data + length);
59 59
60 while (current_read_pos_ < buffer_.size()) { 60 while (current_read_pos_ < buffer_.size()) {
61 bool first_chunk = false; 61 bool first_chunk = false;
62 if (!current_frame_header_.get()) { 62 if (!current_frame_header_.get()) {
63 DecodeFrameHeader(); 63 DecodeFrameHeader();
64 if (websocket_error_ != WEB_SOCKET_OK) 64 if (websocket_error_ != kWebSocketNormalClosure)
65 return false; 65 return false;
66 // If frame header is incomplete, then carry over the remaining 66 // If frame header is incomplete, then carry over the remaining
67 // data to the next round of Decode(). 67 // data to the next round of Decode().
68 if (!current_frame_header_.get()) 68 if (!current_frame_header_.get())
69 break; 69 break;
70 first_chunk = true; 70 first_chunk = true;
71 } 71 }
72 72
73 scoped_ptr<WebSocketFrameChunk> frame_chunk = 73 scoped_ptr<WebSocketFrameChunk> frame_chunk =
74 DecodeFramePayload(first_chunk); 74 DecodeFramePayload(first_chunk);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 bool masked = (second_byte & kMaskBit) != 0; 122 bool masked = (second_byte & kMaskBit) != 0;
123 uint64 payload_length = second_byte & kPayloadLengthMask; 123 uint64 payload_length = second_byte & kPayloadLengthMask;
124 if (payload_length == kPayloadLengthWithTwoByteExtendedLengthField) { 124 if (payload_length == kPayloadLengthWithTwoByteExtendedLengthField) {
125 if (end - current < 2) 125 if (end - current < 2)
126 return; 126 return;
127 uint16 payload_length_16; 127 uint16 payload_length_16;
128 ReadBigEndian(current, &payload_length_16); 128 ReadBigEndian(current, &payload_length_16);
129 current += 2; 129 current += 2;
130 payload_length = payload_length_16; 130 payload_length = payload_length_16;
131 if (payload_length <= kMaxPayloadLengthWithoutExtendedLengthField) 131 if (payload_length <= kMaxPayloadLengthWithoutExtendedLengthField)
132 websocket_error_ = WEB_SOCKET_ERR_PROTOCOL_ERROR; 132 websocket_error_ = kWebSocketErrorProtocolError;
133 } else if (payload_length == kPayloadLengthWithEightByteExtendedLengthField) { 133 } else if (payload_length == kPayloadLengthWithEightByteExtendedLengthField) {
134 if (end - current < 8) 134 if (end - current < 8)
135 return; 135 return;
136 ReadBigEndian(current, &payload_length); 136 ReadBigEndian(current, &payload_length);
137 current += 8; 137 current += 8;
138 if (payload_length <= kuint16max || 138 if (payload_length <= kuint16max ||
139 payload_length > static_cast<uint64>(kint64max)) { 139 payload_length > static_cast<uint64>(kint64max)) {
140 websocket_error_ = WEB_SOCKET_ERR_PROTOCOL_ERROR; 140 websocket_error_ = kWebSocketErrorProtocolError;
141 } else if (payload_length > static_cast<uint64>(kint32max)) { 141 } else if (payload_length > static_cast<uint64>(kint32max)) {
142 websocket_error_ = WEB_SOCKET_ERR_MESSAGE_TOO_BIG; 142 websocket_error_ = kWebSocketErrorMessageTooBig;
143 } 143 }
144 } 144 }
145 if (websocket_error_ != WEB_SOCKET_OK) { 145 if (websocket_error_ != kWebSocketNormalClosure) {
146 buffer_.clear(); 146 buffer_.clear();
147 current_read_pos_ = 0; 147 current_read_pos_ = 0;
148 current_frame_header_.reset(); 148 current_frame_header_.reset();
149 frame_offset_ = 0; 149 frame_offset_ = 0;
150 return; 150 return;
151 } 151 }
152 152
153 if (masked) { 153 if (masked) {
154 if (end - current < kMaskingKeyLength) 154 if (end - current < kMaskingKeyLength)
155 return; 155 return;
156 std::copy(current, current + kMaskingKeyLength, masking_key_.key); 156 std::copy(current, current + kMaskingKeyLength, masking_key_.key);
157 current += kMaskingKeyLength; 157 current += kMaskingKeyLength;
158 } else { 158 } else {
159 std::fill(masking_key_.key, masking_key_.key + kMaskingKeyLength, '\0'); 159 std::fill(masking_key_.key, masking_key_.key + kMaskingKeyLength, '\0');
160 } 160 }
161 161
162 current_frame_header_.reset(new WebSocketFrameHeader); 162 current_frame_header_.reset(new WebSocketFrameHeader(opcode));
163 current_frame_header_->final = final; 163 current_frame_header_->final = final;
164 current_frame_header_->reserved1 = reserved1; 164 current_frame_header_->reserved1 = reserved1;
165 current_frame_header_->reserved2 = reserved2; 165 current_frame_header_->reserved2 = reserved2;
166 current_frame_header_->reserved3 = reserved3; 166 current_frame_header_->reserved3 = reserved3;
167 current_frame_header_->opcode = opcode;
168 current_frame_header_->masked = masked; 167 current_frame_header_->masked = masked;
169 current_frame_header_->payload_length = payload_length; 168 current_frame_header_->payload_length = payload_length;
170 current_read_pos_ += current - start; 169 current_read_pos_ += current - start;
171 DCHECK_EQ(0u, frame_offset_); 170 DCHECK_EQ(0u, frame_offset_);
172 } 171 }
173 172
174 scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload( 173 scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload(
175 bool first_chunk) { 174 bool first_chunk) {
176 const char* current = &buffer_.front() + current_read_pos_; 175 const char* current = &buffer_.front() + current_read_pos_;
177 const char* end = &buffer_.front() + buffer_.size(); 176 const char* end = &buffer_.front() + buffer_.size();
178 uint64 next_size = std::min<uint64>( 177 uint64 next_size = std::min<uint64>(
179 end - current, 178 end - current,
180 current_frame_header_->payload_length - frame_offset_); 179 current_frame_header_->payload_length - frame_offset_);
181 // This check must pass because |payload_length| is already checked to be 180 // This check must pass because |payload_length| is already checked to be
182 // less than std::numeric_limits<int>::max() when the header is parsed. 181 // less than std::numeric_limits<int>::max() when the header is parsed.
183 DCHECK_LE(next_size, static_cast<uint64>(kint32max)); 182 DCHECK_LE(next_size, static_cast<uint64>(kint32max));
184 183
185 scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk); 184 scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk);
186 if (first_chunk) { 185 if (first_chunk) {
187 frame_chunk->header.reset(new WebSocketFrameHeader(*current_frame_header_)); 186 frame_chunk->header = current_frame_header_->Clone();
188 } 187 }
189 frame_chunk->final_chunk = false; 188 frame_chunk->final_chunk = false;
190 if (next_size) { 189 if (next_size) {
191 frame_chunk->data = new IOBufferWithSize(static_cast<int>(next_size)); 190 frame_chunk->data = new IOBufferWithSize(static_cast<int>(next_size));
192 char* io_data = frame_chunk->data->data(); 191 char* io_data = frame_chunk->data->data();
193 memcpy(io_data, current, next_size); 192 memcpy(io_data, current, next_size);
194 if (current_frame_header_->masked) { 193 if (current_frame_header_->masked) {
195 // The masking function is its own inverse, so we use the same function to 194 // The masking function is its own inverse, so we use the same function to
196 // unmask as to mask. 195 // unmask as to mask.
197 MaskWebSocketFramePayload(masking_key_, frame_offset_, 196 MaskWebSocketFramePayload(masking_key_, frame_offset_,
198 io_data, next_size); 197 io_data, next_size);
199 } 198 }
200 199
201 current_read_pos_ += next_size; 200 current_read_pos_ += next_size;
202 frame_offset_ += next_size; 201 frame_offset_ += next_size;
203 } 202 }
204 203
205 DCHECK_LE(frame_offset_, current_frame_header_->payload_length); 204 DCHECK_LE(frame_offset_, current_frame_header_->payload_length);
206 if (frame_offset_ == current_frame_header_->payload_length) { 205 if (frame_offset_ == current_frame_header_->payload_length) {
207 frame_chunk->final_chunk = true; 206 frame_chunk->final_chunk = true;
208 current_frame_header_.reset(); 207 current_frame_header_.reset();
209 frame_offset_ = 0; 208 frame_offset_ = 0;
210 } 209 }
211 210
212 return frame_chunk.Pass(); 211 return frame_chunk.Pass();
213 } 212 }
214 213
215 } // namespace net 214 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_frame_parser.h ('k') | net/websockets/websocket_frame_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698