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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 | 220 |
221 const char* WebSocket::subprotocolSeperator() | 221 const char* WebSocket::subprotocolSeperator() |
222 { | 222 { |
223 return ", "; | 223 return ", "; |
224 } | 224 } |
225 | 225 |
226 WebSocket::WebSocket(ExecutionContext* context) | 226 WebSocket::WebSocket(ExecutionContext* context) |
227 : ActiveDOMObject(context) | 227 : ActiveDOMObject(context) |
228 , m_state(CONNECTING) | 228 , m_state(CONNECTING) |
229 , m_bufferedAmount(0) | 229 , m_bufferedAmount(0) |
230 , m_consumedBufferedAmount(0) | |
230 , m_bufferedAmountAfterClose(0) | 231 , m_bufferedAmountAfterClose(0) |
231 , m_binaryType(BinaryTypeBlob) | 232 , m_binaryType(BinaryTypeBlob) |
232 , m_subprotocol("") | 233 , m_subprotocol("") |
233 , m_extensions("") | 234 , m_extensions("") |
234 , m_eventQueue(EventQueue::create(this)) | 235 , m_eventQueue(EventQueue::create(this)) |
236 , m_bufferedAmountConsumeTimer(this, &WebSocket::reflectBufferedAmountConsum ption) | |
235 { | 237 { |
236 ScriptWrappable::init(this); | 238 ScriptWrappable::init(this); |
237 } | 239 } |
238 | 240 |
239 WebSocket::~WebSocket() | 241 WebSocket::~WebSocket() |
240 { | 242 { |
241 ASSERT(!m_channel); | 243 ASSERT(!m_channel); |
242 } | 244 } |
243 | 245 |
244 void WebSocket::logError(const String& message) | 246 void WebSocket::logError(const String& message) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 } | 367 } |
366 | 368 |
367 void WebSocket::updateBufferedAmountAfterClose(unsigned long payloadSize) | 369 void WebSocket::updateBufferedAmountAfterClose(unsigned long payloadSize) |
368 { | 370 { |
369 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payload Size); | 371 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payload Size); |
370 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFram ingOverhead(payloadSize)); | 372 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFram ingOverhead(payloadSize)); |
371 | 373 |
372 logError("WebSocket is already in CLOSING or CLOSED state."); | 374 logError("WebSocket is already in CLOSING or CLOSED state."); |
373 } | 375 } |
374 | 376 |
377 void WebSocket::reflectBufferedAmountConsumption(Timer<WebSocket>*) | |
378 { | |
379 ASSERT(m_bufferedAmount >= m_consumedBufferedAmount); | |
380 WTF_LOG(Network, "WebSocket %p decreaseBufferedAmount() %lu => %lu", this, m _bufferedAmount, m_bufferedAmount - m_consumedBufferedAmount); | |
tyoshino (SeeGerritForStatus)
2014/06/16 07:31:42
reflect
yhirano
2014/06/16 10:19:44
Done.
| |
381 | |
382 m_bufferedAmount -= m_consumedBufferedAmount; | |
383 m_consumedBufferedAmount = 0; | |
384 } | |
385 | |
375 void WebSocket::releaseChannel() | 386 void WebSocket::releaseChannel() |
376 { | 387 { |
377 ASSERT(m_channel); | 388 ASSERT(m_channel); |
378 m_channel->disconnect(); | 389 m_channel->disconnect(); |
379 m_channel = nullptr; | 390 m_channel = nullptr; |
380 } | 391 } |
381 | 392 |
382 void WebSocket::send(const String& message, ExceptionState& exceptionState) | 393 void WebSocket::send(const String& message, ExceptionState& exceptionState) |
383 { | 394 { |
384 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.ut f8().data()); | 395 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.ut f8().data()); |
385 if (m_state == CONNECTING) { | 396 if (m_state == CONNECTING) { |
386 setInvalidStateErrorForSendMethod(exceptionState); | 397 setInvalidStateErrorForSendMethod(exceptionState); |
387 return; | 398 return; |
388 } | 399 } |
389 // No exception is raised if the connection was once established but has sub sequently been closed. | 400 // No exception is raised if the connection was once established but has sub sequently been closed. |
390 if (m_state == CLOSING || m_state == CLOSED) { | 401 if (m_state == CLOSING || m_state == CLOSED) { |
391 updateBufferedAmountAfterClose(message.utf8().length()); | 402 updateBufferedAmountAfterClose(message.utf8().length()); |
392 return; | 403 return; |
393 } | 404 } |
394 ASSERT(m_channel); | 405 ASSERT(m_channel); |
406 m_bufferedAmount += message.utf8().length(); | |
395 handleSendResult(m_channel->send(message), exceptionState, WebSocketSendType String); | 407 handleSendResult(m_channel->send(message), exceptionState, WebSocketSendType String); |
396 } | 408 } |
397 | 409 |
398 void WebSocket::send(ArrayBuffer* binaryData, ExceptionState& exceptionState) | 410 void WebSocket::send(ArrayBuffer* binaryData, ExceptionState& exceptionState) |
399 { | 411 { |
400 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD ata); | 412 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD ata); |
401 ASSERT(binaryData); | 413 ASSERT(binaryData); |
402 if (m_state == CONNECTING) { | 414 if (m_state == CONNECTING) { |
403 setInvalidStateErrorForSendMethod(exceptionState); | 415 setInvalidStateErrorForSendMethod(exceptionState); |
404 return; | 416 return; |
405 } | 417 } |
406 if (m_state == CLOSING || m_state == CLOSED) { | 418 if (m_state == CLOSING || m_state == CLOSED) { |
407 updateBufferedAmountAfterClose(binaryData->byteLength()); | 419 updateBufferedAmountAfterClose(binaryData->byteLength()); |
408 return; | 420 return; |
409 } | 421 } |
410 ASSERT(m_channel); | 422 ASSERT(m_channel); |
423 m_bufferedAmount += binaryData->byteLength(); | |
411 handleSendResult(m_channel->send(*binaryData, 0, binaryData->byteLength()), exceptionState, WebSocketSendTypeArrayBuffer); | 424 handleSendResult(m_channel->send(*binaryData, 0, binaryData->byteLength()), exceptionState, WebSocketSendTypeArrayBuffer); |
412 } | 425 } |
413 | 426 |
414 void WebSocket::send(ArrayBufferView* arrayBufferView, ExceptionState& exception State) | 427 void WebSocket::send(ArrayBufferView* arrayBufferView, ExceptionState& exception State) |
415 { | 428 { |
416 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr ayBufferView); | 429 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr ayBufferView); |
417 ASSERT(arrayBufferView); | 430 ASSERT(arrayBufferView); |
418 if (m_state == CONNECTING) { | 431 if (m_state == CONNECTING) { |
419 setInvalidStateErrorForSendMethod(exceptionState); | 432 setInvalidStateErrorForSendMethod(exceptionState); |
420 return; | 433 return; |
421 } | 434 } |
422 if (m_state == CLOSING || m_state == CLOSED) { | 435 if (m_state == CLOSING || m_state == CLOSED) { |
423 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); | 436 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); |
424 return; | 437 return; |
425 } | 438 } |
426 ASSERT(m_channel); | 439 ASSERT(m_channel); |
440 m_bufferedAmount += arrayBufferView->byteLength(); | |
427 RefPtr<ArrayBuffer> arrayBuffer(arrayBufferView->buffer()); | 441 RefPtr<ArrayBuffer> arrayBuffer(arrayBufferView->buffer()); |
428 handleSendResult(m_channel->send(*arrayBuffer, arrayBufferView->byteOffset() , arrayBufferView->byteLength()), exceptionState, WebSocketSendTypeArrayBufferVi ew); | 442 handleSendResult(m_channel->send(*arrayBuffer, arrayBufferView->byteOffset() , arrayBufferView->byteLength()), exceptionState, WebSocketSendTypeArrayBufferVi ew); |
429 } | 443 } |
430 | 444 |
431 void WebSocket::send(Blob* binaryData, ExceptionState& exceptionState) | 445 void WebSocket::send(Blob* binaryData, ExceptionState& exceptionState) |
432 { | 446 { |
433 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData-> uuid().utf8().data()); | 447 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData-> uuid().utf8().data()); |
434 ASSERT(binaryData); | 448 ASSERT(binaryData); |
435 if (m_state == CONNECTING) { | 449 if (m_state == CONNECTING) { |
436 setInvalidStateErrorForSendMethod(exceptionState); | 450 setInvalidStateErrorForSendMethod(exceptionState); |
437 return; | 451 return; |
438 } | 452 } |
439 if (m_state == CLOSING || m_state == CLOSED) { | 453 if (m_state == CLOSING || m_state == CLOSED) { |
440 updateBufferedAmountAfterClose(static_cast<unsigned long>(binaryData->si ze())); | 454 updateBufferedAmountAfterClose(static_cast<unsigned long>(binaryData->si ze())); |
441 return; | 455 return; |
442 } | 456 } |
457 m_bufferedAmount += binaryData->size(); | |
443 ASSERT(m_channel); | 458 ASSERT(m_channel); |
444 handleSendResult(m_channel->send(binaryData->blobDataHandle()), exceptionSta te, WebSocketSendTypeBlob); | 459 handleSendResult(m_channel->send(binaryData->blobDataHandle()), exceptionSta te, WebSocketSendTypeBlob); |
445 } | 460 } |
446 | 461 |
447 void WebSocket::close(unsigned short code, const String& reason, ExceptionState& exceptionState) | 462 void WebSocket::close(unsigned short code, const String& reason, ExceptionState& exceptionState) |
448 { | 463 { |
449 closeInternal(code, reason, exceptionState); | 464 closeInternal(code, reason, exceptionState); |
450 } | 465 } |
451 | 466 |
452 void WebSocket::close(ExceptionState& exceptionState) | 467 void WebSocket::close(ExceptionState& exceptionState) |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 } | 647 } |
633 } | 648 } |
634 | 649 |
635 void WebSocket::didReceiveMessageError() | 650 void WebSocket::didReceiveMessageError() |
636 { | 651 { |
637 WTF_LOG(Network, "WebSocket %p didReceiveMessageError()", this); | 652 WTF_LOG(Network, "WebSocket %p didReceiveMessageError()", this); |
638 m_state = CLOSED; | 653 m_state = CLOSED; |
639 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); | 654 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); |
640 } | 655 } |
641 | 656 |
642 void WebSocket::didUpdateBufferedAmount(unsigned long bufferedAmount) | 657 void WebSocket::didConsumeBufferedAmount(unsigned long consumed) |
643 { | 658 { |
644 WTF_LOG(Network, "WebSocket %p didUpdateBufferedAmount() New bufferedAmount is %lu", this, bufferedAmount); | 659 ASSERT(m_bufferedAmount >= consumed); |
660 WTF_LOG(Network, "WebSocket %p didConsumeBufferedAmount(%lu)", this, consume d); | |
645 if (m_state == CLOSED) | 661 if (m_state == CLOSED) |
646 return; | 662 return; |
647 m_bufferedAmount = bufferedAmount; | 663 m_consumedBufferedAmount += consumed; |
664 if (!m_bufferedAmountConsumeTimer.isActive()) | |
665 m_bufferedAmountConsumeTimer.startOneShot(0, FROM_HERE); | |
648 } | 666 } |
649 | 667 |
650 void WebSocket::didStartClosingHandshake() | 668 void WebSocket::didStartClosingHandshake() |
651 { | 669 { |
652 WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this); | 670 WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this); |
653 m_state = CLOSING; | 671 m_state = CLOSING; |
654 } | 672 } |
655 | 673 |
656 void WebSocket::didClose(unsigned long unhandledBufferedAmount, ClosingHandshake CompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) | 674 void WebSocket::didClose(ClosingHandshakeCompletionStatus closingHandshakeComple tion, unsigned short code, const String& reason) |
657 { | 675 { |
658 WTF_LOG(Network, "WebSocket %p didClose()", this); | 676 WTF_LOG(Network, "WebSocket %p didClose()", this); |
659 if (!m_channel) | 677 if (!m_channel) |
660 return; | 678 return; |
661 bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && closingHan dshakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseE ventCodeAbnormalClosure; | 679 m_bufferedAmount -= m_consumedBufferedAmount; |
tyoshino (SeeGerritForStatus)
2014/06/16 07:31:42
doesn't updating m_bufferedAmount here violate the
yhirano
2014/06/16 10:19:44
The spec says:
The bufferedAmount attribute must r
yhirano
2014/06/16 11:53:23
Done.
| |
680 m_consumedBufferedAmount = 0; | |
681 bool hasAllDataConsumed = !m_bufferedAmount; | |
682 bool wasClean = m_state == CLOSING && hasAllDataConsumed && closingHandshake Completion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEventCo deAbnormalClosure; | |
683 m_state = CLOSED; | |
662 | 684 |
663 m_state = CLOSED; | |
664 m_bufferedAmount = unhandledBufferedAmount; | |
665 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); | 685 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); |
666 releaseChannel(); | 686 releaseChannel(); |
667 } | 687 } |
668 | 688 |
669 size_t WebSocket::getFramingOverhead(size_t payloadSize) | 689 size_t WebSocket::getFramingOverhead(size_t payloadSize) |
670 { | 690 { |
671 static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header. | 691 static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header. |
672 static const size_t hybiMaskingKeyLength = 4; // Every frame from client mus t have masking key. | 692 static const size_t hybiMaskingKeyLength = 4; // Every frame from client mus t have masking key. |
673 static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126 ; | 693 static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126 ; |
674 static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0 x10000; | 694 static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0 x10000; |
675 size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength; | 695 size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength; |
676 if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength) | 696 if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength) |
677 overhead += 8; | 697 overhead += 8; |
678 else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength) | 698 else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength) |
679 overhead += 2; | 699 overhead += 2; |
680 return overhead; | 700 return overhead; |
681 } | 701 } |
682 | 702 |
683 void WebSocket::trace(Visitor* visitor) | 703 void WebSocket::trace(Visitor* visitor) |
684 { | 704 { |
685 visitor->trace(m_channel); | 705 visitor->trace(m_channel); |
686 visitor->trace(m_eventQueue); | 706 visitor->trace(m_eventQueue); |
687 EventTargetWithInlineData::trace(visitor); | 707 EventTargetWithInlineData::trace(visitor); |
688 } | 708 } |
689 | 709 |
690 } // namespace WebCore | 710 } // namespace WebCore |
OLD | NEW |