OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_deflate_stream.h" | 5 #include "net/websockets/websocket_deflate_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 OnMessageStart(*frames, i); | 122 OnMessageStart(*frames, i); |
123 | 123 |
124 scoped_ptr<WebSocketFrame> frame((*frames)[i]); | 124 scoped_ptr<WebSocketFrame> frame((*frames)[i]); |
125 (*frames)[i] = NULL; | 125 (*frames)[i] = NULL; |
126 predictor_->RecordInputDataFrame(frame.get()); | 126 predictor_->RecordInputDataFrame(frame.get()); |
127 | 127 |
128 if (writing_state_ == WRITING_UNCOMPRESSED_MESSAGE) { | 128 if (writing_state_ == WRITING_UNCOMPRESSED_MESSAGE) { |
129 if (frame->header.final) | 129 if (frame->header.final) |
130 writing_state_ = NOT_WRITING; | 130 writing_state_ = NOT_WRITING; |
131 predictor_->RecordWrittenDataFrame(frame.get()); | 131 predictor_->RecordWrittenDataFrame(frame.get()); |
132 frames_to_write.push_back(frame.release()); | 132 frames_to_write.push_back(frame.Pass()); |
133 current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; | 133 current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; |
134 } else { | 134 } else { |
135 if (frame->data.get() && | 135 if (frame->data.get() && |
136 !deflater_.AddBytes( | 136 !deflater_.AddBytes( |
137 frame->data->data(), | 137 frame->data->data(), |
138 static_cast<size_t>(frame->header.payload_length))) { | 138 static_cast<size_t>(frame->header.payload_length))) { |
139 DVLOG(1) << "WebSocket protocol error. " | 139 DVLOG(1) << "WebSocket protocol error. " |
140 << "deflater_.AddBytes() returns an error."; | 140 << "deflater_.AddBytes() returns an error."; |
141 return ERR_WS_PROTOCOL_ERROR; | 141 return ERR_WS_PROTOCOL_ERROR; |
142 } | 142 } |
143 if (frame->header.final && !deflater_.Finish()) { | 143 if (frame->header.final && !deflater_.Finish()) { |
144 DVLOG(1) << "WebSocket protocol error. " | 144 DVLOG(1) << "WebSocket protocol error. " |
145 << "deflater_.Finish() returns an error."; | 145 << "deflater_.Finish() returns an error."; |
146 return ERR_WS_PROTOCOL_ERROR; | 146 return ERR_WS_PROTOCOL_ERROR; |
147 } | 147 } |
148 | 148 |
149 if (writing_state_ == WRITING_COMPRESSED_MESSAGE) { | 149 if (writing_state_ == WRITING_COMPRESSED_MESSAGE) { |
150 if (deflater_.CurrentOutputSize() >= kChunkSize || | 150 if (deflater_.CurrentOutputSize() >= kChunkSize || |
151 frame->header.final) { | 151 frame->header.final) { |
152 int result = AppendCompressedFrame(frame->header, &frames_to_write); | 152 int result = AppendCompressedFrame(frame->header, &frames_to_write); |
153 if (result != OK) | 153 if (result != OK) |
154 return result; | 154 return result; |
155 } | 155 } |
156 if (frame->header.final) | 156 if (frame->header.final) |
157 writing_state_ = NOT_WRITING; | 157 writing_state_ = NOT_WRITING; |
158 } else { | 158 } else { |
159 DCHECK_EQ(WRITING_POSSIBLY_COMPRESSED_MESSAGE, writing_state_); | 159 DCHECK_EQ(WRITING_POSSIBLY_COMPRESSED_MESSAGE, writing_state_); |
160 bool final = frame->header.final; | 160 bool final = frame->header.final; |
161 frames_of_message.push_back(frame.release()); | 161 frames_of_message.push_back(frame.Pass()); |
162 if (final) { | 162 if (final) { |
163 int result = AppendPossiblyCompressedMessage(&frames_of_message, | 163 int result = AppendPossiblyCompressedMessage(&frames_of_message, |
164 &frames_to_write); | 164 &frames_to_write); |
165 if (result != OK) | 165 if (result != OK) |
166 return result; | 166 return result; |
167 frames_of_message.clear(); | 167 frames_of_message.clear(); |
168 writing_state_ = NOT_WRITING; | 168 writing_state_ = NOT_WRITING; |
169 } | 169 } |
170 } | 170 } |
171 } | 171 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 compressed->header.CopyFrom(header); | 213 compressed->header.CopyFrom(header); |
214 compressed->header.opcode = opcode; | 214 compressed->header.opcode = opcode; |
215 compressed->header.final = header.final; | 215 compressed->header.final = header.final; |
216 compressed->header.reserved1 = | 216 compressed->header.reserved1 = |
217 (opcode != WebSocketFrameHeader::kOpCodeContinuation); | 217 (opcode != WebSocketFrameHeader::kOpCodeContinuation); |
218 compressed->data = compressed_payload; | 218 compressed->data = compressed_payload; |
219 compressed->header.payload_length = compressed_payload->size(); | 219 compressed->header.payload_length = compressed_payload->size(); |
220 | 220 |
221 current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; | 221 current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; |
222 predictor_->RecordWrittenDataFrame(compressed.get()); | 222 predictor_->RecordWrittenDataFrame(compressed.get()); |
223 frames_to_write->push_back(compressed.release()); | 223 frames_to_write->push_back(compressed.Pass()); |
224 return OK; | 224 return OK; |
225 } | 225 } |
226 | 226 |
227 int WebSocketDeflateStream::AppendPossiblyCompressedMessage( | 227 int WebSocketDeflateStream::AppendPossiblyCompressedMessage( |
228 ScopedVector<WebSocketFrame>* frames, | 228 ScopedVector<WebSocketFrame>* frames, |
229 ScopedVector<WebSocketFrame>* frames_to_write) { | 229 ScopedVector<WebSocketFrame>* frames_to_write) { |
230 DCHECK(!frames->empty()); | 230 DCHECK(!frames->empty()); |
231 | 231 |
232 const WebSocketFrameHeader::OpCode opcode = current_writing_opcode_; | 232 const WebSocketFrameHeader::OpCode opcode = current_writing_opcode_; |
233 scoped_refptr<IOBufferWithSize> compressed_payload = | 233 scoped_refptr<IOBufferWithSize> compressed_payload = |
(...skipping 29 matching lines...) Expand all Loading... |
263 } | 263 } |
264 scoped_ptr<WebSocketFrame> compressed(new WebSocketFrame(opcode)); | 264 scoped_ptr<WebSocketFrame> compressed(new WebSocketFrame(opcode)); |
265 compressed->header.CopyFrom((*frames)[0]->header); | 265 compressed->header.CopyFrom((*frames)[0]->header); |
266 compressed->header.opcode = opcode; | 266 compressed->header.opcode = opcode; |
267 compressed->header.final = true; | 267 compressed->header.final = true; |
268 compressed->header.reserved1 = true; | 268 compressed->header.reserved1 = true; |
269 compressed->data = compressed_payload; | 269 compressed->data = compressed_payload; |
270 compressed->header.payload_length = compressed_payload->size(); | 270 compressed->header.payload_length = compressed_payload->size(); |
271 | 271 |
272 predictor_->RecordWrittenDataFrame(compressed.get()); | 272 predictor_->RecordWrittenDataFrame(compressed.get()); |
273 frames_to_write->push_back(compressed.release()); | 273 frames_to_write->push_back(compressed.Pass()); |
274 return OK; | 274 return OK; |
275 } | 275 } |
276 | 276 |
277 int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) { | 277 int WebSocketDeflateStream::Inflate(ScopedVector<WebSocketFrame>* frames) { |
278 ScopedVector<WebSocketFrame> frames_to_output; | 278 ScopedVector<WebSocketFrame> frames_to_output; |
279 ScopedVector<WebSocketFrame> frames_passed; | 279 ScopedVector<WebSocketFrame> frames_passed; |
280 frames->swap(frames_passed); | 280 frames->swap(frames_passed); |
281 for (size_t i = 0; i < frames_passed.size(); ++i) { | 281 for (size_t i = 0; i < frames_passed.size(); ++i) { |
282 scoped_ptr<WebSocketFrame> frame(frames_passed[i]); | 282 scoped_ptr<WebSocketFrame> frame(frames_passed[i]); |
283 frames_passed[i] = NULL; | 283 frames_passed[i] = NULL; |
284 DVLOG(3) << "Input frame: opcode=" << frame->header.opcode | 284 DVLOG(3) << "Input frame: opcode=" << frame->header.opcode |
285 << " final=" << frame->header.final | 285 << " final=" << frame->header.final |
286 << " reserved1=" << frame->header.reserved1 | 286 << " reserved1=" << frame->header.reserved1 |
287 << " payload_length=" << frame->header.payload_length; | 287 << " payload_length=" << frame->header.payload_length; |
288 | 288 |
289 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) { | 289 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) { |
290 frames_to_output.push_back(frame.release()); | 290 frames_to_output.push_back(frame.Pass()); |
291 continue; | 291 continue; |
292 } | 292 } |
293 | 293 |
294 if (reading_state_ == NOT_READING) { | 294 if (reading_state_ == NOT_READING) { |
295 if (frame->header.reserved1) | 295 if (frame->header.reserved1) |
296 reading_state_ = READING_COMPRESSED_MESSAGE; | 296 reading_state_ = READING_COMPRESSED_MESSAGE; |
297 else | 297 else |
298 reading_state_ = READING_UNCOMPRESSED_MESSAGE; | 298 reading_state_ = READING_UNCOMPRESSED_MESSAGE; |
299 current_reading_opcode_ = frame->header.opcode; | 299 current_reading_opcode_ = frame->header.opcode; |
300 } else { | 300 } else { |
301 if (frame->header.reserved1) { | 301 if (frame->header.reserved1) { |
302 DVLOG(1) << "WebSocket protocol error. " | 302 DVLOG(1) << "WebSocket protocol error. " |
303 << "Receiving a non-first frame with RSV1 flag set."; | 303 << "Receiving a non-first frame with RSV1 flag set."; |
304 return ERR_WS_PROTOCOL_ERROR; | 304 return ERR_WS_PROTOCOL_ERROR; |
305 } | 305 } |
306 } | 306 } |
307 | 307 |
308 if (reading_state_ == READING_UNCOMPRESSED_MESSAGE) { | 308 if (reading_state_ == READING_UNCOMPRESSED_MESSAGE) { |
309 if (frame->header.final) | 309 if (frame->header.final) |
310 reading_state_ = NOT_READING; | 310 reading_state_ = NOT_READING; |
311 current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; | 311 current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; |
312 frames_to_output.push_back(frame.release()); | 312 frames_to_output.push_back(frame.Pass()); |
313 } else { | 313 } else { |
314 DCHECK_EQ(reading_state_, READING_COMPRESSED_MESSAGE); | 314 DCHECK_EQ(reading_state_, READING_COMPRESSED_MESSAGE); |
315 if (frame->data.get() && | 315 if (frame->data.get() && |
316 !inflater_.AddBytes( | 316 !inflater_.AddBytes( |
317 frame->data->data(), | 317 frame->data->data(), |
318 static_cast<size_t>(frame->header.payload_length))) { | 318 static_cast<size_t>(frame->header.payload_length))) { |
319 DVLOG(1) << "WebSocket protocol error. " | 319 DVLOG(1) << "WebSocket protocol error. " |
320 << "inflater_.AddBytes() returns an error."; | 320 << "inflater_.AddBytes() returns an error."; |
321 return ERR_WS_PROTOCOL_ERROR; | 321 return ERR_WS_PROTOCOL_ERROR; |
322 } | 322 } |
(...skipping 23 matching lines...) Expand all Loading... |
346 inflated->header.CopyFrom(frame->header); | 346 inflated->header.CopyFrom(frame->header); |
347 inflated->header.opcode = current_reading_opcode_; | 347 inflated->header.opcode = current_reading_opcode_; |
348 inflated->header.final = is_final; | 348 inflated->header.final = is_final; |
349 inflated->header.reserved1 = false; | 349 inflated->header.reserved1 = false; |
350 inflated->data = data; | 350 inflated->data = data; |
351 inflated->header.payload_length = data->size(); | 351 inflated->header.payload_length = data->size(); |
352 DVLOG(3) << "Inflated frame: opcode=" << inflated->header.opcode | 352 DVLOG(3) << "Inflated frame: opcode=" << inflated->header.opcode |
353 << " final=" << inflated->header.final | 353 << " final=" << inflated->header.final |
354 << " reserved1=" << inflated->header.reserved1 | 354 << " reserved1=" << inflated->header.reserved1 |
355 << " payload_length=" << inflated->header.payload_length; | 355 << " payload_length=" << inflated->header.payload_length; |
356 frames_to_output.push_back(inflated.release()); | 356 frames_to_output.push_back(inflated.Pass()); |
357 current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; | 357 current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; |
358 if (is_final) | 358 if (is_final) |
359 break; | 359 break; |
360 } | 360 } |
361 if (frame->header.final) | 361 if (frame->header.final) |
362 reading_state_ = NOT_READING; | 362 reading_state_ = NOT_READING; |
363 } | 363 } |
364 } | 364 } |
365 frames->swap(frames_to_output); | 365 frames->swap(frames_to_output); |
366 return frames->empty() ? ERR_IO_PENDING : OK; | 366 return frames->empty() ? ERR_IO_PENDING : OK; |
(...skipping 18 matching lines...) Expand all Loading... |
385 DCHECK(!frames->empty()); | 385 DCHECK(!frames->empty()); |
386 | 386 |
387 result = Inflate(frames); | 387 result = Inflate(frames); |
388 } | 388 } |
389 if (result < 0) | 389 if (result < 0) |
390 frames->clear(); | 390 frames->clear(); |
391 return result; | 391 return result; |
392 } | 392 } |
393 | 393 |
394 } // namespace net | 394 } // namespace net |
OLD | NEW |