| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 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 14 matching lines...) Expand all Loading... |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 | 32 |
| 33 #include "modules/websockets/WebSocket.h" | 33 #include "modules/websockets/WebSocket.h" |
| 34 | 34 |
| 35 #include "bindings/v8/ExceptionState.h" | |
| 36 #include "bindings/v8/ScriptController.h" | 35 #include "bindings/v8/ScriptController.h" |
| 37 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 38 #include "core/dom/Event.h" | 37 #include "core/dom/Event.h" |
| 39 #include "core/dom/EventListener.h" | 38 #include "core/dom/EventListener.h" |
| 40 #include "core/dom/EventNames.h" | 39 #include "core/dom/EventNames.h" |
| 41 #include "core/dom/ExceptionCode.h" | 40 #include "core/dom/ExceptionCode.h" |
| 42 #include "core/dom/MessageEvent.h" | 41 #include "core/dom/MessageEvent.h" |
| 43 #include "core/dom/ScriptExecutionContext.h" | 42 #include "core/dom/ScriptExecutionContext.h" |
| 44 #include "core/fileapi/Blob.h" | 43 #include "core/fileapi/Blob.h" |
| 45 #include "core/inspector/ScriptCallStack.h" | 44 #include "core/inspector/ScriptCallStack.h" |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 m_channel->disconnect(); | 147 m_channel->disconnect(); |
| 149 } | 148 } |
| 150 | 149 |
| 151 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context) | 150 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context) |
| 152 { | 151 { |
| 153 RefPtr<WebSocket> webSocket(adoptRef(new WebSocket(context))); | 152 RefPtr<WebSocket> webSocket(adoptRef(new WebSocket(context))); |
| 154 webSocket->suspendIfNeeded(); | 153 webSocket->suspendIfNeeded(); |
| 155 return webSocket.release(); | 154 return webSocket.release(); |
| 156 } | 155 } |
| 157 | 156 |
| 158 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context, const S
tring& url, ExceptionState& es) | 157 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context, const S
tring& url, ExceptionCode& ec) |
| 159 { | 158 { |
| 160 Vector<String> protocols; | 159 Vector<String> protocols; |
| 161 return WebSocket::create(context, url, protocols, es); | 160 return WebSocket::create(context, url, protocols, ec); |
| 162 } | 161 } |
| 163 | 162 |
| 164 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context, const S
tring& url, const Vector<String>& protocols, ExceptionState& es) | 163 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context, const S
tring& url, const Vector<String>& protocols, ExceptionCode& ec) |
| 165 { | 164 { |
| 166 if (url.isNull()) { | 165 if (url.isNull()) { |
| 167 es.throwDOMException(SyntaxError); | 166 ec = SyntaxError; |
| 168 return 0; | 167 return 0; |
| 169 } | 168 } |
| 170 | 169 |
| 171 RefPtr<WebSocket> webSocket(adoptRef(new WebSocket(context))); | 170 RefPtr<WebSocket> webSocket(adoptRef(new WebSocket(context))); |
| 172 webSocket->suspendIfNeeded(); | 171 webSocket->suspendIfNeeded(); |
| 173 | 172 |
| 174 webSocket->connect(context->completeURL(url), protocols, es); | 173 webSocket->connect(context->completeURL(url), protocols, ec); |
| 175 if (es.hadException()) | 174 if (ec) |
| 176 return 0; | 175 return 0; |
| 177 | 176 |
| 178 return webSocket.release(); | 177 return webSocket.release(); |
| 179 } | 178 } |
| 180 | 179 |
| 181 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context, const S
tring& url, const String& protocol, ExceptionState& es) | 180 PassRefPtr<WebSocket> WebSocket::create(ScriptExecutionContext* context, const S
tring& url, const String& protocol, ExceptionCode& ec) |
| 182 { | 181 { |
| 183 Vector<String> protocols; | 182 Vector<String> protocols; |
| 184 protocols.append(protocol); | 183 protocols.append(protocol); |
| 185 return WebSocket::create(context, url, protocols, es); | 184 return WebSocket::create(context, url, protocols, ec); |
| 186 } | 185 } |
| 187 | 186 |
| 188 void WebSocket::connect(const String& url, ExceptionState& es) | 187 void WebSocket::connect(const String& url, ExceptionCode& ec) |
| 189 { | 188 { |
| 190 Vector<String> protocols; | 189 Vector<String> protocols; |
| 191 connect(url, protocols, es); | 190 connect(url, protocols, ec); |
| 192 } | 191 } |
| 193 | 192 |
| 194 void WebSocket::connect(const String& url, const String& protocol, ExceptionStat
e& es) | 193 void WebSocket::connect(const String& url, const String& protocol, ExceptionCode
& ec) |
| 195 { | 194 { |
| 196 Vector<String> protocols; | 195 Vector<String> protocols; |
| 197 protocols.append(protocol); | 196 protocols.append(protocol); |
| 198 connect(url, protocols, es); | 197 connect(url, protocols, ec); |
| 199 } | 198 } |
| 200 | 199 |
| 201 void WebSocket::connect(const String& url, const Vector<String>& protocols, Exce
ptionState& es) | 200 void WebSocket::connect(const String& url, const Vector<String>& protocols, Exce
ptionCode& ec) |
| 202 { | 201 { |
| 203 LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); | 202 LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); |
| 204 m_url = KURL(KURL(), url); | 203 m_url = KURL(KURL(), url); |
| 205 | 204 |
| 206 if (!m_url.isValid()) { | 205 if (!m_url.isValid()) { |
| 207 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "Invalid url for WebSocket " + m_url.elidedString()); | 206 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "Invalid url for WebSocket " + m_url.elidedString()); |
| 208 m_state = CLOSED; | 207 m_state = CLOSED; |
| 209 es.throwDOMException(SyntaxError); | 208 ec = SyntaxError; |
| 210 return; | 209 return; |
| 211 } | 210 } |
| 212 | 211 |
| 213 if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { | 212 if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { |
| 214 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "Wrong url scheme for WebSocket " + m_url.elidedString()); | 213 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "Wrong url scheme for WebSocket " + m_url.elidedString()); |
| 215 m_state = CLOSED; | 214 m_state = CLOSED; |
| 216 es.throwDOMException(SyntaxError); | 215 ec = SyntaxError; |
| 217 return; | 216 return; |
| 218 } | 217 } |
| 219 if (m_url.hasFragmentIdentifier()) { | 218 if (m_url.hasFragmentIdentifier()) { |
| 220 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "URL has fragment component " + m_url.elidedString()); | 219 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "URL has fragment component " + m_url.elidedString()); |
| 221 m_state = CLOSED; | 220 m_state = CLOSED; |
| 222 es.throwDOMException(SyntaxError); | 221 ec = SyntaxError; |
| 223 return; | 222 return; |
| 224 } | 223 } |
| 225 if (!portAllowed(m_url)) { | 224 if (!portAllowed(m_url)) { |
| 226 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "WebSocket port " + String::number(m_url.port()) + " blocked"); | 225 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "WebSocket port " + String::number(m_url.port()) + " blocked"); |
| 227 m_state = CLOSED; | 226 m_state = CLOSED; |
| 228 es.throwDOMException(SecurityError); | 227 ec = SecurityError; |
| 229 return; | 228 return; |
| 230 } | 229 } |
| 231 | 230 |
| 232 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. | 231 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. |
| 233 bool shouldBypassMainWorldContentSecurityPolicy = false; | 232 bool shouldBypassMainWorldContentSecurityPolicy = false; |
| 234 if (scriptExecutionContext()->isDocument()) { | 233 if (scriptExecutionContext()->isDocument()) { |
| 235 Document* document = toDocument(scriptExecutionContext()); | 234 Document* document = toDocument(scriptExecutionContext()); |
| 236 shouldBypassMainWorldContentSecurityPolicy = document->frame()->script()
->shouldBypassMainWorldContentSecurityPolicy(); | 235 shouldBypassMainWorldContentSecurityPolicy = document->frame()->script()
->shouldBypassMainWorldContentSecurityPolicy(); |
| 237 } | 236 } |
| 238 if (!shouldBypassMainWorldContentSecurityPolicy && !scriptExecutionContext()
->contentSecurityPolicy()->allowConnectToSource(m_url)) { | 237 if (!shouldBypassMainWorldContentSecurityPolicy && !scriptExecutionContext()
->contentSecurityPolicy()->allowConnectToSource(m_url)) { |
| 239 m_state = CLOSED; | 238 m_state = CLOSED; |
| 240 | 239 |
| 241 // FIXME: Should this be throwing an exception? | 240 // FIXME: Should this be throwing an exception? |
| 242 es.throwDOMException(SecurityError); | 241 ec = SecurityError; |
| 243 return; | 242 return; |
| 244 } | 243 } |
| 245 | 244 |
| 246 m_channel = WebSocketChannel::create(scriptExecutionContext(), this); | 245 m_channel = WebSocketChannel::create(scriptExecutionContext(), this); |
| 247 | 246 |
| 248 // FIXME: There is a disagreement about restriction of subprotocols between
WebSocket API and hybi-10 protocol | 247 // FIXME: There is a disagreement about restriction of subprotocols between
WebSocket API and hybi-10 protocol |
| 249 // draft. The former simply says "only characters in the range U+0021 to U+0
07E are allowed," while the latter | 248 // draft. The former simply says "only characters in the range U+0021 to U+0
07E are allowed," while the latter |
| 250 // imposes a stricter rule: "the elements MUST be non-empty strings with cha
racters as defined in [RFC2616], | 249 // imposes a stricter rule: "the elements MUST be non-empty strings with cha
racters as defined in [RFC2616], |
| 251 // and MUST all be unique strings." | 250 // and MUST all be unique strings." |
| 252 // | 251 // |
| 253 // Here, we throw SyntaxError if the given protocols do not meet the latter
criteria. This behavior does not | 252 // Here, we throw SyntaxError if the given protocols do not meet the latter
criteria. This behavior does not |
| 254 // comply with WebSocket API specification, but it seems to be the only reas
onable way to handle this conflict. | 253 // comply with WebSocket API specification, but it seems to be the only reas
onable way to handle this conflict. |
| 255 for (size_t i = 0; i < protocols.size(); ++i) { | 254 for (size_t i = 0; i < protocols.size(); ++i) { |
| 256 if (!isValidProtocolString(protocols[i])) { | 255 if (!isValidProtocolString(protocols[i])) { |
| 257 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMe
ssageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(protocols[i]
) + "'"); | 256 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMe
ssageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(protocols[i]
) + "'"); |
| 258 m_state = CLOSED; | 257 m_state = CLOSED; |
| 259 es.throwDOMException(SyntaxError); | 258 ec = SyntaxError; |
| 260 return; | 259 return; |
| 261 } | 260 } |
| 262 } | 261 } |
| 263 HashSet<String> visited; | 262 HashSet<String> visited; |
| 264 for (size_t i = 0; i < protocols.size(); ++i) { | 263 for (size_t i = 0; i < protocols.size(); ++i) { |
| 265 if (!visited.add(protocols[i]).isNewEntry) { | 264 if (!visited.add(protocols[i]).isNewEntry) { |
| 266 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMe
ssageLevel, "WebSocket protocols contain duplicates: '" + encodeProtocolString(p
rotocols[i]) + "'"); | 265 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMe
ssageLevel, "WebSocket protocols contain duplicates: '" + encodeProtocolString(p
rotocols[i]) + "'"); |
| 267 m_state = CLOSED; | 266 m_state = CLOSED; |
| 268 es.throwDOMException(SyntaxError); | 267 ec = SyntaxError; |
| 269 return; | 268 return; |
| 270 } | 269 } |
| 271 } | 270 } |
| 272 | 271 |
| 273 String protocolString; | 272 String protocolString; |
| 274 if (!protocols.isEmpty()) | 273 if (!protocols.isEmpty()) |
| 275 protocolString = joinStrings(protocols, subProtocolSeperator()); | 274 protocolString = joinStrings(protocols, subProtocolSeperator()); |
| 276 | 275 |
| 277 m_channel->connect(m_url, protocolString); | 276 m_channel->connect(m_url, protocolString); |
| 278 ActiveDOMObject::setPendingActivity(this); | 277 ActiveDOMObject::setPendingActivity(this); |
| 279 } | 278 } |
| 280 | 279 |
| 281 void WebSocket::handleSendResult(WebSocketChannel::SendResult result, ExceptionS
tate& es) | 280 void WebSocket::handleSendResult(WebSocketChannel::SendResult result, ExceptionC
ode& ec) |
| 282 { | 281 { |
| 283 switch (result) { | 282 switch (result) { |
| 284 case WebSocketChannel::InvalidMessage: | 283 case WebSocketChannel::InvalidMessage: |
| 285 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "WebSocket message contains invalid character(s)."); | 284 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "WebSocket message contains invalid character(s)."); |
| 286 es.throwDOMException(SyntaxError); | 285 ec = SyntaxError; |
| 287 return; | 286 return; |
| 288 case WebSocketChannel::SendFail: | 287 case WebSocketChannel::SendFail: |
| 289 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "WebSocket send() failed."); | 288 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessag
eLevel, "WebSocket send() failed."); |
| 290 return; | 289 return; |
| 291 case WebSocketChannel::SendSuccess: | 290 case WebSocketChannel::SendSuccess: |
| 292 return; | 291 return; |
| 293 } | 292 } |
| 294 ASSERT_NOT_REACHED(); | 293 ASSERT_NOT_REACHED(); |
| 295 } | 294 } |
| 296 | 295 |
| 297 void WebSocket::updateBufferedAmountAfterClose(unsigned long payloadSize) | 296 void WebSocket::updateBufferedAmountAfterClose(unsigned long payloadSize) |
| 298 { | 297 { |
| 299 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payload
Size); | 298 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payload
Size); |
| 300 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFram
ingOverhead(payloadSize)); | 299 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFram
ingOverhead(payloadSize)); |
| 301 | 300 |
| 302 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLev
el, "WebSocket is already in CLOSING or CLOSED state."); | 301 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLev
el, "WebSocket is already in CLOSING or CLOSED state."); |
| 303 } | 302 } |
| 304 | 303 |
| 305 void WebSocket::send(const String& message, ExceptionState& es) | 304 void WebSocket::send(const String& message, ExceptionCode& ec) |
| 306 { | 305 { |
| 307 LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.utf8()
.data()); | 306 LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.utf8()
.data()); |
| 308 if (m_state == CONNECTING) { | 307 if (m_state == CONNECTING) { |
| 309 es.throwDOMException(InvalidStateError); | 308 ec = InvalidStateError; |
| 310 return; | 309 return; |
| 311 } | 310 } |
| 312 // No exception is raised if the connection was once established but has sub
sequently been closed. | 311 // No exception is raised if the connection was once established but has sub
sequently been closed. |
| 313 if (m_state == CLOSING || m_state == CLOSED) { | 312 if (m_state == CLOSING || m_state == CLOSED) { |
| 314 updateBufferedAmountAfterClose(message.utf8().length()); | 313 updateBufferedAmountAfterClose(message.utf8().length()); |
| 315 return; | 314 return; |
| 316 } | 315 } |
| 317 ASSERT(m_channel); | 316 ASSERT(m_channel); |
| 318 handleSendResult(m_channel->send(message), es); | 317 handleSendResult(m_channel->send(message), ec); |
| 319 } | 318 } |
| 320 | 319 |
| 321 void WebSocket::send(ArrayBuffer* binaryData, ExceptionState& es) | 320 void WebSocket::send(ArrayBuffer* binaryData, ExceptionCode& ec) |
| 322 { | 321 { |
| 323 LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryData)
; | 322 LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryData)
; |
| 324 ASSERT(binaryData); | 323 ASSERT(binaryData); |
| 325 if (m_state == CONNECTING) { | 324 if (m_state == CONNECTING) { |
| 326 es.throwDOMException(InvalidStateError); | 325 ec = InvalidStateError; |
| 327 return; | 326 return; |
| 328 } | 327 } |
| 329 if (m_state == CLOSING || m_state == CLOSED) { | 328 if (m_state == CLOSING || m_state == CLOSED) { |
| 330 updateBufferedAmountAfterClose(binaryData->byteLength()); | 329 updateBufferedAmountAfterClose(binaryData->byteLength()); |
| 331 return; | 330 return; |
| 332 } | 331 } |
| 333 ASSERT(m_channel); | 332 ASSERT(m_channel); |
| 334 handleSendResult(m_channel->send(*binaryData, 0, binaryData->byteLength()),
es); | 333 handleSendResult(m_channel->send(*binaryData, 0, binaryData->byteLength()),
ec); |
| 335 } | 334 } |
| 336 | 335 |
| 337 void WebSocket::send(ArrayBufferView* arrayBufferView, ExceptionState& es) | 336 void WebSocket::send(ArrayBufferView* arrayBufferView, ExceptionCode& ec) |
| 338 { | 337 { |
| 339 LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arrayBu
fferView); | 338 LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arrayBu
fferView); |
| 340 ASSERT(arrayBufferView); | 339 ASSERT(arrayBufferView); |
| 341 if (m_state == CONNECTING) { | 340 if (m_state == CONNECTING) { |
| 342 es.throwDOMException(InvalidStateError); | 341 ec = InvalidStateError; |
| 343 return; | 342 return; |
| 344 } | 343 } |
| 345 if (m_state == CLOSING || m_state == CLOSED) { | 344 if (m_state == CLOSING || m_state == CLOSED) { |
| 346 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); | 345 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); |
| 347 return; | 346 return; |
| 348 } | 347 } |
| 349 ASSERT(m_channel); | 348 ASSERT(m_channel); |
| 350 RefPtr<ArrayBuffer> arrayBuffer(arrayBufferView->buffer()); | 349 RefPtr<ArrayBuffer> arrayBuffer(arrayBufferView->buffer()); |
| 351 handleSendResult(m_channel->send(*arrayBuffer, arrayBufferView->byteOffset()
, arrayBufferView->byteLength()), es); | 350 handleSendResult(m_channel->send(*arrayBuffer, arrayBufferView->byteOffset()
, arrayBufferView->byteLength()), ec); |
| 352 } | 351 } |
| 353 | 352 |
| 354 void WebSocket::send(Blob* binaryData, ExceptionState& es) | 353 void WebSocket::send(Blob* binaryData, ExceptionCode& ec) |
| 355 { | 354 { |
| 356 LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->url(
).elidedString().utf8().data()); | 355 LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->url(
).elidedString().utf8().data()); |
| 357 ASSERT(binaryData); | 356 ASSERT(binaryData); |
| 358 if (m_state == CONNECTING) { | 357 if (m_state == CONNECTING) { |
| 359 es.throwDOMException(InvalidStateError); | 358 ec = InvalidStateError; |
| 360 return; | 359 return; |
| 361 } | 360 } |
| 362 if (m_state == CLOSING || m_state == CLOSED) { | 361 if (m_state == CLOSING || m_state == CLOSED) { |
| 363 updateBufferedAmountAfterClose(static_cast<unsigned long>(binaryData->si
ze())); | 362 updateBufferedAmountAfterClose(static_cast<unsigned long>(binaryData->si
ze())); |
| 364 return; | 363 return; |
| 365 } | 364 } |
| 366 ASSERT(m_channel); | 365 ASSERT(m_channel); |
| 367 handleSendResult(m_channel->send(*binaryData), es); | 366 handleSendResult(m_channel->send(*binaryData), ec); |
| 368 } | 367 } |
| 369 | 368 |
| 370 void WebSocket::close(unsigned short code, const String& reason, ExceptionState&
es) | 369 void WebSocket::close(unsigned short code, const String& reason, ExceptionCode&
ec) |
| 371 { | 370 { |
| 372 closeInternal(code, reason, es); | 371 closeInternal(code, reason, ec); |
| 373 } | 372 } |
| 374 | 373 |
| 375 void WebSocket::close(ExceptionState& es) | 374 void WebSocket::close(ExceptionCode& ec) |
| 376 { | 375 { |
| 377 closeInternal(WebSocketChannel::CloseEventCodeNotSpecified, String(), es); | 376 closeInternal(WebSocketChannel::CloseEventCodeNotSpecified, String(), ec); |
| 378 } | 377 } |
| 379 | 378 |
| 380 void WebSocket::close(unsigned short code, ExceptionState& es) | 379 void WebSocket::close(unsigned short code, ExceptionCode& ec) |
| 381 { | 380 { |
| 382 closeInternal(code, String(), es); | 381 closeInternal(code, String(), ec); |
| 383 } | 382 } |
| 384 | 383 |
| 385 void WebSocket::closeInternal(int code, const String& reason, ExceptionState& es
) | 384 void WebSocket::closeInternal(int code, const String& reason, ExceptionCode& ec) |
| 386 { | 385 { |
| 387 if (code == WebSocketChannel::CloseEventCodeNotSpecified) | 386 if (code == WebSocketChannel::CloseEventCodeNotSpecified) |
| 388 LOG(Network, "WebSocket %p close() without code and reason", this); | 387 LOG(Network, "WebSocket %p close() without code and reason", this); |
| 389 else { | 388 else { |
| 390 LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, rea
son.utf8().data()); | 389 LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, rea
son.utf8().data()); |
| 391 if (!(code == WebSocketChannel::CloseEventCodeNormalClosure || (WebSocke
tChannel::CloseEventCodeMinimumUserDefined <= code && code <= WebSocketChannel::
CloseEventCodeMaximumUserDefined))) { | 390 if (!(code == WebSocketChannel::CloseEventCodeNormalClosure || (WebSocke
tChannel::CloseEventCodeMinimumUserDefined <= code && code <= WebSocketChannel::
CloseEventCodeMaximumUserDefined))) { |
| 392 es.throwDOMException(InvalidAccessError); | 391 ec = InvalidAccessError; |
| 393 return; | 392 return; |
| 394 } | 393 } |
| 395 CString utf8 = reason.utf8(String::StrictConversionReplacingUnpairedSurr
ogatesWithFFFD); | 394 CString utf8 = reason.utf8(String::StrictConversionReplacingUnpairedSurr
ogatesWithFFFD); |
| 396 if (utf8.length() > maxReasonSizeInBytes) { | 395 if (utf8.length() > maxReasonSizeInBytes) { |
| 397 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMe
ssageLevel, "WebSocket close message is too long."); | 396 scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMe
ssageLevel, "WebSocket close message is too long."); |
| 398 es.throwDOMException(SyntaxError); | 397 ec = SyntaxError; |
| 399 return; | 398 return; |
| 400 } | 399 } |
| 401 } | 400 } |
| 402 | 401 |
| 403 if (m_state == CLOSING || m_state == CLOSED) | 402 if (m_state == CLOSING || m_state == CLOSED) |
| 404 return; | 403 return; |
| 405 if (m_state == CONNECTING) { | 404 if (m_state == CONNECTING) { |
| 406 m_state = CLOSING; | 405 m_state = CLOSING; |
| 407 m_channel->fail("WebSocket is closed before the connection is establishe
d.", WarningMessageLevel); | 406 m_channel->fail("WebSocket is closed before the connection is establishe
d.", WarningMessageLevel); |
| 408 return; | 407 return; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0
x10000; | 612 static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0
x10000; |
| 614 size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength; | 613 size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength; |
| 615 if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength) | 614 if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength) |
| 616 overhead += 8; | 615 overhead += 8; |
| 617 else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength) | 616 else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength) |
| 618 overhead += 2; | 617 overhead += 2; |
| 619 return overhead; | 618 return overhead; |
| 620 } | 619 } |
| 621 | 620 |
| 622 } // namespace WebCore | 621 } // namespace WebCore |
| OLD | NEW |