Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_socket.h" | 5 #include "extensions/browser/api/cast_channel/cast_socket.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 net_log_source_.id = net_log_->NextID(); | 92 net_log_source_.id = net_log_->NextID(); |
| 93 | 93 |
| 94 // Reuse these buffers for each message. | 94 // Reuse these buffers for each message. |
| 95 header_read_buffer_ = new net::GrowableIOBuffer(); | 95 header_read_buffer_ = new net::GrowableIOBuffer(); |
| 96 header_read_buffer_->SetCapacity(MessageHeader::header_size()); | 96 header_read_buffer_->SetCapacity(MessageHeader::header_size()); |
| 97 body_read_buffer_ = new net::GrowableIOBuffer(); | 97 body_read_buffer_ = new net::GrowableIOBuffer(); |
| 98 body_read_buffer_->SetCapacity(MessageHeader::max_message_size()); | 98 body_read_buffer_->SetCapacity(MessageHeader::max_message_size()); |
| 99 current_read_buffer_ = header_read_buffer_; | 99 current_read_buffer_ = header_read_buffer_; |
| 100 } | 100 } |
| 101 | 101 |
| 102 CastSocket::~CastSocket() { } | 102 CastSocket::~CastSocket() { |
| 103 CloseInternal(); | |
| 104 } | |
| 103 | 105 |
| 104 ReadyState CastSocket::ready_state() const { | 106 ReadyState CastSocket::ready_state() const { |
| 105 return ready_state_; | 107 return ready_state_; |
| 106 } | 108 } |
| 107 | 109 |
| 108 ChannelError CastSocket::error_state() const { | 110 ChannelError CastSocket::error_state() const { |
| 109 return error_state_; | 111 return error_state_; |
| 110 } | 112 } |
| 111 | 113 |
| 112 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() { | 114 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 DCHECK(CalledOnValidThread()); | 171 DCHECK(CalledOnValidThread()); |
| 170 VLOG_WITH_CONNECTION(1) << "Connect readyState = " << ready_state_; | 172 VLOG_WITH_CONNECTION(1) << "Connect readyState = " << ready_state_; |
| 171 if (ready_state_ != READY_STATE_NONE) { | 173 if (ready_state_ != READY_STATE_NONE) { |
| 172 callback.Run(net::ERR_CONNECTION_FAILED); | 174 callback.Run(net::ERR_CONNECTION_FAILED); |
| 173 return; | 175 return; |
| 174 } | 176 } |
| 175 ready_state_ = READY_STATE_CONNECTING; | 177 ready_state_ = READY_STATE_CONNECTING; |
| 176 connect_callback_ = callback; | 178 connect_callback_ = callback; |
| 177 connect_state_ = CONN_STATE_TCP_CONNECT; | 179 connect_state_ = CONN_STATE_TCP_CONNECT; |
| 178 if (connect_timeout_.InMicroseconds() > 0) { | 180 if (connect_timeout_.InMicroseconds() > 0) { |
| 179 GetTimer()->Start( | 181 DCHECK(cancel_connect_callback_.is_null()); |
| 180 FROM_HERE, | 182 cancel_connect_callback_ = base::Bind(&CastSocket::CancelConnect, |
| 181 connect_timeout_, | 183 base::Unretained(this)); |
| 182 base::Bind(&CastSocket::CancelConnect, AsWeakPtr())); | 184 GetTimer()->Start(FROM_HERE, connect_timeout_, cancel_connect_callback_); |
| 183 } | 185 } |
| 184 DoConnectLoop(net::OK); | 186 DoConnectLoop(net::OK); |
| 185 } | 187 } |
| 186 | 188 |
| 187 void CastSocket::PostTaskToStartConnectLoop(int result) { | 189 void CastSocket::PostTaskToStartConnectLoop(int result) { |
| 188 DCHECK(CalledOnValidThread()); | 190 DCHECK(CalledOnValidThread()); |
| 189 base::MessageLoop::current()->PostTask( | 191 DCHECK(connect_loop_callback_.is_null()); |
| 190 FROM_HERE, | 192 connect_loop_callback_ = base::Bind(&CastSocket::DoConnectLoop, |
| 191 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr(), result)); | 193 base::Unretained(this), |
| 194 result); | |
| 195 base::MessageLoop::current()->PostTask(FROM_HERE, connect_loop_callback_); | |
|
Kevin M
2014/07/28 22:08:16
Should this be turned into PostNonNestableTask now
Wez
2014/07/28 23:14:56
PostNonNestableTask() isn't required here, since w
Wez
2014/07/28 23:14:56
This will blow up if PostTaskToStartConnectLoop()
mark a. foltz
2014/07/29 00:16:24
So Reset()-ing the callback in the dtor is a no-op
mark a. foltz
2014/07/29 00:16:25
Acknowledged.
Wez
2014/07/29 00:41:25
base::Closure is ref-counted, so when you message_
| |
| 192 } | 196 } |
| 193 | 197 |
| 194 void CastSocket::CancelConnect() { | 198 void CastSocket::CancelConnect() { |
| 195 DCHECK(CalledOnValidThread()); | 199 DCHECK(CalledOnValidThread()); |
| 196 // Stop all pending connection setup tasks and report back to the client. | 200 // Stop all pending connection setup tasks and report back to the client. |
| 197 is_canceled_ = true; | 201 is_canceled_ = true; |
| 198 VLOG_WITH_CONNECTION(1) << "Timeout while establishing a connection."; | 202 VLOG_WITH_CONNECTION(1) << "Timeout while establishing a connection."; |
| 199 DoConnectCallback(net::ERR_TIMED_OUT); | 203 DoConnectCallback(net::ERR_TIMED_OUT); |
| 200 } | 204 } |
| 201 | 205 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 if (rv != net::ERR_IO_PENDING) { | 258 if (rv != net::ERR_IO_PENDING) { |
| 255 GetTimer()->Stop(); | 259 GetTimer()->Stop(); |
| 256 DoConnectCallback(rv); | 260 DoConnectCallback(rv); |
| 257 } | 261 } |
| 258 } | 262 } |
| 259 | 263 |
| 260 int CastSocket::DoTcpConnect() { | 264 int CastSocket::DoTcpConnect() { |
| 261 VLOG_WITH_CONNECTION(1) << "DoTcpConnect"; | 265 VLOG_WITH_CONNECTION(1) << "DoTcpConnect"; |
| 262 connect_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; | 266 connect_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; |
| 263 tcp_socket_ = CreateTcpSocket(); | 267 tcp_socket_ = CreateTcpSocket(); |
| 268 DCHECK(connect_loop_callback_.is_null()); | |
| 264 return tcp_socket_->Connect( | 269 return tcp_socket_->Connect( |
| 265 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); | 270 base::Bind(&CastSocket::DoConnectLoop, base::Unretained(this))); |
| 266 } | 271 } |
| 267 | 272 |
| 268 int CastSocket::DoTcpConnectComplete(int result) { | 273 int CastSocket::DoTcpConnectComplete(int result) { |
| 269 VLOG_WITH_CONNECTION(1) << "DoTcpConnectComplete: " << result; | 274 VLOG_WITH_CONNECTION(1) << "DoTcpConnectComplete: " << result; |
| 270 if (result == net::OK) { | 275 if (result == net::OK) { |
| 271 // Enable TCP protocol-level keep-alive. | 276 // Enable TCP protocol-level keep-alive. |
| 272 bool result = tcp_socket_->SetKeepAlive(true, kTcpKeepAliveDelaySecs); | 277 bool result = tcp_socket_->SetKeepAlive(true, kTcpKeepAliveDelaySecs); |
| 273 LOG_IF(WARNING, !result) << "Failed to SetKeepAlive."; | 278 LOG_IF(WARNING, !result) << "Failed to SetKeepAlive."; |
| 274 connect_state_ = CONN_STATE_SSL_CONNECT; | 279 connect_state_ = CONN_STATE_SSL_CONNECT; |
| 275 } | 280 } |
| 276 return result; | 281 return result; |
| 277 } | 282 } |
| 278 | 283 |
| 279 int CastSocket::DoSslConnect() { | 284 int CastSocket::DoSslConnect() { |
| 280 VLOG_WITH_CONNECTION(1) << "DoSslConnect"; | 285 VLOG_WITH_CONNECTION(1) << "DoSslConnect"; |
| 281 connect_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; | 286 connect_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; |
| 282 socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>()); | 287 socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>()); |
| 288 DCHECK(connect_loop_callback_.is_null()); | |
| 283 return socket_->Connect( | 289 return socket_->Connect( |
| 284 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); | 290 base::Bind(&CastSocket::DoConnectLoop, base::Unretained(this))); |
| 285 } | 291 } |
| 286 | 292 |
| 287 int CastSocket::DoSslConnectComplete(int result) { | 293 int CastSocket::DoSslConnectComplete(int result) { |
| 288 VLOG_WITH_CONNECTION(1) << "DoSslConnectComplete: " << result; | 294 VLOG_WITH_CONNECTION(1) << "DoSslConnectComplete: " << result; |
| 289 if (result == net::ERR_CERT_AUTHORITY_INVALID && | 295 if (result == net::ERR_CERT_AUTHORITY_INVALID && |
| 290 peer_cert_.empty() && ExtractPeerCert(&peer_cert_)) { | 296 peer_cert_.empty() && ExtractPeerCert(&peer_cert_)) { |
| 291 connect_state_ = CONN_STATE_TCP_CONNECT; | 297 connect_state_ = CONN_STATE_TCP_CONNECT; |
| 292 } else if (result == net::OK && | 298 } else if (result == net::OK && |
| 293 channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) { | 299 channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) { |
| 294 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND; | 300 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND; |
| 295 } | 301 } |
| 296 return result; | 302 return result; |
| 297 } | 303 } |
| 298 | 304 |
| 299 int CastSocket::DoAuthChallengeSend() { | 305 int CastSocket::DoAuthChallengeSend() { |
| 300 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSend"; | 306 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSend"; |
| 301 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE; | 307 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE; |
| 302 CastMessage challenge_message; | 308 CastMessage challenge_message; |
| 303 CreateAuthChallengeMessage(&challenge_message); | 309 CreateAuthChallengeMessage(&challenge_message); |
| 304 VLOG_WITH_CONNECTION(1) << "Sending challenge: " | 310 VLOG_WITH_CONNECTION(1) << "Sending challenge: " |
| 305 << CastMessageToString(challenge_message); | 311 << CastMessageToString(challenge_message); |
| 306 // Post a task to send auth challenge so that DoWriteLoop is not nested inside | 312 // Post a task to send auth challenge so that DoWriteLoop is not nested inside |
| 307 // DoConnectLoop. This is not strictly necessary but keeps the write loop | 313 // DoConnectLoop. This is not strictly necessary but keeps the write loop |
| 308 // code decoupled from connect loop code. | 314 // code decoupleld from connect loop code. |
|
Kevin M
2014/07/28 22:08:16
typo
mark a. foltz
2014/07/29 00:16:24
Done.
| |
| 309 base::MessageLoop::current()->PostTask( | 315 DCHECK(connect_loop_callback_.is_null()); |
| 310 FROM_HERE, | 316 DCHECK(send_auth_challenge_callback_.is_null()); |
| 311 base::Bind(&CastSocket::SendCastMessageInternal, | 317 send_auth_challenge_callback_ = |
| 312 AsWeakPtr(), | 318 base::Bind(&CastSocket::SendCastMessageInternal, |
|
Kevin M
2014/07/28 22:08:16
4 space indentation
mark a. foltz
2014/07/29 00:16:25
Done.
| |
| 313 challenge_message, | 319 base::Unretained(this), |
| 314 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr()))); | 320 challenge_message, |
| 321 base::Bind(&CastSocket::DoConnectLoop, | |
| 322 base::Unretained(this))); | |
| 323 base::MessageLoop::current()->PostTask(FROM_HERE, | |
| 324 send_auth_challenge_callback_); | |
|
Wez
2014/07/28 23:14:56
This will blow up, as above.
mark a. foltz
2014/07/29 00:16:25
Acknowledged.
| |
| 315 // Always return IO_PENDING since the result is always asynchronous. | 325 // Always return IO_PENDING since the result is always asynchronous. |
| 316 return net::ERR_IO_PENDING; | 326 return net::ERR_IO_PENDING; |
| 317 } | 327 } |
| 318 | 328 |
| 319 int CastSocket::DoAuthChallengeSendComplete(int result) { | 329 int CastSocket::DoAuthChallengeSendComplete(int result) { |
| 320 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSendComplete: " << result; | 330 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSendComplete: " << result; |
| 321 if (result < 0) | 331 if (result < 0) |
| 322 return result; | 332 return result; |
| 323 connect_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE; | 333 connect_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE; |
| 324 // Post a task to start read loop so that DoReadLoop is not nested inside | 334 // Post a task to start read loop so that DoReadLoop is not nested inside |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 347 } else if (result == net::ERR_TIMED_OUT) { | 357 } else if (result == net::ERR_TIMED_OUT) { |
| 348 error_state_ = CHANNEL_ERROR_CONNECT_TIMEOUT; | 358 error_state_ = CHANNEL_ERROR_CONNECT_TIMEOUT; |
| 349 } else { | 359 } else { |
| 350 error_state_ = CHANNEL_ERROR_CONNECT_ERROR; | 360 error_state_ = CHANNEL_ERROR_CONNECT_ERROR; |
| 351 } | 361 } |
| 352 VLOG_WITH_CONNECTION(1) << "Calling Connect_Callback"; | 362 VLOG_WITH_CONNECTION(1) << "Calling Connect_Callback"; |
| 353 base::ResetAndReturn(&connect_callback_).Run(result); | 363 base::ResetAndReturn(&connect_callback_).Run(result); |
| 354 } | 364 } |
| 355 | 365 |
| 356 void CastSocket::Close(const net::CompletionCallback& callback) { | 366 void CastSocket::Close(const net::CompletionCallback& callback) { |
| 367 CloseInternal(); | |
| 368 callback.Run(net::OK); | |
| 369 // |callback| can delete |this| | |
| 370 } | |
| 371 | |
| 372 void CastSocket::CloseInternal() { | |
| 357 DCHECK(CalledOnValidThread()); | 373 DCHECK(CalledOnValidThread()); |
| 374 if (ready_state_ == READY_STATE_CLOSED) { | |
| 375 return; | |
| 376 } | |
| 358 VLOG_WITH_CONNECTION(1) << "Close ReadyState = " << ready_state_; | 377 VLOG_WITH_CONNECTION(1) << "Close ReadyState = " << ready_state_; |
| 359 tcp_socket_.reset(); | 378 tcp_socket_.reset(); |
| 360 socket_.reset(); | 379 socket_.reset(); |
| 361 cert_verifier_.reset(); | 380 cert_verifier_.reset(); |
| 362 transport_security_state_.reset(); | 381 transport_security_state_.reset(); |
| 382 // Reset callbacks passed into us. Or should we invoke them with an error? | |
|
Kevin M
2014/07/28 22:08:16
Stop the timer?
mark a. foltz
2014/07/29 00:16:24
Done.
| |
| 383 connect_callback_.Reset(); | |
|
Kevin M
2014/07/28 22:08:16
Question: does resetting the callbacks also dequeu
mark a. foltz
2014/07/29 00:16:24
Good question.
| |
| 384 for (; !write_queue_.empty(); write_queue_.pop()) { | |
| 385 write_queue_.front().callback.Reset(); | |
| 386 } | |
| 387 // Reset callbacks that we queued ourselves. | |
| 388 connect_loop_callback_.Reset(); | |
| 389 read_loop_callback_.Reset(); | |
| 390 cancel_connect_callback_.Reset(); | |
| 391 send_auth_challenge_callback_.Reset(); | |
| 363 ready_state_ = READY_STATE_CLOSED; | 392 ready_state_ = READY_STATE_CLOSED; |
| 364 callback.Run(net::OK); | |
| 365 // |callback| can delete |this| | |
| 366 } | 393 } |
| 367 | 394 |
| 368 void CastSocket::SendMessage(const MessageInfo& message, | 395 void CastSocket::SendMessage(const MessageInfo& message, |
| 369 const net::CompletionCallback& callback) { | 396 const net::CompletionCallback& callback) { |
| 370 DCHECK(CalledOnValidThread()); | 397 DCHECK(CalledOnValidThread()); |
| 371 if (ready_state_ != READY_STATE_OPEN) { | 398 if (ready_state_ != READY_STATE_OPEN) { |
| 372 callback.Run(net::ERR_FAILED); | 399 callback.Run(net::ERR_FAILED); |
| 373 return; | 400 return; |
| 374 } | 401 } |
| 375 CastMessage message_proto; | 402 CastMessage message_proto; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 | 474 |
| 448 int CastSocket::DoWrite() { | 475 int CastSocket::DoWrite() { |
| 449 DCHECK(!write_queue_.empty()); | 476 DCHECK(!write_queue_.empty()); |
| 450 WriteRequest& request = write_queue_.front(); | 477 WriteRequest& request = write_queue_.front(); |
| 451 | 478 |
| 452 VLOG_WITH_CONNECTION(2) << "WriteData byte_count = " | 479 VLOG_WITH_CONNECTION(2) << "WriteData byte_count = " |
| 453 << request.io_buffer->size() << " bytes_written " | 480 << request.io_buffer->size() << " bytes_written " |
| 454 << request.io_buffer->BytesConsumed(); | 481 << request.io_buffer->BytesConsumed(); |
| 455 | 482 |
| 456 write_state_ = WRITE_STATE_WRITE_COMPLETE; | 483 write_state_ = WRITE_STATE_WRITE_COMPLETE; |
| 457 | |
| 458 return socket_->Write( | 484 return socket_->Write( |
| 459 request.io_buffer.get(), | 485 request.io_buffer.get(), |
| 460 request.io_buffer->BytesRemaining(), | 486 request.io_buffer->BytesRemaining(), |
| 461 base::Bind(&CastSocket::DoWriteLoop, AsWeakPtr())); | 487 base::Bind(&CastSocket::DoWriteLoop, base::Unretained(this))); |
| 462 } | 488 } |
| 463 | 489 |
| 464 int CastSocket::DoWriteComplete(int result) { | 490 int CastSocket::DoWriteComplete(int result) { |
| 465 DCHECK(!write_queue_.empty()); | 491 DCHECK(!write_queue_.empty()); |
| 466 if (result <= 0) { // NOTE that 0 also indicates an error | 492 if (result <= 0) { // NOTE that 0 also indicates an error |
| 467 error_state_ = CHANNEL_ERROR_SOCKET_ERROR; | 493 error_state_ = CHANNEL_ERROR_SOCKET_ERROR; |
| 468 write_state_ = WRITE_STATE_ERROR; | 494 write_state_ = WRITE_STATE_ERROR; |
| 469 return result == 0 ? net::ERR_FAILED : result; | 495 return result == 0 ? net::ERR_FAILED : result; |
| 470 } | 496 } |
| 471 | 497 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 while (!write_queue_.empty()) { | 545 while (!write_queue_.empty()) { |
| 520 WriteRequest& request = write_queue_.front(); | 546 WriteRequest& request = write_queue_.front(); |
| 521 request.callback.Run(result); | 547 request.callback.Run(result); |
| 522 write_queue_.pop(); | 548 write_queue_.pop(); |
| 523 } | 549 } |
| 524 return net::ERR_FAILED; | 550 return net::ERR_FAILED; |
| 525 } | 551 } |
| 526 | 552 |
| 527 void CastSocket::PostTaskToStartReadLoop() { | 553 void CastSocket::PostTaskToStartReadLoop() { |
| 528 DCHECK(CalledOnValidThread()); | 554 DCHECK(CalledOnValidThread()); |
| 529 base::MessageLoop::current()->PostTask( | 555 DCHECK(read_loop_callback_.is_null()); |
| 530 FROM_HERE, | 556 read_loop_callback_ = base::Bind(&CastSocket::StartReadLoop, |
| 531 base::Bind(&CastSocket::StartReadLoop, AsWeakPtr())); | 557 base::Unretained(this)); |
| 558 base::MessageLoop::current()->PostTask(FROM_HERE, read_loop_callback_); | |
|
Wez
2014/07/28 23:14:56
Boom!
mark a. foltz
2014/07/29 00:16:25
Acknowledged.
| |
| 532 } | 559 } |
| 533 | 560 |
| 534 void CastSocket::StartReadLoop() { | 561 void CastSocket::StartReadLoop() { |
| 535 // Read loop would have already been started if read state is not NONE | 562 // Read loop would have already been started if read state is not NONE |
| 536 if (read_state_ == READ_STATE_NONE) { | 563 if (read_state_ == READ_STATE_NONE) { |
| 537 read_state_ = READ_STATE_READ; | 564 read_state_ = READ_STATE_READ; |
| 538 DoReadLoop(net::OK); | 565 DoReadLoop(net::OK); |
| 539 } | 566 } |
| 540 } | 567 } |
| 541 | 568 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); | 623 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); |
| 597 current_read_buffer_ = body_read_buffer_; | 624 current_read_buffer_ = body_read_buffer_; |
| 598 CHECK_LE(num_bytes_to_read, MessageHeader::max_message_size()); | 625 CHECK_LE(num_bytes_to_read, MessageHeader::max_message_size()); |
| 599 } | 626 } |
| 600 CHECK_GT(num_bytes_to_read, 0U); | 627 CHECK_GT(num_bytes_to_read, 0U); |
| 601 | 628 |
| 602 // Read up to num_bytes_to_read into |current_read_buffer_|. | 629 // Read up to num_bytes_to_read into |current_read_buffer_|. |
| 603 return socket_->Read( | 630 return socket_->Read( |
| 604 current_read_buffer_.get(), | 631 current_read_buffer_.get(), |
| 605 num_bytes_to_read, | 632 num_bytes_to_read, |
| 606 base::Bind(&CastSocket::DoReadLoop, AsWeakPtr())); | 633 base::Bind(&CastSocket::DoReadLoop, base::Unretained(this))); |
| 607 } | 634 } |
| 608 | 635 |
| 609 int CastSocket::DoReadComplete(int result) { | 636 int CastSocket::DoReadComplete(int result) { |
| 610 VLOG_WITH_CONNECTION(2) << "DoReadComplete result = " << result | 637 VLOG_WITH_CONNECTION(2) << "DoReadComplete result = " << result |
| 611 << " header offset = " | 638 << " header offset = " |
| 612 << header_read_buffer_->offset() | 639 << header_read_buffer_->offset() |
| 613 << " body offset = " << body_read_buffer_->offset(); | 640 << " body offset = " << body_read_buffer_->offset(); |
| 614 if (result <= 0) { // 0 means EOF: the peer closed the socket | 641 if (result <= 0) { // 0 means EOF: the peer closed the socket |
| 615 VLOG_WITH_CONNECTION(1) << "Read error, peer closed the socket"; | 642 VLOG_WITH_CONNECTION(1) << "Read error, peer closed the socket"; |
| 616 error_state_ = CHANNEL_ERROR_SOCKET_ERROR; | 643 error_state_ = CHANNEL_ERROR_SOCKET_ERROR; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 return false; | 743 return false; |
| 717 } | 744 } |
| 718 CastSocket::MessageHeader header; | 745 CastSocket::MessageHeader header; |
| 719 header.SetMessageSize(message_size); | 746 header.SetMessageSize(message_size); |
| 720 header.PrependToString(message_data); | 747 header.PrependToString(message_data); |
| 721 return true; | 748 return true; |
| 722 } | 749 } |
| 723 | 750 |
| 724 void CastSocket::CloseWithError(ChannelError error) { | 751 void CastSocket::CloseWithError(ChannelError error) { |
| 725 DCHECK(CalledOnValidThread()); | 752 DCHECK(CalledOnValidThread()); |
| 726 socket_.reset(NULL); | 753 CloseInternal(); |
| 727 ready_state_ = READY_STATE_CLOSED; | |
| 728 error_state_ = error; | 754 error_state_ = error; |
| 729 if (delegate_) | 755 if (delegate_) |
| 730 delegate_->OnError(this, error); | 756 delegate_->OnError(this, error); |
| 731 } | 757 } |
| 732 | 758 |
| 733 std::string CastSocket::CastUrl() const { | 759 std::string CastSocket::CastUrl() const { |
| 734 return ((channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) ? | 760 return ((channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) ? |
| 735 "casts://" : "cast://") + ip_endpoint_.ToString(); | 761 "casts://" : "cast://") + ip_endpoint_.ToString(); |
| 736 } | 762 } |
| 737 | 763 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 749 DCHECK_LT(size, static_cast<size_t>(kuint32max)); | 775 DCHECK_LT(size, static_cast<size_t>(kuint32max)); |
| 750 DCHECK_GT(size, 0U); | 776 DCHECK_GT(size, 0U); |
| 751 message_size = size; | 777 message_size = size; |
| 752 } | 778 } |
| 753 | 779 |
| 754 // TODO(mfoltz): Investigate replacing header serialization with base::Pickle, | 780 // TODO(mfoltz): Investigate replacing header serialization with base::Pickle, |
| 755 // if bit-for-bit compatible. | 781 // if bit-for-bit compatible. |
| 756 void CastSocket::MessageHeader::PrependToString(std::string* str) { | 782 void CastSocket::MessageHeader::PrependToString(std::string* str) { |
| 757 MessageHeader output = *this; | 783 MessageHeader output = *this; |
| 758 output.message_size = base::HostToNet32(message_size); | 784 output.message_size = base::HostToNet32(message_size); |
| 759 size_t header_size = base::checked_cast<size_t,uint32>( | 785 size_t header_size = base::checked_cast<size_t, uint32>( |
| 760 MessageHeader::header_size()); | 786 MessageHeader::header_size()); |
| 761 scoped_ptr<char, base::FreeDeleter> char_array( | 787 scoped_ptr<char, base::FreeDeleter> char_array( |
| 762 static_cast<char*>(malloc(header_size))); | 788 static_cast<char*>(malloc(header_size))); |
| 763 memcpy(char_array.get(), &output, header_size); | 789 memcpy(char_array.get(), &output, header_size); |
| 764 str->insert(0, char_array.get(), header_size); | 790 str->insert(0, char_array.get(), header_size); |
| 765 } | 791 } |
| 766 | 792 |
| 767 // TODO(mfoltz): Investigate replacing header deserialization with base::Pickle, | 793 // TODO(mfoltz): Investigate replacing header deserialization with base::Pickle, |
| 768 // if bit-for-bit compatible. | 794 // if bit-for-bit compatible. |
| 769 void CastSocket::MessageHeader::ReadFromIOBuffer( | 795 void CastSocket::MessageHeader::ReadFromIOBuffer( |
| 770 net::GrowableIOBuffer* buffer, MessageHeader* header) { | 796 net::GrowableIOBuffer* buffer, MessageHeader* header) { |
| 771 uint32 message_size; | 797 uint32 message_size; |
| 772 size_t header_size = base::checked_cast<size_t,uint32>( | 798 size_t header_size = base::checked_cast<size_t, uint32>( |
| 773 MessageHeader::header_size()); | 799 MessageHeader::header_size()); |
| 774 memcpy(&message_size, buffer->StartOfBuffer(), header_size); | 800 memcpy(&message_size, buffer->StartOfBuffer(), header_size); |
| 775 header->message_size = base::NetToHost32(message_size); | 801 header->message_size = base::NetToHost32(message_size); |
| 776 } | 802 } |
| 777 | 803 |
| 778 std::string CastSocket::MessageHeader::ToString() { | 804 std::string CastSocket::MessageHeader::ToString() { |
| 779 return "{message_size: " + base::UintToString(message_size) + "}"; | 805 return "{message_size: " + base::UintToString(message_size) + "}"; |
| 780 } | 806 } |
| 781 | 807 |
| 782 CastSocket::WriteRequest::WriteRequest(const net::CompletionCallback& callback) | 808 CastSocket::WriteRequest::WriteRequest(const net::CompletionCallback& callback) |
| 783 : callback(callback) { } | 809 : callback(callback) { } |
| 784 | 810 |
| 785 bool CastSocket::WriteRequest::SetContent(const CastMessage& message_proto) { | 811 bool CastSocket::WriteRequest::SetContent(const CastMessage& message_proto) { |
| 786 DCHECK(!io_buffer.get()); | 812 DCHECK(!io_buffer.get()); |
| 787 std::string message_data; | 813 std::string message_data; |
| 788 if (!Serialize(message_proto, &message_data)) | 814 if (!Serialize(message_proto, &message_data)) |
| 789 return false; | 815 return false; |
| 790 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), | 816 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), |
| 791 message_data.size()); | 817 message_data.size()); |
| 792 return true; | 818 return true; |
| 793 } | 819 } |
| 794 | 820 |
| 795 CastSocket::WriteRequest::~WriteRequest() { } | 821 CastSocket::WriteRequest::~WriteRequest() { } |
| 796 | 822 |
| 797 } // namespace cast_channel | 823 } // namespace cast_channel |
| 798 } // namespace core_api | 824 } // namespace core_api |
| 799 } // namespace extensions | 825 } // namespace extensions |
| 800 | 826 |
| 801 #undef VLOG_WITH_CONNECTION | 827 #undef VLOG_WITH_CONNECTION |
| OLD | NEW |