Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: net/websockets/websocket_channel.cc

Issue 131333010: Rename closing_* in WebSocketChannel to received_close_ and do some refactoring (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/websockets/websocket_channel.h" 5 #include "net/websockets/websocket_channel.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/basictypes.h" // for size_t 9 #include "base/basictypes.h" // for size_t
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 DCHECK_NE(kInvalidRangesEnd, upper); 71 DCHECK_NE(kInvalidRangesEnd, upper);
72 DCHECK_GT(upper, kInvalidRanges); 72 DCHECK_GT(upper, kInvalidRanges);
73 DCHECK_GT(*upper, code); 73 DCHECK_GT(*upper, code);
74 DCHECK_LE(*(upper - 1), code); 74 DCHECK_LE(*(upper - 1), code);
75 return ((upper - kInvalidRanges) % 2) == 0; 75 return ((upper - kInvalidRanges) % 2) == 0;
76 } 76 }
77 77
78 // This function avoids a bunch of boilerplate code. 78 // This function avoids a bunch of boilerplate code.
79 void AllowUnused(ChannelState ALLOW_UNUSED unused) {} 79 void AllowUnused(ChannelState ALLOW_UNUSED unused) {}
80 80
81 // Sets |name| to the name of the frame type for the given |opcode|. Note that
82 // for all of Text, Binary and Continuation opcode, this method returns
83 // "Data frame".
84 void GetFrameTypeForOpcode(WebSocketFrameHeader::OpCode opcode,
85 std::string* name) {
86 switch (opcode) {
87 case WebSocketFrameHeader::kOpCodeText: // fall-thru
88 case WebSocketFrameHeader::kOpCodeBinary: // fall-thru
89 case WebSocketFrameHeader::kOpCodeContinuation:
90 *name = "Data frame";
91 break;
92
93 case WebSocketFrameHeader::kOpCodePing:
94 *name = "Ping";
95 break;
96
97 case WebSocketFrameHeader::kOpCodePong:
98 *name = "Pong";
99 break;
100
101 case WebSocketFrameHeader::kOpCodeClose:
102 *name = "Close";
103 break;
104
105 default:
106 *name = "Unknown frame type";
107 break;
108 }
109
110 return;
111 }
112
81 } // namespace 113 } // namespace
82 114
83 // A class to encapsulate a set of frames and information about the size of 115 // A class to encapsulate a set of frames and information about the size of
84 // those frames. 116 // those frames.
85 class WebSocketChannel::SendBuffer { 117 class WebSocketChannel::SendBuffer {
86 public: 118 public:
87 SendBuffer() : total_bytes_(0) {} 119 SendBuffer() : total_bytes_(0) {}
88 120
89 // Add a WebSocketFrame to the buffer and increase total_bytes_. 121 // Add a WebSocketFrame to the buffer and increase total_bytes_.
90 void AddFrame(scoped_ptr<WebSocketFrame> chunk); 122 void AddFrame(scoped_ptr<WebSocketFrame> chunk);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 248
217 WebSocketChannel::WebSocketChannel( 249 WebSocketChannel::WebSocketChannel(
218 scoped_ptr<WebSocketEventInterface> event_interface, 250 scoped_ptr<WebSocketEventInterface> event_interface,
219 URLRequestContext* url_request_context) 251 URLRequestContext* url_request_context)
220 : event_interface_(event_interface.Pass()), 252 : event_interface_(event_interface.Pass()),
221 url_request_context_(url_request_context), 253 url_request_context_(url_request_context),
222 send_quota_low_water_mark_(kDefaultSendQuotaLowWaterMark), 254 send_quota_low_water_mark_(kDefaultSendQuotaLowWaterMark),
223 send_quota_high_water_mark_(kDefaultSendQuotaHighWaterMark), 255 send_quota_high_water_mark_(kDefaultSendQuotaHighWaterMark),
224 current_send_quota_(0), 256 current_send_quota_(0),
225 timeout_(base::TimeDelta::FromSeconds(kClosingHandshakeTimeoutSeconds)), 257 timeout_(base::TimeDelta::FromSeconds(kClosingHandshakeTimeoutSeconds)),
226 closing_code_(0), 258 received_close_code_(0),
227 state_(FRESHLY_CONSTRUCTED), 259 state_(FRESHLY_CONSTRUCTED),
228 notification_sender_(new HandshakeNotificationSender(this)) {} 260 notification_sender_(new HandshakeNotificationSender(this)) {}
229 261
230 WebSocketChannel::~WebSocketChannel() { 262 WebSocketChannel::~WebSocketChannel() {
231 // The stream may hold a pointer to read_frames_, and so it needs to be 263 // The stream may hold a pointer to read_frames_, and so it needs to be
232 // destroyed first. 264 // destroyed first.
233 stream_.reset(); 265 stream_.reset();
234 // The timer may have a callback pointing back to us, so stop it just in case 266 // The timer may have a callback pointing back to us, so stop it just in case
235 // someone decides to run the event loop from their destructor. 267 // someone decides to run the event loop from their destructor.
236 timer_.Stop(); 268 timer_.Stop();
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 DCHECK_NE(ERR_IO_PENDING, result); 566 DCHECK_NE(ERR_IO_PENDING, result);
535 switch (result) { 567 switch (result) {
536 case OK: 568 case OK:
537 // ReadFrames() must use ERR_CONNECTION_CLOSED for a closed connection 569 // ReadFrames() must use ERR_CONNECTION_CLOSED for a closed connection
538 // with no data read, not an empty response. 570 // with no data read, not an empty response.
539 DCHECK(!read_frames_.empty()) 571 DCHECK(!read_frames_.empty())
540 << "ReadFrames() returned OK, but nothing was read."; 572 << "ReadFrames() returned OK, but nothing was read.";
541 for (size_t i = 0; i < read_frames_.size(); ++i) { 573 for (size_t i = 0; i < read_frames_.size(); ++i) {
542 scoped_ptr<WebSocketFrame> frame(read_frames_[i]); 574 scoped_ptr<WebSocketFrame> frame(read_frames_[i]);
543 read_frames_[i] = NULL; 575 read_frames_[i] = NULL;
544 if (ProcessFrame(frame.Pass()) == CHANNEL_DELETED) 576 if (HandleFrame(frame.Pass()) == CHANNEL_DELETED)
545 return CHANNEL_DELETED; 577 return CHANNEL_DELETED;
546 } 578 }
547 read_frames_.clear(); 579 read_frames_.clear();
548 // There should always be a call to ReadFrames pending. 580 // There should always be a call to ReadFrames pending.
549 // TODO(ricea): Unless we are out of quota. 581 // TODO(ricea): Unless we are out of quota.
550 DCHECK_NE(CLOSED, state_); 582 DCHECK_NE(CLOSED, state_);
551 if (!synchronous) 583 if (!synchronous)
552 return ReadFrames(); 584 return ReadFrames();
553 return CHANNEL_ALIVE; 585 return CHANNEL_ALIVE;
554 586
555 case ERR_WS_PROTOCOL_ERROR: 587 case ERR_WS_PROTOCOL_ERROR:
556 // This could be kWebSocketErrorProtocolError (specifically, non-minimal 588 // This could be kWebSocketErrorProtocolError (specifically, non-minimal
557 // encoding of payload length) or kWebSocketErrorMessageTooBig, or an 589 // encoding of payload length) or kWebSocketErrorMessageTooBig, or an
558 // extension-specific error. 590 // extension-specific error.
559 return FailChannel("Invalid frame header", 591 return FailChannel("Invalid frame header",
560 kWebSocketErrorProtocolError, 592 kWebSocketErrorProtocolError,
561 "WebSocket Protocol Error"); 593 "WebSocket Protocol Error");
562 594
563 default: 595 default:
564 DCHECK_LT(result, 0) 596 DCHECK_LT(result, 0)
565 << "ReadFrames() should only return OK or ERR_ codes"; 597 << "ReadFrames() should only return OK or ERR_ codes";
566 stream_->Close(); 598 stream_->Close();
567 DCHECK_NE(CLOSED, state_); 599 DCHECK_NE(CLOSED, state_);
568 state_ = CLOSED; 600 state_ = CLOSED;
569 uint16 code = kWebSocketErrorAbnormalClosure; 601 uint16 code = kWebSocketErrorAbnormalClosure;
570 std::string reason = ""; 602 std::string reason = "";
571 if (closing_code_ != 0) { 603 if (received_close_code_ != 0) {
572 code = closing_code_; 604 code = received_close_code_;
573 reason = closing_reason_; 605 reason = received_close_reason_;
574 } 606 }
575 return DoDropChannel(code, reason); 607 return DoDropChannel(code, reason);
576 } 608 }
577 } 609 }
578 610
579 ChannelState WebSocketChannel::ProcessFrame(scoped_ptr<WebSocketFrame> frame) { 611 ChannelState WebSocketChannel::HandleFrame(
612 scoped_ptr<WebSocketFrame> frame) {
580 if (frame->header.masked) { 613 if (frame->header.masked) {
581 // RFC6455 Section 5.1 "A client MUST close a connection if it detects a 614 // RFC6455 Section 5.1 "A client MUST close a connection if it detects a
582 // masked frame." 615 // masked frame."
583 return FailChannel( 616 return FailChannel(
584 "A server must not mask any frames that it sends to the " 617 "A server must not mask any frames that it sends to the "
585 "client.", 618 "client.",
586 kWebSocketErrorProtocolError, 619 kWebSocketErrorProtocolError,
587 "Masked frame from server"); 620 "Masked frame from server");
588 } 621 }
589 const WebSocketFrameHeader::OpCode opcode = frame->header.opcode; 622 const WebSocketFrameHeader::OpCode opcode = frame->header.opcode;
590 if (WebSocketFrameHeader::IsKnownControlOpCode(opcode) && 623 if (WebSocketFrameHeader::IsKnownControlOpCode(opcode) &&
591 !frame->header.final) { 624 !frame->header.final) {
592 return FailChannel( 625 return FailChannel(
593 base::StringPrintf("Received fragmented control frame: opcode = %d", 626 base::StringPrintf("Received fragmented control frame: opcode = %d",
594 opcode), 627 opcode),
595 kWebSocketErrorProtocolError, 628 kWebSocketErrorProtocolError,
596 "Control message with FIN bit unset received"); 629 "Control message with FIN bit unset received");
597 } 630 }
598 631
599 // Respond to the frame appropriately to its type. 632 // Respond to the frame appropriately to its type.
600 return HandleFrame( 633 return HandleFrameBottomHalf(
601 opcode, frame->header.final, frame->data, frame->header.payload_length); 634 opcode, frame->header.final, frame->data, frame->header.payload_length);
602 } 635 }
603 636
604 ChannelState WebSocketChannel::HandleFrame( 637 ChannelState WebSocketChannel::HandleFrameBottomHalf(
605 const WebSocketFrameHeader::OpCode opcode, 638 const WebSocketFrameHeader::OpCode opcode,
606 bool final, 639 bool final,
607 const scoped_refptr<IOBuffer>& data_buffer, 640 const scoped_refptr<IOBuffer>& data_buffer,
608 size_t size) { 641 size_t size) {
609 DCHECK_NE(RECV_CLOSED, state_) 642 DCHECK_NE(RECV_CLOSED, state_)
610 << "HandleFrame() does not support being called re-entrantly from within " 643 << "HandleFrame() does not support being called re-entrantly from within "
611 "SendClose()"; 644 "SendClose()";
612 DCHECK_NE(CLOSED, state_); 645 DCHECK_NE(CLOSED, state_);
613 if (state_ == CLOSE_WAIT) { 646 if (state_ == CLOSE_WAIT) {
614 std::string frame_name; 647 std::string frame_name;
615 switch (opcode) { 648 GetFrameTypeForOpcode(opcode, &frame_name);
616 case WebSocketFrameHeader::kOpCodeText: // fall-thru
617 case WebSocketFrameHeader::kOpCodeBinary: // fall-thru
618 case WebSocketFrameHeader::kOpCodeContinuation:
619 frame_name = "Data frame";
620 break;
621 649
622 case WebSocketFrameHeader::kOpCodePing:
623 frame_name = "Ping";
624 break;
625
626 case WebSocketFrameHeader::kOpCodePong:
627 frame_name = "Pong";
628 break;
629
630 case WebSocketFrameHeader::kOpCodeClose:
631 frame_name = "Close";
632 break;
633
634 default:
635 frame_name = "Unknown frame type";
636 break;
637 }
638 // FailChannel() won't send another Close frame. 650 // FailChannel() won't send another Close frame.
639 return FailChannel( 651 return FailChannel(
640 frame_name + " received after close", kWebSocketErrorProtocolError, ""); 652 frame_name + " received after close", kWebSocketErrorProtocolError, "");
641 } 653 }
642 switch (opcode) { 654 switch (opcode) {
643 case WebSocketFrameHeader::kOpCodeText: // fall-thru 655 case WebSocketFrameHeader::kOpCodeText: // fall-thru
644 case WebSocketFrameHeader::kOpCodeBinary: // fall-thru 656 case WebSocketFrameHeader::kOpCodeBinary: // fall-thru
645 case WebSocketFrameHeader::kOpCodeContinuation: 657 case WebSocketFrameHeader::kOpCodeContinuation:
646 if (state_ == CONNECTED) { 658 if (state_ == CONNECTED) {
647 // TODO(ricea): Need to fail the connection if UTF-8 is invalid 659 // TODO(ricea): Need to fail the connection if UTF-8 is invalid
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 // message (escape control codes and so on). 697 // message (escape control codes and so on).
686 VLOG(1) << "Got Close with code " << code; 698 VLOG(1) << "Got Close with code " << code;
687 switch (state_) { 699 switch (state_) {
688 case CONNECTED: 700 case CONNECTED:
689 state_ = RECV_CLOSED; 701 state_ = RECV_CLOSED;
690 if (SendClose(code, reason) == // Sets state_ to CLOSE_WAIT 702 if (SendClose(code, reason) == // Sets state_ to CLOSE_WAIT
691 CHANNEL_DELETED) 703 CHANNEL_DELETED)
692 return CHANNEL_DELETED; 704 return CHANNEL_DELETED;
693 if (event_interface_->OnClosingHandshake() == CHANNEL_DELETED) 705 if (event_interface_->OnClosingHandshake() == CHANNEL_DELETED)
694 return CHANNEL_DELETED; 706 return CHANNEL_DELETED;
695 closing_code_ = code; 707 received_close_code_ = code;
696 closing_reason_ = reason; 708 received_close_reason_ = reason;
697 break; 709 break;
698 710
699 case SEND_CLOSED: 711 case SEND_CLOSED:
700 state_ = CLOSE_WAIT; 712 state_ = CLOSE_WAIT;
701 // From RFC6455 section 7.1.5: "Each endpoint 713 // From RFC6455 section 7.1.5: "Each endpoint
702 // will see the status code sent by the other end as _The WebSocket 714 // will see the status code sent by the other end as _The WebSocket
703 // Connection Close Code_." 715 // Connection Close Code_."
704 closing_code_ = code; 716 received_close_code_ = code;
705 closing_reason_ = reason; 717 received_close_reason_ = reason;
706 break; 718 break;
707 719
708 default: 720 default:
709 LOG(DFATAL) << "Got Close in unexpected state " << state_; 721 LOG(DFATAL) << "Got Close in unexpected state " << state_;
710 break; 722 break;
711 } 723 }
712 return CHANNEL_ALIVE; 724 return CHANNEL_ALIVE;
713 } 725 }
714 726
715 default: 727 default:
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 881
870 void WebSocketChannel::CloseTimeout() { 882 void WebSocketChannel::CloseTimeout() {
871 stream_->Close(); 883 stream_->Close();
872 DCHECK_NE(CLOSED, state_); 884 DCHECK_NE(CLOSED, state_);
873 state_ = CLOSED; 885 state_ = CLOSED;
874 AllowUnused(DoDropChannel(kWebSocketErrorAbnormalClosure, "")); 886 AllowUnused(DoDropChannel(kWebSocketErrorAbnormalClosure, ""));
875 // |this| has been deleted. 887 // |this| has been deleted.
876 } 888 }
877 889
878 } // namespace net 890 } // namespace net
OLDNEW
« net/websockets/websocket_channel.h ('K') | « net/websockets/websocket_channel.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698