Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 : m_document(document) | 65 : m_document(document) |
| 66 , m_client(client) | 66 , m_client(client) |
| 67 , m_resumeTimer(this, &MainThreadWebSocketChannel::resumeTimerFired) | 67 , m_resumeTimer(this, &MainThreadWebSocketChannel::resumeTimerFired) |
| 68 , m_suspended(false) | 68 , m_suspended(false) |
| 69 , m_didFailOfClientAlreadyRun(false) | 69 , m_didFailOfClientAlreadyRun(false) |
| 70 , m_hasCalledDisconnectOnHandle(false) | 70 , m_hasCalledDisconnectOnHandle(false) |
| 71 , m_receivedClosingHandshake(false) | 71 , m_receivedClosingHandshake(false) |
| 72 , m_closingTimer(this, &MainThreadWebSocketChannel::closingTimerFired) | 72 , m_closingTimer(this, &MainThreadWebSocketChannel::closingTimerFired) |
| 73 , m_state(ChannelIdle) | 73 , m_state(ChannelIdle) |
| 74 , m_shouldDiscardReceivedData(false) | 74 , m_shouldDiscardReceivedData(false) |
| 75 , m_unhandledBufferedAmount(0) | |
| 76 , m_identifier(0) | 75 , m_identifier(0) |
| 77 , m_hasContinuousFrame(false) | 76 , m_hasContinuousFrame(false) |
| 78 , m_closeEventCode(CloseEventCodeAbnormalClosure) | 77 , m_closeEventCode(CloseEventCodeAbnormalClosure) |
| 79 , m_outgoingFrameQueueStatus(OutgoingFrameQueueOpen) | 78 , m_outgoingFrameQueueStatus(OutgoingFrameQueueOpen) |
| 79 , m_numConsumedBytesInCurrentFrame(0) | |
| 80 , m_blobLoaderStatus(BlobLoaderNotStarted) | 80 , m_blobLoaderStatus(BlobLoaderNotStarted) |
| 81 , m_sourceURLAtConstruction(sourceURL) | 81 , m_sourceURLAtConstruction(sourceURL) |
| 82 , m_lineNumberAtConstruction(lineNumber) | 82 , m_lineNumberAtConstruction(lineNumber) |
| 83 { | 83 { |
| 84 if (m_document->page()) | 84 if (m_document->page()) |
| 85 m_identifier = createUniqueIdentifier(); | 85 m_identifier = createUniqueIdentifier(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 MainThreadWebSocketChannel::~MainThreadWebSocketChannel() | 88 MainThreadWebSocketChannel::~MainThreadWebSocketChannel() |
| 89 { | 89 { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 } | 175 } |
| 176 | 176 |
| 177 WebSocketChannel::SendResult MainThreadWebSocketChannel::send(PassOwnPtr<Vector< char> > data) | 177 WebSocketChannel::SendResult MainThreadWebSocketChannel::send(PassOwnPtr<Vector< char> > data) |
| 178 { | 178 { |
| 179 WTF_LOG(Network, "MainThreadWebSocketChannel %p send() Sending Vector %p", t his, data.get()); | 179 WTF_LOG(Network, "MainThreadWebSocketChannel %p send() Sending Vector %p", t his, data.get()); |
| 180 enqueueVector(WebSocketFrame::OpCodeBinary, data); | 180 enqueueVector(WebSocketFrame::OpCodeBinary, data); |
| 181 processOutgoingFrameQueue(); | 181 processOutgoingFrameQueue(); |
| 182 return WebSocketChannel::SendSuccess; | 182 return WebSocketChannel::SendSuccess; |
| 183 } | 183 } |
| 184 | 184 |
| 185 unsigned long MainThreadWebSocketChannel::bufferedAmount() const | |
| 186 { | |
| 187 WTF_LOG(Network, "MainThreadWebSocketChannel %p bufferedAmount()", this); | |
| 188 ASSERT(m_handle); | |
| 189 ASSERT(!m_suspended); | |
| 190 return m_handle->bufferedAmount(); | |
| 191 } | |
| 192 | |
| 193 void MainThreadWebSocketChannel::close(int code, const String& reason) | 185 void MainThreadWebSocketChannel::close(int code, const String& reason) |
| 194 { | 186 { |
| 195 WTF_LOG(Network, "MainThreadWebSocketChannel %p close() code=%d reason='%s'" , this, code, reason.utf8().data()); | 187 WTF_LOG(Network, "MainThreadWebSocketChannel %p close() code=%d reason='%s'" , this, code, reason.utf8().data()); |
| 196 ASSERT(!m_suspended); | 188 ASSERT(!m_suspended); |
| 197 if (!m_handle) | 189 if (!m_handle) |
| 198 return; | 190 return; |
| 199 startClosingHandshake(code, reason); | 191 startClosingHandshake(code, reason); |
| 200 if (!m_closingTimer.isActive()) | 192 if (!m_closingTimer.isActive()) |
| 201 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime, FROM_HERE); | 193 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime, FROM_HERE); |
| 202 } | 194 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 const String message = "WebSocket connection to '" + m_handshake->url(). elidedString() + "' failed: Connection closed before receiving a handshake respo nse"; | 303 const String message = "WebSocket connection to '" + m_handshake->url(). elidedString() + "' failed: Connection closed before receiving a handshake respo nse"; |
| 312 m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, messag e, m_sourceURLAtConstruction, m_lineNumberAtConstruction); | 304 m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, messag e, m_sourceURLAtConstruction, m_lineNumberAtConstruction); |
| 313 } | 305 } |
| 314 | 306 |
| 315 m_state = ChannelClosed; | 307 m_state = ChannelClosed; |
| 316 if (m_closingTimer.isActive()) | 308 if (m_closingTimer.isActive()) |
| 317 m_closingTimer.stop(); | 309 m_closingTimer.stop(); |
| 318 if (m_outgoingFrameQueueStatus != OutgoingFrameQueueClosed) | 310 if (m_outgoingFrameQueueStatus != OutgoingFrameQueueClosed) |
| 319 abortOutgoingFrameQueue(); | 311 abortOutgoingFrameQueue(); |
| 320 if (m_handle) { | 312 if (m_handle) { |
| 321 m_unhandledBufferedAmount = m_handle->bufferedAmount(); | |
| 322 WebSocketChannelClient* client = m_client; | 313 WebSocketChannelClient* client = m_client; |
| 323 m_client = 0; | 314 m_client = 0; |
| 324 clearDocument(); | 315 clearDocument(); |
| 325 m_handle = nullptr; | 316 m_handle = nullptr; |
| 326 if (client) | 317 if (client) |
| 327 client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandsha ke ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient:: ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason); | 318 client->didClose(m_receivedClosingHandshake ? WebSocketChannelClient ::ClosingHandshakeComplete : WebSocketChannelClient::ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason); |
| 328 } | 319 } |
| 329 deref(); | 320 deref(); |
| 330 } | 321 } |
| 331 | 322 |
| 332 void MainThreadWebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle* handle, const char* data, int len) | 323 void MainThreadWebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle* handle, const char* data, int len) |
| 333 { | 324 { |
| 334 WTF_LOG(Network, "MainThreadWebSocketChannel %p didReceiveSocketStreamData() Received %d bytes", this, len); | 325 WTF_LOG(Network, "MainThreadWebSocketChannel %p didReceiveSocketStreamData() Received %d bytes", this, len); |
| 335 RefPtrWillBeRawPtr<MainThreadWebSocketChannel> protect(this); // The client can close the channel, potentially removing the last reference. | 326 RefPtrWillBeRawPtr<MainThreadWebSocketChannel> protect(this); // The client can close the channel, potentially removing the last reference. |
| 336 ASSERT(handle == m_handle); | 327 ASSERT(handle == m_handle); |
| 337 if (!m_document) | 328 if (!m_document) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 348 if (m_shouldDiscardReceivedData) | 339 if (m_shouldDiscardReceivedData) |
| 349 return; | 340 return; |
| 350 if (!appendToBuffer(data, len)) { | 341 if (!appendToBuffer(data, len)) { |
| 351 m_shouldDiscardReceivedData = true; | 342 m_shouldDiscardReceivedData = true; |
| 352 failAsError("Ran out of memory while receiving WebSocket data."); | 343 failAsError("Ran out of memory while receiving WebSocket data."); |
| 353 return; | 344 return; |
| 354 } | 345 } |
| 355 processBuffer(); | 346 processBuffer(); |
| 356 } | 347 } |
| 357 | 348 |
| 358 void MainThreadWebSocketChannel::didUpdateBufferedAmount(SocketStreamHandle*, si ze_t bufferedAmount) | 349 void MainThreadWebSocketChannel::didConsumeBufferedAmount(SocketStreamHandle*, s ize_t consumed) |
| 359 { | 350 { |
| 360 if (m_client) | 351 if (m_framingOverheadQueue.isEmpty()) { |
| 361 m_client->didUpdateBufferedAmount(bufferedAmount); | 352 // Ignore the handshake consumption. |
| 353 return; | |
| 354 } | |
| 355 size_t remain = consumed; | |
| 356 if (!remain || !m_client || m_state == ChannelClosing || m_state == ChannelC losed) | |
|
tyoshino (SeeGerritForStatus)
2014/06/16 02:29:28
[optional] i prefer checking "m_client" and "m_sta
yhirano
2014/06/16 04:44:27
Done.
| |
| 357 return; | |
| 358 while (remain > 0) { | |
| 359 ASSERT(!m_framingOverheadQueue.isEmpty()); | |
| 360 const FramingOverhead& frame = m_framingOverheadQueue.first(); | |
| 361 | |
| 362 ASSERT(m_numConsumedBytesInCurrentFrame <= frame.frameDataSize()); | |
| 363 size_t consumedInThisFrame = std::min(remain, frame.frameDataSize() - m_ numConsumedBytesInCurrentFrame); | |
| 364 remain -= consumedInThisFrame; | |
| 365 m_numConsumedBytesInCurrentFrame += consumedInThisFrame; | |
| 366 | |
| 367 if (m_numConsumedBytesInCurrentFrame == frame.frameDataSize()) { | |
| 368 if (m_client && WebSocketFrame::isNonControlOpCode(frame.opcode())) { | |
| 369 // FIXME: As |consumed| is the number of possibly compressed | |
| 370 // bytes, we can't determine the number of consumed original | |
| 371 // bytes in the middle of a frame. | |
| 372 m_client->didConsumeBufferedAmount(frame.originalPayloadLength() ); | |
| 373 } | |
| 374 m_framingOverheadQueue.takeFirst(); | |
| 375 m_numConsumedBytesInCurrentFrame = 0; | |
| 376 } | |
| 377 } | |
| 362 } | 378 } |
| 363 | 379 |
| 364 void MainThreadWebSocketChannel::didFailSocketStream(SocketStreamHandle* handle, const SocketStreamError& error) | 380 void MainThreadWebSocketChannel::didFailSocketStream(SocketStreamHandle* handle, const SocketStreamError& error) |
| 365 { | 381 { |
| 366 WTF_LOG(Network, "MainThreadWebSocketChannel %p didFailSocketStream()", this ); | 382 WTF_LOG(Network, "MainThreadWebSocketChannel %p didFailSocketStream()", this ); |
| 367 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); | 383 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); |
| 368 m_shouldDiscardReceivedData = true; | 384 m_shouldDiscardReceivedData = true; |
| 369 String message; | 385 String message; |
| 370 if (error.isNull()) | 386 if (error.isNull()) |
| 371 message = "WebSocket network error"; | 387 message = "WebSocket network error"; |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 858 return false; | 874 return false; |
| 859 } | 875 } |
| 860 | 876 |
| 861 if (!m_perMessageDeflate.deflate(frame)) { | 877 if (!m_perMessageDeflate.deflate(frame)) { |
| 862 failAsError(m_perMessageDeflate.failureReason()); | 878 failAsError(m_perMessageDeflate.failureReason()); |
| 863 return false; | 879 return false; |
| 864 } | 880 } |
| 865 | 881 |
| 866 Vector<char> frameData; | 882 Vector<char> frameData; |
| 867 frame.makeFrameData(frameData); | 883 frame.makeFrameData(frameData); |
| 884 m_framingOverheadQueue.append(FramingOverhead(opCode, frameData.size(), data Length)); | |
| 868 | 885 |
| 869 m_perMessageDeflate.resetDeflateBuffer(); | 886 m_perMessageDeflate.resetDeflateBuffer(); |
| 870 return m_handle->send(frameData.data(), frameData.size()); | 887 return m_handle->send(frameData.data(), frameData.size()); |
| 871 } | 888 } |
| 872 | 889 |
| 873 } // namespace WebCore | 890 } // namespace WebCore |
| OLD | NEW |