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