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 |