| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 if (Page* page = m_document->page()) | 93 if (Page* page = m_document->page()) |
| 94 m_identifier = page->progress()->createUniqueIdentifier(); | 94 m_identifier = page->progress()->createUniqueIdentifier(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 WebSocketChannel::~WebSocketChannel() | 97 WebSocketChannel::~WebSocketChannel() |
| 98 { | 98 { |
| 99 } | 99 } |
| 100 | 100 |
| 101 void WebSocketChannel::connect(const KURL& url, const String& protocol) | 101 void WebSocketChannel::connect(const KURL& url, const String& protocol) |
| 102 { | 102 { |
| 103 LOG(Network, "WebSocketChannel %p connect", this); | 103 LOG_INFO(Network, "WebSocketChannel %p connect", this); |
| 104 ASSERT(!m_handle); | 104 ASSERT(!m_handle); |
| 105 ASSERT(!m_suspended); | 105 ASSERT(!m_suspended); |
| 106 m_handshake = adoptPtr(new WebSocketHandshake(url, protocol, m_document)); | 106 m_handshake = adoptPtr(new WebSocketHandshake(url, protocol, m_document)); |
| 107 m_handshake->reset(); | 107 m_handshake->reset(); |
| 108 if (m_deflateFramer.canDeflate()) | 108 if (m_deflateFramer.canDeflate()) |
| 109 m_handshake->addExtensionProcessor(m_deflateFramer.createExtensionProces
sor()); | 109 m_handshake->addExtensionProcessor(m_deflateFramer.createExtensionProces
sor()); |
| 110 if (m_identifier) | 110 if (m_identifier) |
| 111 InspectorInstrumentation::didCreateWebSocket(m_document, m_identifier, u
rl, m_document->url(), protocol); | 111 InspectorInstrumentation::didCreateWebSocket(m_document, m_identifier, u
rl, m_document->url(), protocol); |
| 112 ref(); | 112 ref(); |
| 113 m_handle = SocketStreamHandle::create(m_handshake->url(), this); | 113 m_handle = SocketStreamHandle::create(m_handshake->url(), this); |
| 114 } | 114 } |
| 115 | 115 |
| 116 String WebSocketChannel::subprotocol() | 116 String WebSocketChannel::subprotocol() |
| 117 { | 117 { |
| 118 LOG(Network, "WebSocketChannel %p subprotocol", this); | 118 LOG_INFO(Network, "WebSocketChannel %p subprotocol", this); |
| 119 if (!m_handshake || m_handshake->mode() != WebSocketHandshake::Connected) | 119 if (!m_handshake || m_handshake->mode() != WebSocketHandshake::Connected) |
| 120 return ""; | 120 return ""; |
| 121 String serverProtocol = m_handshake->serverWebSocketProtocol(); | 121 String serverProtocol = m_handshake->serverWebSocketProtocol(); |
| 122 if (serverProtocol.isNull()) | 122 if (serverProtocol.isNull()) |
| 123 return ""; | 123 return ""; |
| 124 return serverProtocol; | 124 return serverProtocol; |
| 125 } | 125 } |
| 126 | 126 |
| 127 String WebSocketChannel::extensions() | 127 String WebSocketChannel::extensions() |
| 128 { | 128 { |
| 129 LOG(Network, "WebSocketChannel %p extensions", this); | 129 LOG_INFO(Network, "WebSocketChannel %p extensions", this); |
| 130 if (!m_handshake || m_handshake->mode() != WebSocketHandshake::Connected) | 130 if (!m_handshake || m_handshake->mode() != WebSocketHandshake::Connected) |
| 131 return ""; | 131 return ""; |
| 132 String extensions = m_handshake->acceptedExtensions(); | 132 String extensions = m_handshake->acceptedExtensions(); |
| 133 if (extensions.isNull()) | 133 if (extensions.isNull()) |
| 134 return ""; | 134 return ""; |
| 135 return extensions; | 135 return extensions; |
| 136 } | 136 } |
| 137 | 137 |
| 138 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const String& mess
age) | 138 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const String& mess
age) |
| 139 { | 139 { |
| 140 LOG(Network, "WebSocketChannel %p send %s", this, message.utf8().data()); | 140 LOG_INFO(Network, "WebSocketChannel %p send %s", this, message.utf8().data()
); |
| 141 CString utf8 = message.utf8(String::StrictConversionReplacingUnpairedSurroga
tesWithFFFD); | 141 CString utf8 = message.utf8(String::StrictConversionReplacingUnpairedSurroga
tesWithFFFD); |
| 142 enqueueTextFrame(utf8); | 142 enqueueTextFrame(utf8); |
| 143 // According to WebSocket API specification, WebSocket.send() should return
void instead | 143 // According to WebSocket API specification, WebSocket.send() should return
void instead |
| 144 // of boolean. However, our implementation still returns boolean due to comp
atibility | 144 // of boolean. However, our implementation still returns boolean due to comp
atibility |
| 145 // concern (see bug 65850). | 145 // concern (see bug 65850). |
| 146 // m_channel->send() may happen later, thus it's not always possible to know
whether | 146 // m_channel->send() may happen later, thus it's not always possible to know
whether |
| 147 // the message has been sent to the socket successfully. In this case, we ha
ve no choice | 147 // the message has been sent to the socket successfully. In this case, we ha
ve no choice |
| 148 // but to return true. | 148 // but to return true. |
| 149 return ThreadableWebSocketChannel::SendSuccess; | 149 return ThreadableWebSocketChannel::SendSuccess; |
| 150 } | 150 } |
| 151 | 151 |
| 152 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const ArrayBuffer&
binaryData, unsigned byteOffset, unsigned byteLength) | 152 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const ArrayBuffer&
binaryData, unsigned byteOffset, unsigned byteLength) |
| 153 { | 153 { |
| 154 LOG(Network, "WebSocketChannel %p send arraybuffer %p %u %u", this, &binaryD
ata, byteOffset, byteLength); | 154 LOG_INFO(Network, "WebSocketChannel %p send arraybuffer %p %u %u", this, &bi
naryData, byteOffset, byteLength); |
| 155 enqueueRawFrame(WebSocketFrame::OpCodeBinary, static_cast<const char*>(binar
yData.data()) + byteOffset, byteLength); | 155 enqueueRawFrame(WebSocketFrame::OpCodeBinary, static_cast<const char*>(binar
yData.data()) + byteOffset, byteLength); |
| 156 return ThreadableWebSocketChannel::SendSuccess; | 156 return ThreadableWebSocketChannel::SendSuccess; |
| 157 } | 157 } |
| 158 | 158 |
| 159 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const Blob& binary
Data) | 159 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const Blob& binary
Data) |
| 160 { | 160 { |
| 161 LOG(Network, "WebSocketChannel %p send blob %s", this, binaryData.url().elid
edString().utf8().data()); | 161 LOG_INFO(Network, "WebSocketChannel %p send blob %s", this, binaryData.url()
.elidedString().utf8().data()); |
| 162 enqueueBlobFrame(WebSocketFrame::OpCodeBinary, binaryData); | 162 enqueueBlobFrame(WebSocketFrame::OpCodeBinary, binaryData); |
| 163 return ThreadableWebSocketChannel::SendSuccess; | 163 return ThreadableWebSocketChannel::SendSuccess; |
| 164 } | 164 } |
| 165 | 165 |
| 166 bool WebSocketChannel::send(const char* data, int length) | 166 bool WebSocketChannel::send(const char* data, int length) |
| 167 { | 167 { |
| 168 LOG(Network, "WebSocketChannel %p send binary %p (%dB)", this, data, length)
; | 168 LOG_INFO(Network, "WebSocketChannel %p send binary %p (%dB)", this, data, le
ngth); |
| 169 enqueueRawFrame(WebSocketFrame::OpCodeBinary, data, length); | 169 enqueueRawFrame(WebSocketFrame::OpCodeBinary, data, length); |
| 170 return true; | 170 return true; |
| 171 } | 171 } |
| 172 | 172 |
| 173 unsigned long WebSocketChannel::bufferedAmount() const | 173 unsigned long WebSocketChannel::bufferedAmount() const |
| 174 { | 174 { |
| 175 LOG(Network, "WebSocketChannel %p bufferedAmount", this); | 175 LOG_INFO(Network, "WebSocketChannel %p bufferedAmount", this); |
| 176 ASSERT(m_handle); | 176 ASSERT(m_handle); |
| 177 ASSERT(!m_suspended); | 177 ASSERT(!m_suspended); |
| 178 return m_handle->bufferedAmount(); | 178 return m_handle->bufferedAmount(); |
| 179 } | 179 } |
| 180 | 180 |
| 181 void WebSocketChannel::close(int code, const String& reason) | 181 void WebSocketChannel::close(int code, const String& reason) |
| 182 { | 182 { |
| 183 LOG(Network, "WebSocketChannel %p close", this); | 183 LOG_INFO(Network, "WebSocketChannel %p close", this); |
| 184 ASSERT(!m_suspended); | 184 ASSERT(!m_suspended); |
| 185 if (!m_handle) | 185 if (!m_handle) |
| 186 return; | 186 return; |
| 187 startClosingHandshake(code, reason); | 187 startClosingHandshake(code, reason); |
| 188 if (m_closing && !m_closingTimer.isActive()) | 188 if (m_closing && !m_closingTimer.isActive()) |
| 189 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime); | 189 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime); |
| 190 } | 190 } |
| 191 | 191 |
| 192 void WebSocketChannel::fail(const String& reason) | 192 void WebSocketChannel::fail(const String& reason) |
| 193 { | 193 { |
| 194 LOG(Network, "WebSocketChannel %p fail: %s", this, reason.utf8().data()); | 194 LOG_INFO(Network, "WebSocketChannel %p fail: %s", this, reason.utf8().data()
); |
| 195 ASSERT(!m_suspended); | 195 ASSERT(!m_suspended); |
| 196 if (m_document) { | 196 if (m_document) { |
| 197 InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_id
entifier, reason); | 197 InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_id
entifier, reason); |
| 198 m_document->addConsoleMessage(NetworkMessageSource, ErrorMessageLevel, "
WebSocket connection to '" + m_handshake->url().elidedString() + "' failed: " +
reason); | 198 m_document->addConsoleMessage(NetworkMessageSource, ErrorMessageLevel, "
WebSocket connection to '" + m_handshake->url().elidedString() + "' failed: " +
reason); |
| 199 } | 199 } |
| 200 | 200 |
| 201 // Hybi-10 specification explicitly states we must not continue to handle in
coming data | 201 // Hybi-10 specification explicitly states we must not continue to handle in
coming data |
| 202 // once the WebSocket connection is failed (section 7.1.7). | 202 // once the WebSocket connection is failed (section 7.1.7). |
| 203 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. | 203 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. |
| 204 m_shouldDiscardReceivedData = true; | 204 m_shouldDiscardReceivedData = true; |
| 205 if (!m_buffer.isEmpty()) | 205 if (!m_buffer.isEmpty()) |
| 206 skipBuffer(m_buffer.size()); // Save memory. | 206 skipBuffer(m_buffer.size()); // Save memory. |
| 207 m_deflateFramer.didFail(); | 207 m_deflateFramer.didFail(); |
| 208 m_hasContinuousFrame = false; | 208 m_hasContinuousFrame = false; |
| 209 m_continuousFrameData.clear(); | 209 m_continuousFrameData.clear(); |
| 210 m_client->didReceiveMessageError(); | 210 m_client->didReceiveMessageError(); |
| 211 | 211 |
| 212 if (m_handle && !m_closed) | 212 if (m_handle && !m_closed) |
| 213 m_handle->disconnect(); // Will call didClose(). | 213 m_handle->disconnect(); // Will call didClose(). |
| 214 } | 214 } |
| 215 | 215 |
| 216 void WebSocketChannel::disconnect() | 216 void WebSocketChannel::disconnect() |
| 217 { | 217 { |
| 218 LOG(Network, "WebSocketChannel %p disconnect", this); | 218 LOG_INFO(Network, "WebSocketChannel %p disconnect", this); |
| 219 if (m_identifier && m_document) | 219 if (m_identifier && m_document) |
| 220 InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier); | 220 InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier); |
| 221 if (m_handshake) | 221 if (m_handshake) |
| 222 m_handshake->clearScriptExecutionContext(); | 222 m_handshake->clearScriptExecutionContext(); |
| 223 m_client = 0; | 223 m_client = 0; |
| 224 m_document = 0; | 224 m_document = 0; |
| 225 if (m_handle) | 225 if (m_handle) |
| 226 m_handle->disconnect(); | 226 m_handle->disconnect(); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void WebSocketChannel::suspend() | 229 void WebSocketChannel::suspend() |
| 230 { | 230 { |
| 231 m_suspended = true; | 231 m_suspended = true; |
| 232 } | 232 } |
| 233 | 233 |
| 234 void WebSocketChannel::resume() | 234 void WebSocketChannel::resume() |
| 235 { | 235 { |
| 236 m_suspended = false; | 236 m_suspended = false; |
| 237 if ((!m_buffer.isEmpty() || m_closed) && m_client && !m_resumeTimer.isActive
()) | 237 if ((!m_buffer.isEmpty() || m_closed) && m_client && !m_resumeTimer.isActive
()) |
| 238 m_resumeTimer.startOneShot(0); | 238 m_resumeTimer.startOneShot(0); |
| 239 } | 239 } |
| 240 | 240 |
| 241 void WebSocketChannel::willOpenSocketStream(SocketStreamHandle* handle) | 241 void WebSocketChannel::willOpenSocketStream(SocketStreamHandle* handle) |
| 242 { | 242 { |
| 243 LOG(Network, "WebSocketChannel %p willOpensocketStream", this); | 243 LOG_INFO(Network, "WebSocketChannel %p willOpensocketStream", this); |
| 244 ASSERT(handle); | 244 ASSERT(handle); |
| 245 if (m_document->frame()) | 245 if (m_document->frame()) |
| 246 m_document->frame()->loader()->client()->dispatchWillOpenSocketStream(ha
ndle); | 246 m_document->frame()->loader()->client()->dispatchWillOpenSocketStream(ha
ndle); |
| 247 } | 247 } |
| 248 | 248 |
| 249 void WebSocketChannel::didOpenSocketStream(SocketStreamHandle* handle) | 249 void WebSocketChannel::didOpenSocketStream(SocketStreamHandle* handle) |
| 250 { | 250 { |
| 251 LOG(Network, "WebSocketChannel %p didOpenSocketStream", this); | 251 LOG_INFO(Network, "WebSocketChannel %p didOpenSocketStream", this); |
| 252 ASSERT(handle == m_handle); | 252 ASSERT(handle == m_handle); |
| 253 if (!m_document) | 253 if (!m_document) |
| 254 return; | 254 return; |
| 255 if (m_identifier) | 255 if (m_identifier) |
| 256 InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document,
m_identifier, *m_handshake->clientHandshakeRequest()); | 256 InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document,
m_identifier, *m_handshake->clientHandshakeRequest()); |
| 257 CString handshakeMessage = m_handshake->clientHandshakeMessage(); | 257 CString handshakeMessage = m_handshake->clientHandshakeMessage(); |
| 258 if (!handle->send(handshakeMessage.data(), handshakeMessage.length())) | 258 if (!handle->send(handshakeMessage.data(), handshakeMessage.length())) |
| 259 fail("Failed to send WebSocket handshake."); | 259 fail("Failed to send WebSocket handshake."); |
| 260 } | 260 } |
| 261 | 261 |
| 262 void WebSocketChannel::didCloseSocketStream(SocketStreamHandle* handle) | 262 void WebSocketChannel::didCloseSocketStream(SocketStreamHandle* handle) |
| 263 { | 263 { |
| 264 LOG(Network, "WebSocketChannel %p didCloseSocketStream", this); | 264 LOG_INFO(Network, "WebSocketChannel %p didCloseSocketStream", this); |
| 265 if (m_identifier && m_document) | 265 if (m_identifier && m_document) |
| 266 InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier); | 266 InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier); |
| 267 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); | 267 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); |
| 268 m_closed = true; | 268 m_closed = true; |
| 269 if (m_closingTimer.isActive()) | 269 if (m_closingTimer.isActive()) |
| 270 m_closingTimer.stop(); | 270 m_closingTimer.stop(); |
| 271 if (m_outgoingFrameQueueStatus != OutgoingFrameQueueClosed) | 271 if (m_outgoingFrameQueueStatus != OutgoingFrameQueueClosed) |
| 272 abortOutgoingFrameQueue(); | 272 abortOutgoingFrameQueue(); |
| 273 if (m_handle) { | 273 if (m_handle) { |
| 274 m_unhandledBufferedAmount = m_handle->bufferedAmount(); | 274 m_unhandledBufferedAmount = m_handle->bufferedAmount(); |
| 275 if (m_suspended) | 275 if (m_suspended) |
| 276 return; | 276 return; |
| 277 WebSocketChannelClient* client = m_client; | 277 WebSocketChannelClient* client = m_client; |
| 278 m_client = 0; | 278 m_client = 0; |
| 279 m_document = 0; | 279 m_document = 0; |
| 280 m_handle = 0; | 280 m_handle = 0; |
| 281 if (client) | 281 if (client) |
| 282 client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandsha
ke ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient::
ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason); | 282 client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandsha
ke ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient::
ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason); |
| 283 } | 283 } |
| 284 deref(); | 284 deref(); |
| 285 } | 285 } |
| 286 | 286 |
| 287 void WebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle* handle, co
nst char* data, int len) | 287 void WebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle* handle, co
nst char* data, int len) |
| 288 { | 288 { |
| 289 LOG(Network, "WebSocketChannel %p didReceiveSocketStreamData %d", this, len)
; | 289 LOG_INFO(Network, "WebSocketChannel %p didReceiveSocketStreamData %d", this,
len); |
| 290 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. | 290 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. |
| 291 ASSERT(handle == m_handle); | 291 ASSERT(handle == m_handle); |
| 292 if (!m_document) { | 292 if (!m_document) { |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 if (len <= 0) { | 295 if (len <= 0) { |
| 296 handle->disconnect(); | 296 handle->disconnect(); |
| 297 return; | 297 return; |
| 298 } | 298 } |
| 299 if (!m_client) { | 299 if (!m_client) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 314 } | 314 } |
| 315 | 315 |
| 316 void WebSocketChannel::didUpdateBufferedAmount(SocketStreamHandle*, size_t buffe
redAmount) | 316 void WebSocketChannel::didUpdateBufferedAmount(SocketStreamHandle*, size_t buffe
redAmount) |
| 317 { | 317 { |
| 318 if (m_client) | 318 if (m_client) |
| 319 m_client->didUpdateBufferedAmount(bufferedAmount); | 319 m_client->didUpdateBufferedAmount(bufferedAmount); |
| 320 } | 320 } |
| 321 | 321 |
| 322 void WebSocketChannel::didFailSocketStream(SocketStreamHandle* handle, const Soc
ketStreamError& error) | 322 void WebSocketChannel::didFailSocketStream(SocketStreamHandle* handle, const Soc
ketStreamError& error) |
| 323 { | 323 { |
| 324 LOG(Network, "WebSocketChannel %p didFailSocketStream", this); | 324 LOG_INFO(Network, "WebSocketChannel %p didFailSocketStream", this); |
| 325 ASSERT(handle == m_handle || !m_handle); | 325 ASSERT(handle == m_handle || !m_handle); |
| 326 if (m_document) { | 326 if (m_document) { |
| 327 String message; | 327 String message; |
| 328 if (error.isNull()) | 328 if (error.isNull()) |
| 329 message = "WebSocket network error"; | 329 message = "WebSocket network error"; |
| 330 else if (error.localizedDescription().isNull()) | 330 else if (error.localizedDescription().isNull()) |
| 331 message = "WebSocket network error: error code " + String::number(er
ror.errorCode()); | 331 message = "WebSocket network error: error code " + String::number(er
ror.errorCode()); |
| 332 else | 332 else |
| 333 message = "WebSocket network error: " + error.localizedDescription()
; | 333 message = "WebSocket network error: " + error.localizedDescription()
; |
| 334 InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_id
entifier, message); | 334 InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_id
entifier, message); |
| 335 m_document->addConsoleMessage(NetworkMessageSource, ErrorMessageLevel, m
essage); | 335 m_document->addConsoleMessage(NetworkMessageSource, ErrorMessageLevel, m
essage); |
| 336 } | 336 } |
| 337 m_shouldDiscardReceivedData = true; | 337 m_shouldDiscardReceivedData = true; |
| 338 handle->disconnect(); | 338 handle->disconnect(); |
| 339 } | 339 } |
| 340 | 340 |
| 341 void WebSocketChannel::didReceiveAuthenticationChallenge(SocketStreamHandle*, co
nst AuthenticationChallenge&) | 341 void WebSocketChannel::didReceiveAuthenticationChallenge(SocketStreamHandle*, co
nst AuthenticationChallenge&) |
| 342 { | 342 { |
| 343 } | 343 } |
| 344 | 344 |
| 345 void WebSocketChannel::didCancelAuthenticationChallenge(SocketStreamHandle*, con
st AuthenticationChallenge&) | 345 void WebSocketChannel::didCancelAuthenticationChallenge(SocketStreamHandle*, con
st AuthenticationChallenge&) |
| 346 { | 346 { |
| 347 } | 347 } |
| 348 | 348 |
| 349 #if ENABLE(BLOB) | 349 #if ENABLE(BLOB) |
| 350 void WebSocketChannel::didStartLoading() | 350 void WebSocketChannel::didStartLoading() |
| 351 { | 351 { |
| 352 LOG(Network, "WebSocketChannel %p didStartLoading", this); | 352 LOG_INFO(Network, "WebSocketChannel %p didStartLoading", this); |
| 353 ASSERT(m_blobLoader); | 353 ASSERT(m_blobLoader); |
| 354 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); | 354 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); |
| 355 } | 355 } |
| 356 | 356 |
| 357 void WebSocketChannel::didReceiveData() | 357 void WebSocketChannel::didReceiveData() |
| 358 { | 358 { |
| 359 LOG(Network, "WebSocketChannel %p didReceiveData", this); | 359 LOG_INFO(Network, "WebSocketChannel %p didReceiveData", this); |
| 360 ASSERT(m_blobLoader); | 360 ASSERT(m_blobLoader); |
| 361 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); | 361 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); |
| 362 } | 362 } |
| 363 | 363 |
| 364 void WebSocketChannel::didFinishLoading() | 364 void WebSocketChannel::didFinishLoading() |
| 365 { | 365 { |
| 366 LOG(Network, "WebSocketChannel %p didFinishLoading", this); | 366 LOG_INFO(Network, "WebSocketChannel %p didFinishLoading", this); |
| 367 ASSERT(m_blobLoader); | 367 ASSERT(m_blobLoader); |
| 368 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); | 368 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); |
| 369 m_blobLoaderStatus = BlobLoaderFinished; | 369 m_blobLoaderStatus = BlobLoaderFinished; |
| 370 processOutgoingFrameQueue(); | 370 processOutgoingFrameQueue(); |
| 371 deref(); | 371 deref(); |
| 372 } | 372 } |
| 373 | 373 |
| 374 void WebSocketChannel::didFail(int errorCode) | 374 void WebSocketChannel::didFail(int errorCode) |
| 375 { | 375 { |
| 376 LOG(Network, "WebSocketChannel %p didFail %d", this, errorCode); | 376 LOG_INFO(Network, "WebSocketChannel %p didFail %d", this, errorCode); |
| 377 ASSERT(m_blobLoader); | 377 ASSERT(m_blobLoader); |
| 378 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); | 378 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); |
| 379 m_blobLoader.clear(); | 379 m_blobLoader.clear(); |
| 380 m_blobLoaderStatus = BlobLoaderFailed; | 380 m_blobLoaderStatus = BlobLoaderFailed; |
| 381 fail("Failed to load Blob: error code = " + String::number(errorCode)); // F
IXME: Generate human-friendly reason message. | 381 fail("Failed to load Blob: error code = " + String::number(errorCode)); // F
IXME: Generate human-friendly reason message. |
| 382 deref(); | 382 deref(); |
| 383 } | 383 } |
| 384 #endif | 384 #endif |
| 385 | 385 |
| 386 bool WebSocketChannel::appendToBuffer(const char* data, size_t len) | 386 bool WebSocketChannel::appendToBuffer(const char* data, size_t len) |
| 387 { | 387 { |
| 388 size_t newBufferSize = m_buffer.size() + len; | 388 size_t newBufferSize = m_buffer.size() + len; |
| 389 if (newBufferSize < m_buffer.size()) { | 389 if (newBufferSize < m_buffer.size()) { |
| 390 LOG(Network, "WebSocket buffer overflow (%lu+%lu)", static_cast<unsigned
long>(m_buffer.size()), static_cast<unsigned long>(len)); | 390 LOG_INFO(Network, "WebSocket buffer overflow (%lu+%lu)", static_cast<uns
igned long>(m_buffer.size()), static_cast<unsigned long>(len)); |
| 391 return false; | 391 return false; |
| 392 } | 392 } |
| 393 m_buffer.append(data, len); | 393 m_buffer.append(data, len); |
| 394 return true; | 394 return true; |
| 395 } | 395 } |
| 396 | 396 |
| 397 void WebSocketChannel::skipBuffer(size_t len) | 397 void WebSocketChannel::skipBuffer(size_t len) |
| 398 { | 398 { |
| 399 ASSERT_WITH_SECURITY_IMPLICATION(len <= m_buffer.size()); | 399 ASSERT_WITH_SECURITY_IMPLICATION(len <= m_buffer.size()); |
| 400 memmove(m_buffer.data(), m_buffer.data() + len, m_buffer.size() - len); | 400 memmove(m_buffer.data(), m_buffer.data() + len, m_buffer.size() - len); |
| 401 m_buffer.resize(m_buffer.size() - len); | 401 m_buffer.resize(m_buffer.size() - len); |
| 402 } | 402 } |
| 403 | 403 |
| 404 bool WebSocketChannel::processBuffer() | 404 bool WebSocketChannel::processBuffer() |
| 405 { | 405 { |
| 406 ASSERT(!m_suspended); | 406 ASSERT(!m_suspended); |
| 407 ASSERT(m_client); | 407 ASSERT(m_client); |
| 408 ASSERT(!m_buffer.isEmpty()); | 408 ASSERT(!m_buffer.isEmpty()); |
| 409 LOG(Network, "WebSocketChannel %p processBuffer %lu", this, static_cast<unsi
gned long>(m_buffer.size())); | 409 LOG_INFO(Network, "WebSocketChannel %p processBuffer %lu", this, static_cast
<unsigned long>(m_buffer.size())); |
| 410 | 410 |
| 411 if (m_shouldDiscardReceivedData) | 411 if (m_shouldDiscardReceivedData) |
| 412 return false; | 412 return false; |
| 413 | 413 |
| 414 if (m_receivedClosingHandshake) { | 414 if (m_receivedClosingHandshake) { |
| 415 skipBuffer(m_buffer.size()); | 415 skipBuffer(m_buffer.size()); |
| 416 return false; | 416 return false; |
| 417 } | 417 } |
| 418 | 418 |
| 419 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. | 419 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. |
| 420 | 420 |
| 421 if (m_handshake->mode() == WebSocketHandshake::Incomplete) { | 421 if (m_handshake->mode() == WebSocketHandshake::Incomplete) { |
| 422 int headerLength = m_handshake->readServerHandshake(m_buffer.data(), m_b
uffer.size()); | 422 int headerLength = m_handshake->readServerHandshake(m_buffer.data(), m_b
uffer.size()); |
| 423 if (headerLength <= 0) | 423 if (headerLength <= 0) |
| 424 return false; | 424 return false; |
| 425 if (m_handshake->mode() == WebSocketHandshake::Connected) { | 425 if (m_handshake->mode() == WebSocketHandshake::Connected) { |
| 426 if (m_identifier) | 426 if (m_identifier) |
| 427 InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(m
_document, m_identifier, m_handshake->serverHandshakeResponse()); | 427 InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(m
_document, m_identifier, m_handshake->serverHandshakeResponse()); |
| 428 if (!m_handshake->serverSetCookie().isEmpty()) { | 428 if (!m_handshake->serverSetCookie().isEmpty()) { |
| 429 if (cookiesEnabled(m_document)) { | 429 if (cookiesEnabled(m_document)) { |
| 430 // Exception (for sandboxed documents) ignored. | 430 // Exception (for sandboxed documents) ignored. |
| 431 m_document->setCookie(m_handshake->serverSetCookie(), IGNORE
_EXCEPTION); | 431 m_document->setCookie(m_handshake->serverSetCookie(), IGNORE
_EXCEPTION); |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 // FIXME: handle set-cookie2. | 434 // FIXME: handle set-cookie2. |
| 435 LOG(Network, "WebSocketChannel %p connected", this); | 435 LOG_INFO(Network, "WebSocketChannel %p connected", this); |
| 436 skipBuffer(headerLength); | 436 skipBuffer(headerLength); |
| 437 m_client->didConnect(); | 437 m_client->didConnect(); |
| 438 LOG(Network, "remaining in read buf %lu", static_cast<unsigned long>
(m_buffer.size())); | 438 LOG_INFO(Network, "remaining in read buf %lu", static_cast<unsigned
long>(m_buffer.size())); |
| 439 return !m_buffer.isEmpty(); | 439 return !m_buffer.isEmpty(); |
| 440 } | 440 } |
| 441 ASSERT(m_handshake->mode() == WebSocketHandshake::Failed); | 441 ASSERT(m_handshake->mode() == WebSocketHandshake::Failed); |
| 442 LOG(Network, "WebSocketChannel %p connection failed", this); | 442 LOG_INFO(Network, "WebSocketChannel %p connection failed", this); |
| 443 skipBuffer(headerLength); | 443 skipBuffer(headerLength); |
| 444 m_shouldDiscardReceivedData = true; | 444 m_shouldDiscardReceivedData = true; |
| 445 fail(m_handshake->failureReason()); | 445 fail(m_handshake->failureReason()); |
| 446 return false; | 446 return false; |
| 447 } | 447 } |
| 448 if (m_handshake->mode() != WebSocketHandshake::Connected) | 448 if (m_handshake->mode() != WebSocketHandshake::Connected) |
| 449 return false; | 449 return false; |
| 450 | 450 |
| 451 return processFrame(); | 451 return processFrame(); |
| 452 } | 452 } |
| 453 | 453 |
| 454 void WebSocketChannel::resumeTimerFired(Timer<WebSocketChannel>* timer) | 454 void WebSocketChannel::resumeTimerFired(Timer<WebSocketChannel>* timer) |
| 455 { | 455 { |
| 456 ASSERT_UNUSED(timer, timer == &m_resumeTimer); | 456 ASSERT_UNUSED(timer, timer == &m_resumeTimer); |
| 457 | 457 |
| 458 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. | 458 RefPtr<WebSocketChannel> protect(this); // The client can close the channel,
potentially removing the last reference. |
| 459 while (!m_suspended && m_client && !m_buffer.isEmpty()) | 459 while (!m_suspended && m_client && !m_buffer.isEmpty()) |
| 460 if (!processBuffer()) | 460 if (!processBuffer()) |
| 461 break; | 461 break; |
| 462 if (!m_suspended && m_client && m_closed && m_handle) | 462 if (!m_suspended && m_client && m_closed && m_handle) |
| 463 didCloseSocketStream(m_handle.get()); | 463 didCloseSocketStream(m_handle.get()); |
| 464 } | 464 } |
| 465 | 465 |
| 466 void WebSocketChannel::startClosingHandshake(int code, const String& reason) | 466 void WebSocketChannel::startClosingHandshake(int code, const String& reason) |
| 467 { | 467 { |
| 468 LOG(Network, "WebSocketChannel %p closing %d %d", this, m_closing, m_receive
dClosingHandshake); | 468 LOG_INFO(Network, "WebSocketChannel %p closing %d %d", this, m_closing, m_re
ceivedClosingHandshake); |
| 469 if (m_closing) | 469 if (m_closing) |
| 470 return; | 470 return; |
| 471 ASSERT(m_handle); | 471 ASSERT(m_handle); |
| 472 | 472 |
| 473 Vector<char> buf; | 473 Vector<char> buf; |
| 474 if (!m_receivedClosingHandshake && code != CloseEventCodeNotSpecified) { | 474 if (!m_receivedClosingHandshake && code != CloseEventCodeNotSpecified) { |
| 475 unsigned char highByte = code >> 8; | 475 unsigned char highByte = code >> 8; |
| 476 unsigned char lowByte = code; | 476 unsigned char lowByte = code; |
| 477 buf.append(static_cast<char>(highByte)); | 477 buf.append(static_cast<char>(highByte)); |
| 478 buf.append(static_cast<char>(lowByte)); | 478 buf.append(static_cast<char>(lowByte)); |
| 479 buf.append(reason.utf8().data(), reason.utf8().length()); | 479 buf.append(reason.utf8().data(), reason.utf8().length()); |
| 480 } | 480 } |
| 481 enqueueRawFrame(WebSocketFrame::OpCodeClose, buf.data(), buf.size()); | 481 enqueueRawFrame(WebSocketFrame::OpCodeClose, buf.data(), buf.size()); |
| 482 | 482 |
| 483 m_closing = true; | 483 m_closing = true; |
| 484 if (m_client) | 484 if (m_client) |
| 485 m_client->didStartClosingHandshake(); | 485 m_client->didStartClosingHandshake(); |
| 486 } | 486 } |
| 487 | 487 |
| 488 void WebSocketChannel::closingTimerFired(Timer<WebSocketChannel>* timer) | 488 void WebSocketChannel::closingTimerFired(Timer<WebSocketChannel>* timer) |
| 489 { | 489 { |
| 490 LOG(Network, "WebSocketChannel %p closing timer", this); | 490 LOG_INFO(Network, "WebSocketChannel %p closing timer", this); |
| 491 ASSERT_UNUSED(timer, &m_closingTimer == timer); | 491 ASSERT_UNUSED(timer, &m_closingTimer == timer); |
| 492 if (m_handle) | 492 if (m_handle) |
| 493 m_handle->disconnect(); | 493 m_handle->disconnect(); |
| 494 } | 494 } |
| 495 | 495 |
| 496 | 496 |
| 497 bool WebSocketChannel::processFrame() | 497 bool WebSocketChannel::processFrame() |
| 498 { | 498 { |
| 499 ASSERT(!m_buffer.isEmpty()); | 499 ASSERT(!m_buffer.isEmpty()); |
| 500 | 500 |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 | 802 |
| 803 Vector<char> frameData; | 803 Vector<char> frameData; |
| 804 frame.makeFrameData(frameData); | 804 frame.makeFrameData(frameData); |
| 805 | 805 |
| 806 return m_handle->send(frameData.data(), frameData.size()); | 806 return m_handle->send(frameData.data(), frameData.size()); |
| 807 } | 807 } |
| 808 | 808 |
| 809 } // namespace WebCore | 809 } // namespace WebCore |
| 810 | 810 |
| 811 #endif // ENABLE(WEB_SOCKETS) | 811 #endif // ENABLE(WEB_SOCKETS) |
| OLD | NEW |