| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 } | 153 } |
| 154 | 154 |
| 155 WebSocketChannel::SendResult MainThreadWebSocketChannel::send(PassOwnPtr<Vector<
char> > data) | 155 WebSocketChannel::SendResult MainThreadWebSocketChannel::send(PassOwnPtr<Vector<
char> > data) |
| 156 { | 156 { |
| 157 WTF_LOG(Network, "MainThreadWebSocketChannel %p send() Sending Vector %p", t
his, data.get()); | 157 WTF_LOG(Network, "MainThreadWebSocketChannel %p send() Sending Vector %p", t
his, data.get()); |
| 158 enqueueVector(WebSocketFrame::OpCodeBinary, data); | 158 enqueueVector(WebSocketFrame::OpCodeBinary, data); |
| 159 processOutgoingFrameQueue(); | 159 processOutgoingFrameQueue(); |
| 160 return WebSocketChannel::SendSuccess; | 160 return WebSocketChannel::SendSuccess; |
| 161 } | 161 } |
| 162 | 162 |
| 163 unsigned long MainThreadWebSocketChannel::bufferedAmount() const | |
| 164 { | |
| 165 WTF_LOG(Network, "MainThreadWebSocketChannel %p bufferedAmount()", this); | |
| 166 ASSERT(m_handle); | |
| 167 ASSERT(!m_suspended); | |
| 168 return m_handle->bufferedAmount(); | |
| 169 } | |
| 170 | |
| 171 void MainThreadWebSocketChannel::close(int code, const String& reason) | 163 void MainThreadWebSocketChannel::close(int code, const String& reason) |
| 172 { | 164 { |
| 173 WTF_LOG(Network, "MainThreadWebSocketChannel %p close() code=%d reason='%s'"
, this, code, reason.utf8().data()); | 165 WTF_LOG(Network, "MainThreadWebSocketChannel %p close() code=%d reason='%s'"
, this, code, reason.utf8().data()); |
| 174 ASSERT(!m_suspended); | 166 ASSERT(!m_suspended); |
| 175 if (!m_handle) | 167 if (!m_handle) |
| 176 return; | 168 return; |
| 177 startClosingHandshake(code, reason); | 169 startClosingHandshake(code, reason); |
| 178 if (!m_closingTimer.isActive()) | 170 if (!m_closingTimer.isActive()) |
| 179 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime, FROM_HERE); | 171 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime, FROM_HERE); |
| 180 } | 172 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 const String message = "WebSocket connection to '" + m_handshake->url().
elidedString() + "' failed: Connection closed before receiving a handshake respo
nse"; | 281 const String message = "WebSocket connection to '" + m_handshake->url().
elidedString() + "' failed: Connection closed before receiving a handshake respo
nse"; |
| 290 m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, messag
e, m_sourceURLAtConstruction, m_lineNumberAtConstruction); | 282 m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, messag
e, m_sourceURLAtConstruction, m_lineNumberAtConstruction); |
| 291 } | 283 } |
| 292 | 284 |
| 293 m_state = ChannelClosed; | 285 m_state = ChannelClosed; |
| 294 if (m_closingTimer.isActive()) | 286 if (m_closingTimer.isActive()) |
| 295 m_closingTimer.stop(); | 287 m_closingTimer.stop(); |
| 296 if (m_outgoingFrameQueueStatus != OutgoingFrameQueueClosed) | 288 if (m_outgoingFrameQueueStatus != OutgoingFrameQueueClosed) |
| 297 abortOutgoingFrameQueue(); | 289 abortOutgoingFrameQueue(); |
| 298 if (m_handle) { | 290 if (m_handle) { |
| 299 m_unhandledBufferedAmount = m_handle->bufferedAmount(); | |
| 300 WebSocketChannelClient* client = m_client; | 291 WebSocketChannelClient* client = m_client; |
| 301 m_client = 0; | 292 m_client = 0; |
| 302 clearDocument(); | 293 clearDocument(); |
| 303 m_handle = nullptr; | 294 m_handle = nullptr; |
| 304 if (client) | 295 if (client) |
| 305 client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandsha
ke ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient::
ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason); | 296 client->didClose(m_receivedClosingHandshake ? WebSocketChannelClient
::ClosingHandshakeComplete : WebSocketChannelClient::ClosingHandshakeIncomplete,
m_closeEventCode, m_closeEventReason); |
| 306 } | 297 } |
| 307 deref(); | 298 deref(); |
| 308 } | 299 } |
| 309 | 300 |
| 310 void MainThreadWebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle*
handle, const char* data, int len) | 301 void MainThreadWebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle*
handle, const char* data, int len) |
| 311 { | 302 { |
| 312 WTF_LOG(Network, "MainThreadWebSocketChannel %p didReceiveSocketStreamData()
Received %d bytes", this, len); | 303 WTF_LOG(Network, "MainThreadWebSocketChannel %p didReceiveSocketStreamData()
Received %d bytes", this, len); |
| 313 RefPtrWillBeRawPtr<MainThreadWebSocketChannel> protect(this); // The client
can close the channel, potentially removing the last reference. | 304 RefPtrWillBeRawPtr<MainThreadWebSocketChannel> protect(this); // The client
can close the channel, potentially removing the last reference. |
| 314 ASSERT(handle == m_handle); | 305 ASSERT(handle == m_handle); |
| 315 if (!m_document) | 306 if (!m_document) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 326 if (m_shouldDiscardReceivedData) | 317 if (m_shouldDiscardReceivedData) |
| 327 return; | 318 return; |
| 328 if (!appendToBuffer(data, len)) { | 319 if (!appendToBuffer(data, len)) { |
| 329 m_shouldDiscardReceivedData = true; | 320 m_shouldDiscardReceivedData = true; |
| 330 failAsError("Ran out of memory while receiving WebSocket data."); | 321 failAsError("Ran out of memory while receiving WebSocket data."); |
| 331 return; | 322 return; |
| 332 } | 323 } |
| 333 processBuffer(); | 324 processBuffer(); |
| 334 } | 325 } |
| 335 | 326 |
| 336 void MainThreadWebSocketChannel::didUpdateBufferedAmount(SocketStreamHandle*, si
ze_t bufferedAmount) | 327 void MainThreadWebSocketChannel::didConsumeBufferedAmount(SocketStreamHandle*, s
ize_t consumed) |
| 337 { | 328 { |
| 338 if (m_client) | 329 if (m_framingOverheadQueue.isEmpty()) { |
| 339 m_client->didUpdateBufferedAmount(bufferedAmount); | 330 // Ignore the handshake consumption. |
| 331 return; |
| 332 } |
| 333 if (!m_client || m_state == ChannelClosed) |
| 334 return; |
| 335 size_t remain = consumed; |
| 336 while (remain > 0) { |
| 337 ASSERT(!m_framingOverheadQueue.isEmpty()); |
| 338 const FramingOverhead& frame = m_framingOverheadQueue.first(); |
| 339 |
| 340 ASSERT(m_numConsumedBytesInCurrentFrame <= frame.frameDataSize()); |
| 341 size_t consumedInThisFrame = std::min(remain, frame.frameDataSize() - m_
numConsumedBytesInCurrentFrame); |
| 342 remain -= consumedInThisFrame; |
| 343 m_numConsumedBytesInCurrentFrame += consumedInThisFrame; |
| 344 |
| 345 if (m_numConsumedBytesInCurrentFrame == frame.frameDataSize()) { |
| 346 if (m_client && WebSocketFrame::isNonControlOpCode(frame.opcode()))
{ |
| 347 // FIXME: As |consumed| is the number of possibly compressed |
| 348 // bytes, we can't determine the number of consumed original |
| 349 // bytes in the middle of a frame. |
| 350 m_client->didConsumeBufferedAmount(frame.originalPayloadLength()
); |
| 351 } |
| 352 m_framingOverheadQueue.takeFirst(); |
| 353 m_numConsumedBytesInCurrentFrame = 0; |
| 354 } |
| 355 } |
| 340 } | 356 } |
| 341 | 357 |
| 342 void MainThreadWebSocketChannel::didFailSocketStream(SocketStreamHandle* handle,
const SocketStreamError& error) | 358 void MainThreadWebSocketChannel::didFailSocketStream(SocketStreamHandle* handle,
const SocketStreamError& error) |
| 343 { | 359 { |
| 344 WTF_LOG(Network, "MainThreadWebSocketChannel %p didFailSocketStream()", this
); | 360 WTF_LOG(Network, "MainThreadWebSocketChannel %p didFailSocketStream()", this
); |
| 345 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); | 361 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); |
| 346 m_shouldDiscardReceivedData = true; | 362 m_shouldDiscardReceivedData = true; |
| 347 String message; | 363 String message; |
| 348 if (error.isNull()) | 364 if (error.isNull()) |
| 349 message = "WebSocket network error"; | 365 message = "WebSocket network error"; |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 return false; | 854 return false; |
| 839 } | 855 } |
| 840 | 856 |
| 841 if (!m_perMessageDeflate.deflate(frame)) { | 857 if (!m_perMessageDeflate.deflate(frame)) { |
| 842 failAsError(m_perMessageDeflate.failureReason()); | 858 failAsError(m_perMessageDeflate.failureReason()); |
| 843 return false; | 859 return false; |
| 844 } | 860 } |
| 845 | 861 |
| 846 Vector<char> frameData; | 862 Vector<char> frameData; |
| 847 frame.makeFrameData(frameData); | 863 frame.makeFrameData(frameData); |
| 864 m_framingOverheadQueue.append(FramingOverhead(opCode, frameData.size(), data
Length)); |
| 848 | 865 |
| 849 m_perMessageDeflate.resetDeflateBuffer(); | 866 m_perMessageDeflate.resetDeflateBuffer(); |
| 850 return m_handle->send(frameData.data(), frameData.size()); | 867 return m_handle->send(frameData.data(), frameData.size()); |
| 851 } | 868 } |
| 852 | 869 |
| 853 } // namespace WebCore | 870 } // namespace WebCore |
| OLD | NEW |