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

Side by Side Diff: chrome/browser/extensions/api/cast_channel/cast_socket.cc

Issue 35443002: Update CastSocket connection flow to check for receiver credentials. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 2 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 "chrome/browser/extensions/api/cast_channel/cast_socket.h" 5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/sys_byteorder.h" 13 #include "base/sys_byteorder.h"
14 #include "chrome/browser/extensions/api/cast_channel/cast_auth_util.h"
14 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" 15 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h"
15 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" 16 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h"
16 #include "net/base/address_list.h" 17 #include "net/base/address_list.h"
17 #include "net/base/host_port_pair.h" 18 #include "net/base/host_port_pair.h"
18 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h" 20 #include "net/base/net_util.h"
20 #include "net/cert/cert_verifier.h" 21 #include "net/cert/cert_verifier.h"
21 #include "net/cert/x509_certificate.h" 22 #include "net/cert/x509_certificate.h"
22 #include "net/http/transport_security_state.h" 23 #include "net/http/transport_security_state.h"
23 #include "net/socket/client_socket_factory.h" 24 #include "net/socket/client_socket_factory.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() { 59 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() {
59 return &g_factory.Get(); 60 return &g_factory.Get();
60 } 61 }
61 62
62 namespace api { 63 namespace api {
63 namespace cast_channel { 64 namespace cast_channel {
64 65
65 const uint32 kMaxMessageSize = 65536; 66 const uint32 kMaxMessageSize = 65536;
66 67
67 CastSocket::CastSocket(const std::string& owner_extension_id, 68 CastSocket::CastSocket(const std::string& owner_extension_id,
68 const GURL& url, CastSocket::Delegate* delegate, 69 const GURL& url,
70 CastSocket::Delegate* delegate,
69 net::NetLog* net_log) : 71 net::NetLog* net_log) :
70 ApiResource(owner_extension_id), 72 ApiResource(owner_extension_id),
71 channel_id_(0), 73 channel_id_(0),
72 url_(url), 74 url_(url),
73 delegate_(delegate), 75 delegate_(delegate),
74 is_secure_(false), 76 auth_required_(false),
75 error_state_(CHANNEL_ERROR_NONE), 77 error_state_(CHANNEL_ERROR_NONE),
76 ready_state_(READY_STATE_NONE), 78 ready_state_(READY_STATE_NONE),
77 write_callback_pending_(false), 79 write_callback_pending_(false),
78 read_callback_pending_(false), 80 read_callback_pending_(false),
79 current_message_size_(0), 81 current_message_size_(0),
80 net_log_(net_log), 82 net_log_(net_log),
81 next_state_(CONN_STATE_NONE) { 83 next_state_(CONN_STATE_NONE) {
82 DCHECK(net_log_); 84 DCHECK(net_log_);
83 net_log_source_.type = net::NetLog::SOURCE_SOCKET; 85 net_log_source_.type = net::NetLog::SOURCE_SOCKET;
84 net_log_source_.id = net_log_->NextID(); 86 net_log_source_.id = net_log_->NextID();
85 87
86 // We reuse these buffers for each message. 88 // We reuse these buffers for each message.
87 header_read_buffer_ = new net::GrowableIOBuffer(); 89 header_read_buffer_ = new net::GrowableIOBuffer();
88 header_read_buffer_->SetCapacity(kMessageHeaderSize); 90 header_read_buffer_->SetCapacity(kMessageHeaderSize);
89 body_read_buffer_ = new net::GrowableIOBuffer(); 91 body_read_buffer_ = new net::GrowableIOBuffer();
90 body_read_buffer_->SetCapacity(kMaxMessageSize); 92 body_read_buffer_->SetCapacity(kMaxMessageSize);
91 current_read_buffer_ = header_read_buffer_; 93 current_read_buffer_ = header_read_buffer_;
92 } 94 }
93 95
94 CastSocket::~CastSocket() { } 96 CastSocket::~CastSocket() { }
95 97
96 const GURL& CastSocket::url() const { 98 const GURL& CastSocket::url() const {
97 return url_; 99 return url_;
98 } 100 }
99 101
100 bool CastSocket::ExtractPeerCert(std::string* cert) {
101 CHECK(peer_cert_.empty());
102 net::SSLInfo ssl_info;
103 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
104 return false;
105 bool result = net::X509Certificate::GetDEREncoded(
106 ssl_info.cert->os_cert_handle(), cert);
107 if (result)
108 DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
109 return result;
110 }
111
112 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() { 102 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() {
113 net::AddressList addresses(ip_endpoint_); 103 net::AddressList addresses(ip_endpoint_);
114 scoped_ptr<net::TCPClientSocket> tcp_socket( 104 scoped_ptr<net::TCPClientSocket> tcp_socket(
115 new net::TCPClientSocket(addresses, net_log_, net_log_source_)); 105 new net::TCPClientSocket(addresses, net_log_, net_log_source_));
116 // Enable keepalive 106 // Enable keepalive
117 tcp_socket->SetKeepAlive(true, kTcpKeepAliveDelaySecs); 107 tcp_socket->SetKeepAlive(true, kTcpKeepAliveDelaySecs);
118 return tcp_socket.Pass(); 108 return tcp_socket.Pass();
119 } 109 }
120 110
121 scoped_ptr<net::SSLClientSocket> CastSocket::CreateSslSocket() { 111 scoped_ptr<net::SSLClientSocket> CastSocket::CreateSslSocket() {
(...skipping 17 matching lines...) Expand all
139 129
140 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle); 130 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle);
141 connection->SetSocket(tcp_socket_.PassAs<net::StreamSocket>()); 131 connection->SetSocket(tcp_socket_.PassAs<net::StreamSocket>());
142 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint( 132 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint(
143 ip_endpoint_); 133 ip_endpoint_);
144 134
145 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( 135 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket(
146 connection.Pass(), host_and_port, ssl_config, context); 136 connection.Pass(), host_and_port, ssl_config, context);
147 } 137 }
148 138
139 bool CastSocket::ExtractPeerCert(std::string* cert) {
140 CHECK(cert);
141 CHECK(peer_cert_.empty());
Ryan Sleevi 2013/10/23 19:14:05 These both seem like they should be DCHECKs. CHEC
Munjal (Google) 2013/10/23 20:08:56 Done.
Munjal (Google) 2013/10/23 20:08:56 Done.
142 net::SSLInfo ssl_info;
143 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
144 return false;
145 bool result = net::X509Certificate::GetDEREncoded(
146 ssl_info.cert->os_cert_handle(), cert);
147 if (result)
148 DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
149 return result;
150 }
151
152 int CastSocket::SendAuthChallenge() {
153 CastMessage challenge_message;
154 CreateAuthChallengeMessage(&challenge_message);
155 return SendMessageInternal(
156 challenge_message,
157 base::Bind(&CastSocket::OnChallengeEvent, AsWeakPtr()));
158 }
159
160 int CastSocket::ReadAuthChallengeReply() {
161 return ReadData();
162 }
163
149 void CastSocket::OnConnectComplete(int result) { 164 void CastSocket::OnConnectComplete(int result) {
150 int rv = DoConnectLoop(result); 165 int rv = DoConnectLoop(result);
151 if (rv != net::ERR_IO_PENDING) 166 if (rv != net::ERR_IO_PENDING)
152 DoConnectCallback(rv); 167 DoConnectCallback(rv);
153 } 168 }
154 169
170 void CastSocket::OnChallengeEvent(int result) {
171 int rv = DoConnectLoop(result);
172 if (rv != net::ERR_IO_PENDING)
173 DoConnectCallback(rv);
174 }
175
155 void CastSocket::Connect(const net::CompletionCallback& callback) { 176 void CastSocket::Connect(const net::CompletionCallback& callback) {
156 DCHECK(CalledOnValidThread()); 177 DCHECK(CalledOnValidThread());
157 int result = net::ERR_CONNECTION_FAILED; 178 int result = net::ERR_CONNECTION_FAILED;
158 DVLOG(1) << "Connect readyState = " << ready_state_; 179 DVLOG(1) << "Connect readyState = " << ready_state_;
159 if (ready_state_ != READY_STATE_NONE) { 180 if (ready_state_ != READY_STATE_NONE) {
160 callback.Run(result); 181 callback.Run(result);
161 return; 182 return;
162 } 183 }
163 if (!ParseChannelUrl(url_)) { 184 if (!ParseChannelUrl(url_)) {
164 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR); 185 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR);
165 // TODO(mfoltz): Signal channel errors via |callback|
166 callback.Run(result); 186 callback.Run(result);
167 return; 187 return;
168 } 188 }
169 connect_callback_ = callback; 189 connect_callback_ = callback;
170 next_state_ = CONN_STATE_TCP_CONNECT; 190 next_state_ = CONN_STATE_TCP_CONNECT;
171 int rv = DoConnectLoop(net::OK); 191 int rv = DoConnectLoop(net::OK);
172 if (rv != net::ERR_IO_PENDING) 192 if (rv != net::ERR_IO_PENDING)
173 DoConnectCallback(rv); 193 DoConnectCallback(rv);
174 } 194 }
175 195
(...skipping 22 matching lines...) Expand all
198 case CONN_STATE_TCP_CONNECT_COMPLETE: 218 case CONN_STATE_TCP_CONNECT_COMPLETE:
199 rv = DoTcpConnectComplete(rv); 219 rv = DoTcpConnectComplete(rv);
200 break; 220 break;
201 case CONN_STATE_SSL_CONNECT: 221 case CONN_STATE_SSL_CONNECT:
202 DCHECK_EQ(net::OK, rv); 222 DCHECK_EQ(net::OK, rv);
203 rv = DoSslConnect(); 223 rv = DoSslConnect();
204 break; 224 break;
205 case CONN_STATE_SSL_CONNECT_COMPLETE: 225 case CONN_STATE_SSL_CONNECT_COMPLETE:
206 rv = DoSslConnectComplete(rv); 226 rv = DoSslConnectComplete(rv);
207 break; 227 break;
228 case CONN_STATE_AUTH_CHALLENGE_SEND:
229 rv = DoAuthChallengeSend();
230 break;
231 case CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE:
232 rv = DoAuthChallengeSendComplete(rv);
233 break;
234 case CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE:
235 rv = DoAuthChallengeReplyComplete(rv);
236 break;
237
208 default: 238 default:
209 NOTREACHED() << "BUG in CastSocket state machine code"; 239 NOTREACHED() << "BUG in CastSocket state machine code";
210 break; 240 break;
211 } 241 }
212 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE); 242 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE);
213 // Get out of the loop either when: 243 // Get out of the loop either when:
214 // a. A network operation is pending, OR 244 // a. A network operation is pending, OR
215 // b. The Do* method called did not change state 245 // b. The Do* method called did not change state
216 246
217 return rv; 247 return rv;
(...skipping 13 matching lines...) Expand all
231 } 261 }
232 262
233 int CastSocket::DoSslConnect() { 263 int CastSocket::DoSslConnect() {
234 next_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; 264 next_state_ = CONN_STATE_SSL_CONNECT_COMPLETE;
235 socket_ = CreateSslSocket(); 265 socket_ = CreateSslSocket();
236 return socket_->Connect( 266 return socket_->Connect(
237 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr())); 267 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr()));
238 } 268 }
239 269
240 int CastSocket::DoSslConnectComplete(int result) { 270 int CastSocket::DoSslConnectComplete(int result) {
241 // TODO(mfoltz,munjal): Authenticate the channel if is_secure_ == true.
242 if (result == net::ERR_CERT_AUTHORITY_INVALID && 271 if (result == net::ERR_CERT_AUTHORITY_INVALID &&
243 peer_cert_.empty() && 272 peer_cert_.empty() &&
244 ExtractPeerCert(&peer_cert_)) { 273 ExtractPeerCert(&peer_cert_)) {
245 next_state_ = CONN_STATE_TCP_CONNECT; 274 next_state_ = CONN_STATE_TCP_CONNECT;
275 } else if (result == net::OK && auth_required_) {
276 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND;
246 } 277 }
247 return result; 278 return result;
248 } 279 }
249 280
281 int CastSocket::DoAuthChallengeSend() {
282 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE;
283 return SendAuthChallenge();
Ryan Sleevi 2013/10/23 19:14:05 BUG: You're still potentially reentering the loop
Munjal (Google) 2013/10/23 20:08:56 Done. Good catch.
284 }
285
286 int CastSocket::DoAuthChallengeSendComplete(int result) {
287 if (result != net::OK)
288 return result;
289 next_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE;
290 return ReadAuthChallengeReply();
291 }
292
293 int CastSocket::DoAuthChallengeReplyComplete(int result) {
294 if (result != net::OK)
295 return result;
296 if (VerifyChallengeReply())
297 return net::OK;
298 else
299 return net::ERR_FAILED;
Ryan Sleevi 2013/10/23 19:14:05 style suggestion: if (!VerifyChallengeReply())
Munjal (Google) 2013/10/23 20:08:56 Done.
300 }
301
302 bool CastSocket::VerifyChallengeReply() {
303 return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_);
304 }
305
250 void CastSocket::DoConnectCallback(int result) { 306 void CastSocket::DoConnectCallback(int result) {
251 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; 307 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
252 error_state_ = (result == net::OK) ? 308 error_state_ = (result == net::OK) ?
253 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; 309 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR;
254 base::ResetAndReturn(&connect_callback_).Run(result); 310 base::ResetAndReturn(&connect_callback_).Run(result);
255 if (result == net::OK) 311 if (result == net::OK)
256 ReadData(); 312 ReadData();
257 } 313 }
258 314
259 void CastSocket::Close(const net::CompletionCallback& callback) { 315 void CastSocket::Close(const net::CompletionCallback& callback) {
260 DCHECK(CalledOnValidThread()); 316 DCHECK(CalledOnValidThread());
261 DVLOG(1) << "Close ReadyState = " << ready_state_; 317 DVLOG(1) << "Close ReadyState = " << ready_state_;
262 tcp_socket_.reset(NULL); 318 tcp_socket_.reset(NULL);
263 socket_.reset(NULL); 319 socket_.reset(NULL);
264 cert_verifier_.reset(NULL); 320 cert_verifier_.reset(NULL);
265 transport_security_state_.reset(NULL); 321 transport_security_state_.reset(NULL);
266 ready_state_ = READY_STATE_CLOSED; 322 ready_state_ = READY_STATE_CLOSED;
267 callback.Run(net::OK); 323 callback.Run(net::OK);
268 } 324 }
269 325
270 void CastSocket::SendMessage(const MessageInfo& message, 326 void CastSocket::SendMessage(const MessageInfo& message,
271 const net::CompletionCallback& callback) { 327 const net::CompletionCallback& callback) {
272 DCHECK(CalledOnValidThread()); 328 DCHECK(CalledOnValidThread());
273 DVLOG(1) << "Send ReadyState " << ready_state_; 329 DVLOG(1) << "Send ReadyState " << ready_state_;
274 int result = net::ERR_FAILED; 330 int result = net::ERR_FAILED;
275 if (ready_state_ != READY_STATE_OPEN) { 331 if (ready_state_ != READY_STATE_OPEN) {
276 callback.Run(result); 332 callback.Run(result);
277 return; 333 return;
278 } 334 }
279 WriteRequest write_request(callback);
280 CastMessage message_proto; 335 CastMessage message_proto;
281 if (!MessageInfoToCastMessage(message, &message_proto) || 336 if (!MessageInfoToCastMessage(message, &message_proto)) {
282 !write_request.SetContent(message_proto)) {
283 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE); 337 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
284 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the 338 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the
285 // caller. 339 // caller.
286 callback.Run(net::OK); 340 callback.Run(net::OK);
287 return; 341 return;
288 } 342 }
289 write_queue_.push(write_request); 343 SendMessageInternal(message_proto, callback);
290 WriteData();
291 } 344 }
292 345
293 void CastSocket::WriteData() { 346 int CastSocket::SendMessageInternal(const CastMessage& message_proto,
347 const net::CompletionCallback& callback) {
348 WriteRequest write_request(callback);
349 if (!write_request.SetContent(message_proto)) {
350 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
351 callback.Run(net::OK);
Ryan Sleevi 2013/10/23 19:14:05 is net::OK really the right error to run the callb
Munjal (Google) 2013/10/23 20:08:56 Done.
352 return net::ERR_FAILED;
353 }
354 write_queue_.push(write_request);
355 return WriteData();
356 }
357
358 int CastSocket::WriteData() {
294 DCHECK(CalledOnValidThread()); 359 DCHECK(CalledOnValidThread());
295 DVLOG(1) << "WriteData q = " << write_queue_.size(); 360 DVLOG(1) << "WriteData q = " << write_queue_.size();
296 if (write_queue_.empty() || write_callback_pending_) 361 if (write_queue_.empty() || write_callback_pending_)
297 return; 362 return net::ERR_FAILED;
298 363
299 WriteRequest& request = write_queue_.front(); 364 WriteRequest& request = write_queue_.front();
300 if (ready_state_ != READY_STATE_OPEN) {
301 request.callback.Run(net::ERR_FAILED);
302 return;
303 }
304 365
305 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() << 366 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() <<
306 " bytes_written " << request.io_buffer->BytesConsumed(); 367 " bytes_written " << request.io_buffer->BytesConsumed();
307 368
308 write_callback_pending_ = true; 369 write_callback_pending_ = true;
309 int result = socket_->Write( 370 int result = socket_->Write(
310 request.io_buffer.get(), 371 request.io_buffer.get(),
311 request.io_buffer->BytesRemaining(), 372 request.io_buffer->BytesRemaining(),
312 base::Bind(&CastSocket::OnWriteData, AsWeakPtr())); 373 base::Bind(&CastSocket::OnWriteData, AsWeakPtr()));
313 374
314 DVLOG(1) << "WriteData result = " << result;
315
316 if (result != net::ERR_IO_PENDING) 375 if (result != net::ERR_IO_PENDING)
317 OnWriteData(result); 376 OnWriteData(result);
377
378 return result;
318 } 379 }
319 380
320 void CastSocket::OnWriteData(int result) { 381 void CastSocket::OnWriteData(int result) {
321 DCHECK(CalledOnValidThread()); 382 DCHECK(CalledOnValidThread());
322 DVLOG(1) << "OnWriteComplete result = " << result; 383 DVLOG(1) << "OnWriteComplete result = " << result;
323 DCHECK(write_callback_pending_); 384 DCHECK(write_callback_pending_);
324 DCHECK(!write_queue_.empty()); 385 DCHECK(!write_queue_.empty());
325 write_callback_pending_ = false; 386 write_callback_pending_ = false;
326 WriteRequest& request = write_queue_.front(); 387 WriteRequest& request = write_queue_.front();
327 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer; 388 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer;
(...skipping 23 matching lines...) Expand all
351 412
352 if (result < 0) { 413 if (result < 0) {
353 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 414 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
354 return; 415 return;
355 } 416 }
356 417
357 if (!write_queue_.empty()) 418 if (!write_queue_.empty())
358 WriteData(); 419 WriteData();
359 } 420 }
360 421
361 void CastSocket::ReadData() { 422 int CastSocket::ReadData() {
362 DCHECK(CalledOnValidThread()); 423 DCHECK(CalledOnValidThread());
363 if (!socket_.get() || ready_state_ != READY_STATE_OPEN) { 424 if (!socket_.get())
364 return; 425 return net::ERR_FAILED;
365 }
366 DCHECK(!read_callback_pending_); 426 DCHECK(!read_callback_pending_);
367 read_callback_pending_ = true; 427 read_callback_pending_ = true;
368 // Figure out if we are reading the header or body, and the remaining bytes. 428 // Figure out if we are reading the header or body, and the remaining bytes.
369 uint32 num_bytes_to_read = 0; 429 uint32 num_bytes_to_read = 0;
370 if (header_read_buffer_->RemainingCapacity() > 0) { 430 if (header_read_buffer_->RemainingCapacity() > 0) {
371 current_read_buffer_ = header_read_buffer_; 431 current_read_buffer_ = header_read_buffer_;
372 num_bytes_to_read = header_read_buffer_->RemainingCapacity(); 432 num_bytes_to_read = header_read_buffer_->RemainingCapacity();
373 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize); 433 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize);
374 } else { 434 } else {
375 DCHECK_GT(current_message_size_, 0U); 435 DCHECK_GT(current_message_size_, 0U);
376 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); 436 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset();
377 current_read_buffer_ = body_read_buffer_; 437 current_read_buffer_ = body_read_buffer_;
378 DCHECK_LE(num_bytes_to_read, kMaxMessageSize); 438 DCHECK_LE(num_bytes_to_read, kMaxMessageSize);
379 } 439 }
380 DCHECK_GT(num_bytes_to_read, 0U); 440 DCHECK_GT(num_bytes_to_read, 0U);
381 // We read up to num_bytes_to_read into |current_read_buffer_|. 441 // We read up to num_bytes_to_read into |current_read_buffer_|.
382 int result = socket_->Read( 442 int result = socket_->Read(
383 current_read_buffer_.get(), 443 current_read_buffer_.get(),
384 num_bytes_to_read, 444 num_bytes_to_read,
385 base::Bind(&CastSocket::OnReadData, AsWeakPtr())); 445 base::Bind(&CastSocket::OnReadData, AsWeakPtr()));
386 DVLOG(1) << "ReadData result = " << result; 446 DVLOG(1) << "ReadData result = " << result;
387 if (result > 0) { 447 if (result > 0) {
388 OnReadData(result); 448 OnReadData(result);
389 } else if (result != net::ERR_IO_PENDING) { 449 } else if (result != net::ERR_IO_PENDING) {
390 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 450 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
391 } 451 }
452 return result;
392 } 453 }
393 454
394 void CastSocket::OnReadData(int result) { 455 void CastSocket::OnReadData(int result) {
395 DCHECK(CalledOnValidThread()); 456 DCHECK(CalledOnValidThread());
396 DVLOG(1) << "OnReadData result = " << result << 457 DVLOG(1) << "OnReadData result = " << result
397 " header offset = " << header_read_buffer_->offset() << 458 << " header offset = " << header_read_buffer_->offset()
398 " body offset = " << body_read_buffer_->offset(); 459 << " body offset = " << body_read_buffer_->offset();
399 read_callback_pending_ = false; 460 read_callback_pending_ = false;
400 if (result <= 0) { 461 if (result <= 0) {
401 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 462 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
402 return; 463 return;
403 } 464 }
404 // We read some data. Move the offset in the current buffer forward. 465 // We read some data. Move the offset in the current buffer forward.
405 DCHECK_LE(current_read_buffer_->offset() + result, 466 DCHECK_LE(current_read_buffer_->offset() + result,
406 current_read_buffer_->capacity()); 467 current_read_buffer_->capacity());
407 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); 468 current_read_buffer_->set_offset(current_read_buffer_->offset() + result);
408 469
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 512
452 bool CastSocket::ParseMessageFromBody() { 513 bool CastSocket::ParseMessageFromBody() {
453 DCHECK(CalledOnValidThread()); 514 DCHECK(CalledOnValidThread());
454 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), 515 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()),
455 current_message_size_); 516 current_message_size_);
456 CastMessage message_proto; 517 CastMessage message_proto;
457 if (!message_proto.ParseFromArray( 518 if (!message_proto.ParseFromArray(
458 body_read_buffer_->StartOfBuffer(), 519 body_read_buffer_->StartOfBuffer(),
459 current_message_size_)) 520 current_message_size_))
460 return false; 521 return false;
461 DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto); 522 DVLOG(1) << "Parsed message " << CastMessageToString(message_proto);
462 if (delegate_) { 523 // If the message is an auth message then we handle it internally.
524 if (IsAuthMessage(message_proto)) {
525 challenge_reply_.reset(new CastMessage(message_proto));
526 OnChallengeEvent(net::OK);
527 } else if (delegate_) {
463 MessageInfo message; 528 MessageInfo message;
464 if (!CastMessageToMessageInfo(message_proto, &message)) 529 if (!CastMessageToMessageInfo(message_proto, &message))
465 return false; 530 return false;
466 delegate_->OnMessage(this, message); 531 delegate_->OnMessage(this, message);
467 } 532 }
468 return true; 533 return true;
469 } 534 }
470 535
471 // static 536 // static
472 bool CastSocket::Serialize(const CastMessage& message_proto, 537 bool CastSocket::Serialize(const CastMessage& message_proto,
(...skipping 16 matching lines...) Expand all
489 socket_.reset(NULL); 554 socket_.reset(NULL);
490 ready_state_ = READY_STATE_CLOSED; 555 ready_state_ = READY_STATE_CLOSED;
491 error_state_ = error; 556 error_state_ = error;
492 if (delegate_) 557 if (delegate_)
493 delegate_->OnError(this, error); 558 delegate_->OnError(this, error);
494 } 559 }
495 560
496 bool CastSocket::ParseChannelUrl(const GURL& url) { 561 bool CastSocket::ParseChannelUrl(const GURL& url) {
497 DVLOG(1) << "url = " + url.spec(); 562 DVLOG(1) << "url = " + url.spec();
498 if (url.SchemeIs(kCastInsecureScheme)) { 563 if (url.SchemeIs(kCastInsecureScheme)) {
499 is_secure_ = false; 564 auth_required_ = false;
500 } else if (url.SchemeIs(kCastSecureScheme)) { 565 } else if (url.SchemeIs(kCastSecureScheme)) {
501 is_secure_ = true; 566 auth_required_ = true;
502 } else { 567 } else {
503 return false; 568 return false;
504 } 569 }
505 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes? 570 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes?
506 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? 571 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets?
507 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local 572 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local
508 // networks 573 // networks
509 const std::string& path = url.path(); 574 const std::string& path = url.path();
510 // Shortest possible: //A:B 575 // Shortest possible: //A:B
511 if (path.size() < 5) { 576 if (path.size() < 5) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), 642 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data),
578 message_data.size()); 643 message_data.size());
579 return true; 644 return true;
580 } 645 }
581 646
582 CastSocket::WriteRequest::~WriteRequest() { } 647 CastSocket::WriteRequest::~WriteRequest() { }
583 648
584 } // namespace cast_channel 649 } // namespace cast_channel
585 } // namespace api 650 } // namespace api
586 } // namespace extensions 651 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698