| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 current_reading_opcode_(WebSocketFrameHeader::kOpCodeText), | 46 current_reading_opcode_(WebSocketFrameHeader::kOpCodeText), |
| 47 current_writing_opcode_(WebSocketFrameHeader::kOpCodeText), | 47 current_writing_opcode_(WebSocketFrameHeader::kOpCodeText), |
| 48 predictor_(predictor.Pass()) { | 48 predictor_(predictor.Pass()) { |
| 49 DCHECK(stream_); | 49 DCHECK(stream_); |
| 50 DCHECK_GE(client_window_bits, 8); | 50 DCHECK_GE(client_window_bits, 8); |
| 51 DCHECK_LE(client_window_bits, 15); | 51 DCHECK_LE(client_window_bits, 15); |
| 52 deflater_.Initialize(client_window_bits); | 52 deflater_.Initialize(client_window_bits); |
| 53 inflater_.Initialize(kWindowBits); | 53 inflater_.Initialize(kWindowBits); |
| 54 } | 54 } |
| 55 | 55 |
| 56 WebSocketDeflateStream::~WebSocketDeflateStream() {} | 56 WebSocketDeflateStream::~WebSocketDeflateStream() { |
| 57 } |
| 57 | 58 |
| 58 int WebSocketDeflateStream::ReadFrames(ScopedVector<WebSocketFrame>* frames, | 59 int WebSocketDeflateStream::ReadFrames(ScopedVector<WebSocketFrame>* frames, |
| 59 const CompletionCallback& callback) { | 60 const CompletionCallback& callback) { |
| 60 int result = stream_->ReadFrames( | 61 int result = |
| 61 frames, | 62 stream_->ReadFrames(frames, |
| 62 base::Bind(&WebSocketDeflateStream::OnReadComplete, | 63 base::Bind(&WebSocketDeflateStream::OnReadComplete, |
| 63 base::Unretained(this), | 64 base::Unretained(this), |
| 64 base::Unretained(frames), | 65 base::Unretained(frames), |
| 65 callback)); | 66 callback)); |
| 66 if (result < 0) | 67 if (result < 0) |
| 67 return result; | 68 return result; |
| 68 DCHECK_EQ(OK, result); | 69 DCHECK_EQ(OK, result); |
| 69 DCHECK(!frames->empty()); | 70 DCHECK(!frames->empty()); |
| 70 | 71 |
| 71 return InflateAndReadIfNecessary(frames, callback); | 72 return InflateAndReadIfNecessary(frames, callback); |
| 72 } | 73 } |
| 73 | 74 |
| 74 int WebSocketDeflateStream::WriteFrames(ScopedVector<WebSocketFrame>* frames, | 75 int WebSocketDeflateStream::WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| 75 const CompletionCallback& callback) { | 76 const CompletionCallback& callback) { |
| 76 int result = Deflate(frames); | 77 int result = Deflate(frames); |
| 77 if (result != OK) | 78 if (result != OK) |
| 78 return result; | 79 return result; |
| 79 if (frames->empty()) | 80 if (frames->empty()) |
| 80 return OK; | 81 return OK; |
| 81 return stream_->WriteFrames(frames, callback); | 82 return stream_->WriteFrames(frames, callback); |
| 82 } | 83 } |
| 83 | 84 |
| 84 void WebSocketDeflateStream::Close() { stream_->Close(); } | 85 void WebSocketDeflateStream::Close() { |
| 86 stream_->Close(); |
| 87 } |
| 85 | 88 |
| 86 std::string WebSocketDeflateStream::GetSubProtocol() const { | 89 std::string WebSocketDeflateStream::GetSubProtocol() const { |
| 87 return stream_->GetSubProtocol(); | 90 return stream_->GetSubProtocol(); |
| 88 } | 91 } |
| 89 | 92 |
| 90 std::string WebSocketDeflateStream::GetExtensions() const { | 93 std::string WebSocketDeflateStream::GetExtensions() const { |
| 91 return stream_->GetExtensions(); | 94 return stream_->GetExtensions(); |
| 92 } | 95 } |
| 93 | 96 |
| 94 void WebSocketDeflateStream::OnReadComplete( | 97 void WebSocketDeflateStream::OnReadComplete( |
| (...skipping 30 matching lines...) Expand all Loading... |
| 125 (*frames)[i] = NULL; | 128 (*frames)[i] = NULL; |
| 126 predictor_->RecordInputDataFrame(frame.get()); | 129 predictor_->RecordInputDataFrame(frame.get()); |
| 127 | 130 |
| 128 if (writing_state_ == WRITING_UNCOMPRESSED_MESSAGE) { | 131 if (writing_state_ == WRITING_UNCOMPRESSED_MESSAGE) { |
| 129 if (frame->header.final) | 132 if (frame->header.final) |
| 130 writing_state_ = NOT_WRITING; | 133 writing_state_ = NOT_WRITING; |
| 131 predictor_->RecordWrittenDataFrame(frame.get()); | 134 predictor_->RecordWrittenDataFrame(frame.get()); |
| 132 frames_to_write.push_back(frame.release()); | 135 frames_to_write.push_back(frame.release()); |
| 133 current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; | 136 current_writing_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; |
| 134 } else { | 137 } else { |
| 135 if (frame->data && !deflater_.AddBytes(frame->data->data(), | 138 if (frame->data && |
| 136 frame->header.payload_length)) { | 139 !deflater_.AddBytes(frame->data->data(), |
| 140 frame->header.payload_length)) { |
| 137 DVLOG(1) << "WebSocket protocol error. " | 141 DVLOG(1) << "WebSocket protocol error. " |
| 138 << "deflater_.AddBytes() returns an error."; | 142 << "deflater_.AddBytes() returns an error."; |
| 139 return ERR_WS_PROTOCOL_ERROR; | 143 return ERR_WS_PROTOCOL_ERROR; |
| 140 } | 144 } |
| 141 if (frame->header.final && !deflater_.Finish()) { | 145 if (frame->header.final && !deflater_.Finish()) { |
| 142 DVLOG(1) << "WebSocket protocol error. " | 146 DVLOG(1) << "WebSocket protocol error. " |
| 143 << "deflater_.Finish() returns an error."; | 147 << "deflater_.Finish() returns an error."; |
| 144 return ERR_WS_PROTOCOL_ERROR; | 148 return ERR_WS_PROTOCOL_ERROR; |
| 145 } | 149 } |
| 146 | 150 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 167 } | 171 } |
| 168 } | 172 } |
| 169 } | 173 } |
| 170 } | 174 } |
| 171 DCHECK_NE(WRITING_POSSIBLY_COMPRESSED_MESSAGE, writing_state_); | 175 DCHECK_NE(WRITING_POSSIBLY_COMPRESSED_MESSAGE, writing_state_); |
| 172 frames->swap(frames_to_write); | 176 frames->swap(frames_to_write); |
| 173 return OK; | 177 return OK; |
| 174 } | 178 } |
| 175 | 179 |
| 176 void WebSocketDeflateStream::OnMessageStart( | 180 void WebSocketDeflateStream::OnMessageStart( |
| 177 const ScopedVector<WebSocketFrame>& frames, size_t index) { | 181 const ScopedVector<WebSocketFrame>& frames, |
| 182 size_t index) { |
| 178 WebSocketFrame* frame = frames[index]; | 183 WebSocketFrame* frame = frames[index]; |
| 179 current_writing_opcode_ = frame->header.opcode; | 184 current_writing_opcode_ = frame->header.opcode; |
| 180 DCHECK(current_writing_opcode_ == WebSocketFrameHeader::kOpCodeText || | 185 DCHECK(current_writing_opcode_ == WebSocketFrameHeader::kOpCodeText || |
| 181 current_writing_opcode_ == WebSocketFrameHeader::kOpCodeBinary); | 186 current_writing_opcode_ == WebSocketFrameHeader::kOpCodeBinary); |
| 182 WebSocketDeflatePredictor::Result prediction = | 187 WebSocketDeflatePredictor::Result prediction = |
| 183 predictor_->Predict(frames, index); | 188 predictor_->Predict(frames, index); |
| 184 | 189 |
| 185 switch (prediction) { | 190 switch (prediction) { |
| 186 case WebSocketDeflatePredictor::DEFLATE: | 191 case WebSocketDeflatePredictor::DEFLATE: |
| 187 writing_state_ = WRITING_COMPRESSED_MESSAGE; | 192 writing_state_ = WRITING_COMPRESSED_MESSAGE; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 DVLOG(1) << "WebSocket protocol error. " | 239 DVLOG(1) << "WebSocket protocol error. " |
| 235 << "deflater_.GetOutput() returns an error."; | 240 << "deflater_.GetOutput() returns an error."; |
| 236 return ERR_WS_PROTOCOL_ERROR; | 241 return ERR_WS_PROTOCOL_ERROR; |
| 237 } | 242 } |
| 238 | 243 |
| 239 uint64 original_payload_length = 0; | 244 uint64 original_payload_length = 0; |
| 240 for (size_t i = 0; i < frames->size(); ++i) { | 245 for (size_t i = 0; i < frames->size(); ++i) { |
| 241 WebSocketFrame* frame = (*frames)[i]; | 246 WebSocketFrame* frame = (*frames)[i]; |
| 242 // Asserts checking that frames represent one whole data message. | 247 // Asserts checking that frames represent one whole data message. |
| 243 DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)); | 248 DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)); |
| 244 DCHECK_EQ(i == 0, | 249 DCHECK_EQ( |
| 245 WebSocketFrameHeader::kOpCodeContinuation != | 250 i == 0, |
| 246 frame->header.opcode); | 251 WebSocketFrameHeader::kOpCodeContinuation != frame->header.opcode); |
| 247 DCHECK_EQ(i == frames->size() - 1, frame->header.final); | 252 DCHECK_EQ(i == frames->size() - 1, frame->header.final); |
| 248 original_payload_length += frame->header.payload_length; | 253 original_payload_length += frame->header.payload_length; |
| 249 } | 254 } |
| 250 if (original_payload_length <= | 255 if (original_payload_length <= |
| 251 static_cast<uint64>(compressed_payload->size())) { | 256 static_cast<uint64>(compressed_payload->size())) { |
| 252 // Compression is not effective. Use the original frames. | 257 // Compression is not effective. Use the original frames. |
| 253 for (size_t i = 0; i < frames->size(); ++i) { | 258 for (size_t i = 0; i < frames->size(); ++i) { |
| 254 WebSocketFrame* frame = (*frames)[i]; | 259 WebSocketFrame* frame = (*frames)[i]; |
| 255 frames_to_write->push_back(frame); | 260 frames_to_write->push_back(frame); |
| 256 predictor_->RecordWrittenDataFrame(frame); | 261 predictor_->RecordWrittenDataFrame(frame); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 } | 308 } |
| 304 } | 309 } |
| 305 | 310 |
| 306 if (reading_state_ == READING_UNCOMPRESSED_MESSAGE) { | 311 if (reading_state_ == READING_UNCOMPRESSED_MESSAGE) { |
| 307 if (frame->header.final) | 312 if (frame->header.final) |
| 308 reading_state_ = NOT_READING; | 313 reading_state_ = NOT_READING; |
| 309 current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; | 314 current_reading_opcode_ = WebSocketFrameHeader::kOpCodeContinuation; |
| 310 frames_to_output.push_back(frame.release()); | 315 frames_to_output.push_back(frame.release()); |
| 311 } else { | 316 } else { |
| 312 DCHECK_EQ(reading_state_, READING_COMPRESSED_MESSAGE); | 317 DCHECK_EQ(reading_state_, READING_COMPRESSED_MESSAGE); |
| 313 if (frame->data && !inflater_.AddBytes(frame->data->data(), | 318 if (frame->data && |
| 314 frame->header.payload_length)) { | 319 !inflater_.AddBytes(frame->data->data(), |
| 320 frame->header.payload_length)) { |
| 315 DVLOG(1) << "WebSocket protocol error. " | 321 DVLOG(1) << "WebSocket protocol error. " |
| 316 << "inflater_.AddBytes() returns an error."; | 322 << "inflater_.AddBytes() returns an error."; |
| 317 return ERR_WS_PROTOCOL_ERROR; | 323 return ERR_WS_PROTOCOL_ERROR; |
| 318 } | 324 } |
| 319 if (frame->header.final) { | 325 if (frame->header.final) { |
| 320 if (!inflater_.Finish()) { | 326 if (!inflater_.Finish()) { |
| 321 DVLOG(1) << "WebSocket protocol error. " | 327 DVLOG(1) << "WebSocket protocol error. " |
| 322 << "inflater_.Finish() returns an error."; | 328 << "inflater_.Finish() returns an error."; |
| 323 return ERR_WS_PROTOCOL_ERROR; | 329 return ERR_WS_PROTOCOL_ERROR; |
| 324 } | 330 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 return frames->empty() ? ERR_IO_PENDING : OK; | 368 return frames->empty() ? ERR_IO_PENDING : OK; |
| 363 } | 369 } |
| 364 | 370 |
| 365 int WebSocketDeflateStream::InflateAndReadIfNecessary( | 371 int WebSocketDeflateStream::InflateAndReadIfNecessary( |
| 366 ScopedVector<WebSocketFrame>* frames, | 372 ScopedVector<WebSocketFrame>* frames, |
| 367 const CompletionCallback& callback) { | 373 const CompletionCallback& callback) { |
| 368 int result = Inflate(frames); | 374 int result = Inflate(frames); |
| 369 while (result == ERR_IO_PENDING) { | 375 while (result == ERR_IO_PENDING) { |
| 370 DCHECK(frames->empty()); | 376 DCHECK(frames->empty()); |
| 371 | 377 |
| 372 result = stream_->ReadFrames( | 378 result = |
| 373 frames, | 379 stream_->ReadFrames(frames, |
| 374 base::Bind(&WebSocketDeflateStream::OnReadComplete, | 380 base::Bind(&WebSocketDeflateStream::OnReadComplete, |
| 375 base::Unretained(this), | 381 base::Unretained(this), |
| 376 base::Unretained(frames), | 382 base::Unretained(frames), |
| 377 callback)); | 383 callback)); |
| 378 if (result < 0) | 384 if (result < 0) |
| 379 break; | 385 break; |
| 380 DCHECK_EQ(OK, result); | 386 DCHECK_EQ(OK, result); |
| 381 DCHECK(!frames->empty()); | 387 DCHECK(!frames->empty()); |
| 382 | 388 |
| 383 result = Inflate(frames); | 389 result = Inflate(frames); |
| 384 } | 390 } |
| 385 if (result < 0) | 391 if (result < 0) |
| 386 frames->clear(); | 392 frames->clear(); |
| 387 return result; | 393 return result; |
| 388 } | 394 } |
| 389 | 395 |
| 390 } // namespace net | 396 } // namespace net |
| OLD | NEW |