| 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_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 24 matching lines...) Expand all Loading... |
| 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_(kWebSocketNormalClosure) { | 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 } | |
| 47 | 46 |
| 48 bool WebSocketFrameParser::Decode( | 47 bool WebSocketFrameParser::Decode( |
| 49 const char* data, | 48 const char* data, |
| 50 size_t length, | 49 size_t length, |
| 51 ScopedVector<WebSocketFrameChunk>* frame_chunks) { | 50 ScopedVector<WebSocketFrameChunk>* frame_chunks) { |
| 52 if (websocket_error_ != kWebSocketNormalClosure) | 51 if (websocket_error_ != kWebSocketNormalClosure) |
| 53 return false; | 52 return false; |
| 54 if (!length) | 53 if (!length) |
| 55 return true; | 54 return true; |
| 56 | 55 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 current_frame_header_->payload_length = payload_length; | 167 current_frame_header_->payload_length = payload_length; |
| 169 current_read_pos_ += current - start; | 168 current_read_pos_ += current - start; |
| 170 DCHECK_EQ(0u, frame_offset_); | 169 DCHECK_EQ(0u, frame_offset_); |
| 171 } | 170 } |
| 172 | 171 |
| 173 scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload( | 172 scoped_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload( |
| 174 bool first_chunk) { | 173 bool first_chunk) { |
| 175 const char* current = &buffer_.front() + current_read_pos_; | 174 const char* current = &buffer_.front() + current_read_pos_; |
| 176 const char* end = &buffer_.front() + buffer_.size(); | 175 const char* end = &buffer_.front() + buffer_.size(); |
| 177 uint64 next_size = std::min<uint64>( | 176 uint64 next_size = std::min<uint64>( |
| 178 end - current, | 177 end - current, current_frame_header_->payload_length - frame_offset_); |
| 179 current_frame_header_->payload_length - frame_offset_); | |
| 180 // This check must pass because |payload_length| is already checked to be | 178 // This check must pass because |payload_length| is already checked to be |
| 181 // less than std::numeric_limits<int>::max() when the header is parsed. | 179 // less than std::numeric_limits<int>::max() when the header is parsed. |
| 182 DCHECK_LE(next_size, static_cast<uint64>(kint32max)); | 180 DCHECK_LE(next_size, static_cast<uint64>(kint32max)); |
| 183 | 181 |
| 184 scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk); | 182 scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk); |
| 185 if (first_chunk) { | 183 if (first_chunk) { |
| 186 frame_chunk->header = current_frame_header_->Clone(); | 184 frame_chunk->header = current_frame_header_->Clone(); |
| 187 } | 185 } |
| 188 frame_chunk->final_chunk = false; | 186 frame_chunk->final_chunk = false; |
| 189 if (next_size) { | 187 if (next_size) { |
| 190 frame_chunk->data = new IOBufferWithSize(static_cast<int>(next_size)); | 188 frame_chunk->data = new IOBufferWithSize(static_cast<int>(next_size)); |
| 191 char* io_data = frame_chunk->data->data(); | 189 char* io_data = frame_chunk->data->data(); |
| 192 memcpy(io_data, current, next_size); | 190 memcpy(io_data, current, next_size); |
| 193 if (current_frame_header_->masked) { | 191 if (current_frame_header_->masked) { |
| 194 // The masking function is its own inverse, so we use the same function to | 192 // The masking function is its own inverse, so we use the same function to |
| 195 // unmask as to mask. | 193 // unmask as to mask. |
| 196 MaskWebSocketFramePayload(masking_key_, frame_offset_, | 194 MaskWebSocketFramePayload( |
| 197 io_data, next_size); | 195 masking_key_, frame_offset_, io_data, next_size); |
| 198 } | 196 } |
| 199 | 197 |
| 200 current_read_pos_ += next_size; | 198 current_read_pos_ += next_size; |
| 201 frame_offset_ += next_size; | 199 frame_offset_ += next_size; |
| 202 } | 200 } |
| 203 | 201 |
| 204 DCHECK_LE(frame_offset_, current_frame_header_->payload_length); | 202 DCHECK_LE(frame_offset_, current_frame_header_->payload_length); |
| 205 if (frame_offset_ == current_frame_header_->payload_length) { | 203 if (frame_offset_ == current_frame_header_->payload_length) { |
| 206 frame_chunk->final_chunk = true; | 204 frame_chunk->final_chunk = true; |
| 207 current_frame_header_.reset(); | 205 current_frame_header_.reset(); |
| 208 frame_offset_ = 0; | 206 frame_offset_ = 0; |
| 209 } | 207 } |
| 210 | 208 |
| 211 return frame_chunk.Pass(); | 209 return frame_chunk.Pass(); |
| 212 } | 210 } |
| 213 | 211 |
| 214 } // namespace net | 212 } // namespace net |
| OLD | NEW |