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 |