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

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

Issue 2267233002: Change WebSocketChannel to pass data via IOBuffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More Created 4 years, 3 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
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 <limits.h> // for INT_MAX 7 #include <limits.h> // for INT_MAX
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 break; 121 break;
122 122
123 default: 123 default:
124 *name = "Unknown frame type"; 124 *name = "Unknown frame type";
125 break; 125 break;
126 } 126 }
127 127
128 return; 128 return;
129 } 129 }
130 130
131 class DependentIOBuffer : public WrappedIOBuffer {
132 public:
133 DependentIOBuffer(const scoped_refptr<IOBuffer>& buffer, size_t offset)
yhirano 2016/09/06 12:19:48 I think |const scoped_refptr<T>&| is discouraged.
134 : WrappedIOBuffer(buffer->data() + offset), buffer_(buffer) {}
135 private:
136 ~DependentIOBuffer() override {}
137 scoped_refptr<net::IOBuffer> buffer_;
138 };
139
131 } // namespace 140 } // namespace
132 141
133 // A class to encapsulate a set of frames and information about the size of 142 // A class to encapsulate a set of frames and information about the size of
134 // those frames. 143 // those frames.
135 class WebSocketChannel::SendBuffer { 144 class WebSocketChannel::SendBuffer {
136 public: 145 public:
137 SendBuffer() : total_bytes_(0) {} 146 SendBuffer() : total_bytes_(0) {}
138 147
139 // Add a WebSocketFrame to the buffer and increase total_bytes_. 148 // Add a WebSocketFrame to the buffer and increase total_bytes_.
140 void AddFrame(std::unique_ptr<WebSocketFrame> chunk); 149 void AddFrame(std::unique_ptr<WebSocketFrame> chunk);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // The state RECV_CLOSED is not supported here, because it is only used in one 372 // The state RECV_CLOSED is not supported here, because it is only used in one
364 // code path and should not leak into the code in general. 373 // code path and should not leak into the code in general.
365 DCHECK_NE(RECV_CLOSED, state_) 374 DCHECK_NE(RECV_CLOSED, state_)
366 << "InClosingState called with state_ == RECV_CLOSED"; 375 << "InClosingState called with state_ == RECV_CLOSED";
367 return state_ == SEND_CLOSED || state_ == CLOSE_WAIT || state_ == CLOSED; 376 return state_ == SEND_CLOSED || state_ == CLOSE_WAIT || state_ == CLOSED;
368 } 377 }
369 378
370 WebSocketChannel::ChannelState WebSocketChannel::SendFrame( 379 WebSocketChannel::ChannelState WebSocketChannel::SendFrame(
371 bool fin, 380 bool fin,
372 WebSocketFrameHeader::OpCode op_code, 381 WebSocketFrameHeader::OpCode op_code,
373 const std::vector<char>& data) { 382 scoped_refptr<IOBuffer> buffer,
374 if (data.size() > INT_MAX) { 383 size_t buffer_size) {
384 if (buffer_size > INT_MAX) {
375 NOTREACHED() << "Frame size sanity check failed"; 385 NOTREACHED() << "Frame size sanity check failed";
376 return CHANNEL_ALIVE; 386 return CHANNEL_ALIVE;
377 } 387 }
378 if (stream_ == NULL) { 388 if (stream_ == NULL) {
379 LOG(DFATAL) << "Got SendFrame without a connection established; " 389 LOG(DFATAL) << "Got SendFrame without a connection established; "
380 << "misbehaving renderer? fin=" << fin << " op_code=" << op_code 390 << "misbehaving renderer? fin=" << fin << " op_code=" << op_code
381 << " data.size()=" << data.size(); 391 << " buffer_size=" << buffer_size;
382 return CHANNEL_ALIVE; 392 return CHANNEL_ALIVE;
383 } 393 }
384 if (InClosingState()) { 394 if (InClosingState()) {
385 DVLOG(1) << "SendFrame called in state " << state_ 395 DVLOG(1) << "SendFrame called in state " << state_
386 << ". This may be a bug, or a harmless race."; 396 << ". This may be a bug, or a harmless race.";
387 return CHANNEL_ALIVE; 397 return CHANNEL_ALIVE;
388 } 398 }
389 if (state_ != CONNECTED) { 399 if (state_ != CONNECTED) {
390 NOTREACHED() << "SendFrame() called in state " << state_; 400 NOTREACHED() << "SendFrame() called in state " << state_;
391 return CHANNEL_ALIVE; 401 return CHANNEL_ALIVE;
392 } 402 }
393 if (data.size() > base::checked_cast<size_t>(current_send_quota_)) { 403 if (buffer_size > base::checked_cast<size_t>(current_send_quota_)) {
394 // TODO(ricea): Kill renderer. 404 // TODO(ricea): Kill renderer.
395 return FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, ""); 405 return FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, "");
396 // |this| has been deleted. 406 // |this| has been deleted.
397 } 407 }
398 if (!WebSocketFrameHeader::IsKnownDataOpCode(op_code)) { 408 if (!WebSocketFrameHeader::IsKnownDataOpCode(op_code)) {
399 LOG(DFATAL) << "Got SendFrame with bogus op_code " << op_code 409 LOG(DFATAL) << "Got SendFrame with bogus op_code " << op_code
400 << "; misbehaving renderer? fin=" << fin 410 << "; misbehaving renderer? fin=" << fin
401 << " data.size()=" << data.size(); 411 << " buffer_size=" << buffer_size;
402 return CHANNEL_ALIVE; 412 return CHANNEL_ALIVE;
403 } 413 }
404 if (op_code == WebSocketFrameHeader::kOpCodeText || 414 if (op_code == WebSocketFrameHeader::kOpCodeText ||
405 (op_code == WebSocketFrameHeader::kOpCodeContinuation && 415 (op_code == WebSocketFrameHeader::kOpCodeContinuation &&
406 sending_text_message_)) { 416 sending_text_message_)) {
407 StreamingUtf8Validator::State state = 417 StreamingUtf8Validator::State state =
408 outgoing_utf8_validator_.AddBytes(data.data(), data.size()); 418 outgoing_utf8_validator_.AddBytes(buffer->data(), buffer_size);
409 if (state == StreamingUtf8Validator::INVALID || 419 if (state == StreamingUtf8Validator::INVALID ||
410 (state == StreamingUtf8Validator::VALID_MIDPOINT && fin)) { 420 (state == StreamingUtf8Validator::VALID_MIDPOINT && fin)) {
411 // TODO(ricea): Kill renderer. 421 // TODO(ricea): Kill renderer.
412 return FailChannel("Browser sent a text frame containing invalid UTF-8", 422 return FailChannel("Browser sent a text frame containing invalid UTF-8",
413 kWebSocketErrorGoingAway, ""); 423 kWebSocketErrorGoingAway, "");
414 // |this| has been deleted. 424 // |this| has been deleted.
415 } 425 }
416 sending_text_message_ = !fin; 426 sending_text_message_ = !fin;
417 DCHECK(!fin || state == StreamingUtf8Validator::VALID_ENDPOINT); 427 DCHECK(!fin || state == StreamingUtf8Validator::VALID_ENDPOINT);
418 } 428 }
419 current_send_quota_ -= data.size(); 429 current_send_quota_ -= buffer_size;
420 // TODO(ricea): If current_send_quota_ has dropped below 430 // TODO(ricea): If current_send_quota_ has dropped below
421 // send_quota_low_water_mark_, it might be good to increase the "low 431 // send_quota_low_water_mark_, it might be good to increase the "low
422 // water mark" and "high water mark", but only if the link to the WebSocket 432 // water mark" and "high water mark", but only if the link to the WebSocket
423 // server is not saturated. 433 // server is not saturated.
424 scoped_refptr<IOBuffer> buffer(new IOBuffer(data.size())); 434 return SendFrameFromIOBuffer(fin, op_code, std::move(buffer), buffer_size);
yhirano 2016/09/06 12:19:48 With this change SendFrame also takes an IOBuffer.
425 std::copy(data.begin(), data.end(), buffer->data());
426 return SendFrameFromIOBuffer(fin, op_code, buffer, data.size());
427 // |this| may have been deleted. 435 // |this| may have been deleted.
428 } 436 }
429 437
430 ChannelState WebSocketChannel::SendFlowControl(int64_t quota) { 438 ChannelState WebSocketChannel::SendFlowControl(int64_t quota) {
431 DCHECK(state_ == CONNECTING || state_ == CONNECTED || state_ == SEND_CLOSED || 439 DCHECK(state_ == CONNECTING || state_ == CONNECTED || state_ == SEND_CLOSED ||
432 state_ == CLOSE_WAIT); 440 state_ == CLOSE_WAIT);
433 // TODO(ricea): Kill the renderer if it tries to send us a negative quota 441 // TODO(ricea): Kill the renderer if it tries to send us a negative quota
434 // value or > INT_MAX. 442 // value or > INT_MAX.
435 DCHECK_GE(quota, 0); 443 DCHECK_GE(quota, 0);
436 DCHECK_LE(quota, INT_MAX); 444 DCHECK_LE(quota, INT_MAX);
437 if (!pending_received_frames_.empty()) { 445 if (!pending_received_frames_.empty()) {
438 DCHECK_EQ(0u, current_receive_quota_); 446 DCHECK_EQ(0u, current_receive_quota_);
439 } 447 }
440 while (!pending_received_frames_.empty() && quota > 0) { 448 while (!pending_received_frames_.empty() && quota > 0) {
441 PendingReceivedFrame& front = pending_received_frames_.front(); 449 PendingReceivedFrame& front = pending_received_frames_.front();
442 const uint64_t data_size = front.size() - front.offset(); 450 const uint64_t data_size = front.size() - front.offset();
443 const uint64_t bytes_to_send = 451 const uint64_t bytes_to_send =
444 std::min(base::checked_cast<uint64_t>(quota), data_size); 452 std::min(base::checked_cast<uint64_t>(quota), data_size);
445 const bool final = front.final() && data_size == bytes_to_send; 453 const bool final = front.final() && data_size == bytes_to_send;
446 const char* data = 454 scoped_refptr<IOBuffer> buffer_to_pass;
447 front.data().get() ? front.data()->data() + front.offset() : NULL; 455 if (front.data().get()) {
Ryan Sleevi 2016/08/30 08:07:39 The .get() here is superfluous due to the bool ope
448 DCHECK(!bytes_to_send || data) << "Non empty data should not be null."; 456 buffer_to_pass = new DependentIOBuffer(front.data(), front.offset());
449 const std::vector<char> data_vector(data, data + bytes_to_send); 457 } else {
458 DCHECK(!bytes_to_send) << "Non empty data should not be null.";
459 }
450 DVLOG(3) << "Sending frame previously split due to quota to the " 460 DVLOG(3) << "Sending frame previously split due to quota to the "
451 << "renderer: quota=" << quota << " data_size=" << data_size 461 << "renderer: quota=" << quota << " data_size=" << data_size
452 << " bytes_to_send=" << bytes_to_send; 462 << " bytes_to_send=" << bytes_to_send;
453 if (event_interface_->OnDataFrame(final, front.opcode(), data_vector) == 463 if (event_interface_->OnDataFrame(
454 CHANNEL_DELETED) 464 final, front.opcode(), std::move(buffer_to_pass), bytes_to_send) ==
465 CHANNEL_DELETED)
455 return CHANNEL_DELETED; 466 return CHANNEL_DELETED;
456 if (bytes_to_send < data_size) { 467 if (bytes_to_send < data_size) {
457 front.DidConsume(bytes_to_send); 468 front.DidConsume(bytes_to_send);
458 front.ResetOpcode(); 469 front.ResetOpcode();
459 return CHANNEL_ALIVE; 470 return CHANNEL_ALIVE;
460 } 471 }
461 quota -= bytes_to_send; 472 quota -= bytes_to_send;
462 473
463 pending_received_frames_.pop(); 474 pending_received_frames_.pop();
464 } 475 }
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 "One or more reserved bits are on: reserved1 = %d, " 836 "One or more reserved bits are on: reserved1 = %d, "
826 "reserved2 = %d, reserved3 = %d", 837 "reserved2 = %d, reserved3 = %d",
827 static_cast<int>(frame->header.reserved1), 838 static_cast<int>(frame->header.reserved1),
828 static_cast<int>(frame->header.reserved2), 839 static_cast<int>(frame->header.reserved2),
829 static_cast<int>(frame->header.reserved3)), 840 static_cast<int>(frame->header.reserved3)),
830 kWebSocketErrorProtocolError, 841 kWebSocketErrorProtocolError,
831 "Invalid reserved bit"); 842 "Invalid reserved bit");
832 } 843 }
833 844
834 // Respond to the frame appropriately to its type. 845 // Respond to the frame appropriately to its type.
835 return HandleFrameByState( 846 return HandleFrameByState(opcode, frame->header.final, std::move(frame->data),
836 opcode, frame->header.final, frame->data, frame->header.payload_length); 847 frame->header.payload_length);
837 } 848 }
838 849
839 ChannelState WebSocketChannel::HandleFrameByState( 850 ChannelState WebSocketChannel::HandleFrameByState(
840 const WebSocketFrameHeader::OpCode opcode, 851 const WebSocketFrameHeader::OpCode opcode,
841 bool final, 852 bool final,
842 const scoped_refptr<IOBuffer>& data_buffer, 853 scoped_refptr<IOBuffer> data_buffer,
843 uint64_t size) { 854 uint64_t size) {
844 DCHECK_NE(RECV_CLOSED, state_) 855 DCHECK_NE(RECV_CLOSED, state_)
845 << "HandleFrame() does not support being called re-entrantly from within " 856 << "HandleFrame() does not support being called re-entrantly from within "
846 "SendClose()"; 857 "SendClose()";
847 DCHECK_NE(CLOSED, state_); 858 DCHECK_NE(CLOSED, state_);
848 if (state_ == CLOSE_WAIT) { 859 if (state_ == CLOSE_WAIT) {
849 std::string frame_name; 860 std::string frame_name;
850 GetFrameTypeForOpcode(opcode, &frame_name); 861 GetFrameTypeForOpcode(opcode, &frame_name);
851 862
852 // FailChannel() won't send another Close frame. 863 // FailChannel() won't send another Close frame.
853 return FailChannel( 864 return FailChannel(
854 frame_name + " received after close", kWebSocketErrorProtocolError, ""); 865 frame_name + " received after close", kWebSocketErrorProtocolError, "");
855 } 866 }
856 switch (opcode) { 867 switch (opcode) {
857 case WebSocketFrameHeader::kOpCodeText: // fall-thru 868 case WebSocketFrameHeader::kOpCodeText: // fall-thru
858 case WebSocketFrameHeader::kOpCodeBinary: 869 case WebSocketFrameHeader::kOpCodeBinary:
859 case WebSocketFrameHeader::kOpCodeContinuation: 870 case WebSocketFrameHeader::kOpCodeContinuation:
860 return HandleDataFrame(opcode, final, data_buffer, size); 871 return HandleDataFrame(opcode, final, std::move(data_buffer), size);
861 872
862 case WebSocketFrameHeader::kOpCodePing: 873 case WebSocketFrameHeader::kOpCodePing:
863 DVLOG(1) << "Got Ping of size " << size; 874 DVLOG(1) << "Got Ping of size " << size;
864 if (state_ == CONNECTED) 875 if (state_ == CONNECTED)
865 return SendFrameFromIOBuffer( 876 return SendFrameFromIOBuffer(
866 true, WebSocketFrameHeader::kOpCodePong, data_buffer, size); 877 true, WebSocketFrameHeader::kOpCodePong, std::move(data_buffer),
878 size);
867 DVLOG(3) << "Ignored ping in state " << state_; 879 DVLOG(3) << "Ignored ping in state " << state_;
868 return CHANNEL_ALIVE; 880 return CHANNEL_ALIVE;
869 881
870 case WebSocketFrameHeader::kOpCodePong: 882 case WebSocketFrameHeader::kOpCodePong:
871 DVLOG(1) << "Got Pong of size " << size; 883 DVLOG(1) << "Got Pong of size " << size;
872 // There is no need to do anything with pong messages. 884 // There is no need to do anything with pong messages.
873 return CHANNEL_ALIVE; 885 return CHANNEL_ALIVE;
874 886
875 case WebSocketFrameHeader::kOpCodeClose: { 887 case WebSocketFrameHeader::kOpCodeClose: {
876 uint16_t code = kWebSocketNormalClosure; 888 uint16_t code = kWebSocketNormalClosure;
877 std::string reason; 889 std::string reason;
878 std::string message; 890 std::string message;
879 if (!ParseClose(data_buffer, size, &code, &reason, &message)) { 891 if (!ParseClose(std::move(data_buffer), size, &code, &reason, &message)) {
880 return FailChannel(message, code, reason); 892 return FailChannel(message, code, reason);
881 } 893 }
882 // TODO(ricea): Find a way to safely log the message from the close 894 // TODO(ricea): Find a way to safely log the message from the close
883 // message (escape control codes and so on). 895 // message (escape control codes and so on).
884 DVLOG(1) << "Got Close with code " << code; 896 DVLOG(1) << "Got Close with code " << code;
885 return HandleCloseFrame(code, reason); 897 return HandleCloseFrame(code, reason);
886 } 898 }
887 899
888 default: 900 default:
889 return FailChannel( 901 return FailChannel(
890 base::StringPrintf("Unrecognized frame opcode: %d", opcode), 902 base::StringPrintf("Unrecognized frame opcode: %d", opcode),
891 kWebSocketErrorProtocolError, 903 kWebSocketErrorProtocolError,
892 "Unknown opcode"); 904 "Unknown opcode");
893 } 905 }
894 } 906 }
895 907
896 ChannelState WebSocketChannel::HandleDataFrame( 908 ChannelState WebSocketChannel::HandleDataFrame(
897 WebSocketFrameHeader::OpCode opcode, 909 WebSocketFrameHeader::OpCode opcode,
898 bool final, 910 bool final,
899 const scoped_refptr<IOBuffer>& data_buffer, 911 scoped_refptr<IOBuffer> data_buffer,
900 uint64_t size) { 912 uint64_t size) {
901 if (state_ != CONNECTED) { 913 if (state_ != CONNECTED) {
902 DVLOG(3) << "Ignored data packet received in state " << state_; 914 DVLOG(3) << "Ignored data packet received in state " << state_;
903 return CHANNEL_ALIVE; 915 return CHANNEL_ALIVE;
904 } 916 }
905 if (has_received_close_frame_) { 917 if (has_received_close_frame_) {
906 DVLOG(3) << "Ignored data packet as we've received a close frame."; 918 DVLOG(3) << "Ignored data packet as we've received a close frame.";
907 return CHANNEL_ALIVE; 919 return CHANNEL_ALIVE;
908 } 920 }
909 DCHECK(opcode == WebSocketFrameHeader::kOpCodeContinuation || 921 DCHECK(opcode == WebSocketFrameHeader::kOpCodeContinuation ||
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 WebSocketFrameHeader::OpCode opcode_to_queue = 968 WebSocketFrameHeader::OpCode opcode_to_queue =
957 no_quota ? opcode_to_send : WebSocketFrameHeader::kOpCodeContinuation; 969 no_quota ? opcode_to_send : WebSocketFrameHeader::kOpCodeContinuation;
958 pending_received_frames_.push(PendingReceivedFrame( 970 pending_received_frames_.push(PendingReceivedFrame(
959 final, opcode_to_queue, data_buffer, current_receive_quota_, size)); 971 final, opcode_to_queue, data_buffer, current_receive_quota_, size));
960 if (no_quota) 972 if (no_quota)
961 return CHANNEL_ALIVE; 973 return CHANNEL_ALIVE;
962 size = current_receive_quota_; 974 size = current_receive_quota_;
963 final = false; 975 final = false;
964 } 976 }
965 977
966 // TODO(ricea): Can this copy be eliminated?
967 const char* const data_begin = size ? data_buffer->data() : NULL;
968 const char* const data_end = data_begin + size;
969 const std::vector<char> data(data_begin, data_end);
970 current_receive_quota_ -= size; 978 current_receive_quota_ -= size;
971 979
972 // Sends the received frame to the renderer process. 980 // Sends the received frame to the renderer process.
973 return event_interface_->OnDataFrame(final, opcode_to_send, data); 981 return event_interface_->OnDataFrame(
982 final, opcode_to_send, std::move(data_buffer), size);
974 } 983 }
975 984
976 ChannelState WebSocketChannel::HandleCloseFrame(uint16_t code, 985 ChannelState WebSocketChannel::HandleCloseFrame(uint16_t code,
977 const std::string& reason) { 986 const std::string& reason) {
978 DVLOG(1) << "Got Close with code " << code; 987 DVLOG(1) << "Got Close with code " << code;
979 switch (state_) { 988 switch (state_) {
980 case CONNECTED: 989 case CONNECTED:
981 has_received_close_frame_ = true; 990 has_received_close_frame_ = true;
982 received_close_code_ = code; 991 received_close_code_ = code;
983 received_close_reason_ = reason; 992 received_close_reason_ = reason;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 close_timer_.Start( 1038 close_timer_.Start(
1030 FROM_HERE, underlying_connection_close_timeout_, 1039 FROM_HERE, underlying_connection_close_timeout_,
1031 base::Bind(&WebSocketChannel::CloseTimeout, base::Unretained(this))); 1040 base::Bind(&WebSocketChannel::CloseTimeout, base::Unretained(this)));
1032 1041
1033 return event_interface_->OnClosingHandshake(); 1042 return event_interface_->OnClosingHandshake();
1034 } 1043 }
1035 1044
1036 ChannelState WebSocketChannel::SendFrameFromIOBuffer( 1045 ChannelState WebSocketChannel::SendFrameFromIOBuffer(
1037 bool fin, 1046 bool fin,
1038 WebSocketFrameHeader::OpCode op_code, 1047 WebSocketFrameHeader::OpCode op_code,
1039 const scoped_refptr<IOBuffer>& buffer, 1048 scoped_refptr<IOBuffer> buffer,
1040 uint64_t size) { 1049 uint64_t size) {
1041 DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED); 1050 DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
1042 DCHECK(stream_); 1051 DCHECK(stream_);
1043 1052
1044 std::unique_ptr<WebSocketFrame> frame(new WebSocketFrame(op_code)); 1053 std::unique_ptr<WebSocketFrame> frame(new WebSocketFrame(op_code));
1045 WebSocketFrameHeader& header = frame->header; 1054 WebSocketFrameHeader& header = frame->header;
1046 header.final = fin; 1055 header.final = fin;
1047 header.masked = true; 1056 header.masked = true;
1048 header.payload_length = size; 1057 header.payload_length = size;
1049 frame->data = buffer; 1058 frame->data = std::move(buffer);
1050 1059
1051 if (data_being_sent_) { 1060 if (data_being_sent_) {
1052 // Either the link to the WebSocket server is saturated, or several messages 1061 // Either the link to the WebSocket server is saturated, or several messages
1053 // are being sent in a batch. 1062 // are being sent in a batch.
1054 // TODO(ricea): Keep some statistics to work out the situation and adjust 1063 // TODO(ricea): Keep some statistics to work out the situation and adjust
1055 // quota appropriately. 1064 // quota appropriately.
1056 if (!data_to_send_next_) 1065 if (!data_to_send_next_)
1057 data_to_send_next_.reset(new SendBuffer); 1066 data_to_send_next_.reset(new SendBuffer);
1058 data_to_send_next_->AddFrame(std::move(frame)); 1067 data_to_send_next_->AddFrame(std::move(frame));
1059 return CHANNEL_ALIVE; 1068 return CHANNEL_ALIVE;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 const size_t payload_length = kWebSocketCloseCodeLength + reason.length(); 1111 const size_t payload_length = kWebSocketCloseCodeLength + reason.length();
1103 body = new IOBuffer(payload_length); 1112 body = new IOBuffer(payload_length);
1104 size = payload_length; 1113 size = payload_length;
1105 base::WriteBigEndian(body->data(), code); 1114 base::WriteBigEndian(body->data(), code);
1106 static_assert(sizeof(code) == kWebSocketCloseCodeLength, 1115 static_assert(sizeof(code) == kWebSocketCloseCodeLength,
1107 "they should both be two"); 1116 "they should both be two");
1108 std::copy( 1117 std::copy(
1109 reason.begin(), reason.end(), body->data() + kWebSocketCloseCodeLength); 1118 reason.begin(), reason.end(), body->data() + kWebSocketCloseCodeLength);
1110 } 1119 }
1111 if (SendFrameFromIOBuffer( 1120 if (SendFrameFromIOBuffer(
1112 true, WebSocketFrameHeader::kOpCodeClose, body, size) == 1121 true, WebSocketFrameHeader::kOpCodeClose, std::move(body), size) ==
1113 CHANNEL_DELETED) 1122 CHANNEL_DELETED)
1114 return CHANNEL_DELETED; 1123 return CHANNEL_DELETED;
1115 return CHANNEL_ALIVE; 1124 return CHANNEL_ALIVE;
1116 } 1125 }
1117 1126
1118 bool WebSocketChannel::ParseClose(const scoped_refptr<IOBuffer>& buffer, 1127 bool WebSocketChannel::ParseClose(scoped_refptr<IOBuffer> buffer,
1119 uint64_t size, 1128 uint64_t size,
1120 uint16_t* code, 1129 uint16_t* code,
1121 std::string* reason, 1130 std::string* reason,
1122 std::string* message) { 1131 std::string* message) {
1123 reason->clear(); 1132 reason->clear();
1124 if (size < kWebSocketCloseCodeLength) { 1133 if (size < kWebSocketCloseCodeLength) {
1125 if (size == 0U) { 1134 if (size == 0U) {
1126 *code = kWebSocketErrorNoStatusReceived; 1135 *code = kWebSocketErrorNoStatusReceived;
1127 return true; 1136 return true;
1128 } 1137 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 } 1190 }
1182 1191
1183 void WebSocketChannel::CloseTimeout() { 1192 void WebSocketChannel::CloseTimeout() {
1184 stream_->Close(); 1193 stream_->Close();
1185 SetState(CLOSED); 1194 SetState(CLOSED);
1186 DoDropChannel(false, kWebSocketErrorAbnormalClosure, ""); 1195 DoDropChannel(false, kWebSocketErrorAbnormalClosure, "");
1187 // |this| has been deleted. 1196 // |this| has been deleted.
1188 } 1197 }
1189 1198
1190 } // namespace net 1199 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698