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 |