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

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, 1 month 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 DCHECK(cert);
141 DCHECK(peer_cert_.empty());
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();
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::ERR_FAILED;
298 return net::OK;
299 }
300
301 bool CastSocket::VerifyChallengeReply() {
302 return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_);
303 }
304
250 void CastSocket::DoConnectCallback(int result) { 305 void CastSocket::DoConnectCallback(int result) {
251 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; 306 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
252 error_state_ = (result == net::OK) ? 307 error_state_ = (result == net::OK) ?
253 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; 308 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR;
254 base::ResetAndReturn(&connect_callback_).Run(result); 309 base::ResetAndReturn(&connect_callback_).Run(result);
255 if (result == net::OK) 310 if (result == net::OK)
256 ReadData(); 311 ReadData();
257 } 312 }
258 313
259 void CastSocket::Close(const net::CompletionCallback& callback) { 314 void CastSocket::Close(const net::CompletionCallback& callback) {
260 DCHECK(CalledOnValidThread()); 315 DCHECK(CalledOnValidThread());
261 DVLOG(1) << "Close ReadyState = " << ready_state_; 316 DVLOG(1) << "Close ReadyState = " << ready_state_;
262 tcp_socket_.reset(NULL); 317 tcp_socket_.reset(NULL);
263 socket_.reset(NULL); 318 socket_.reset(NULL);
264 cert_verifier_.reset(NULL); 319 cert_verifier_.reset(NULL);
265 transport_security_state_.reset(NULL); 320 transport_security_state_.reset(NULL);
266 ready_state_ = READY_STATE_CLOSED; 321 ready_state_ = READY_STATE_CLOSED;
267 callback.Run(net::OK); 322 callback.Run(net::OK);
268 } 323 }
269 324
270 void CastSocket::SendMessage(const MessageInfo& message, 325 void CastSocket::SendMessage(const MessageInfo& message,
271 const net::CompletionCallback& callback) { 326 const net::CompletionCallback& callback) {
272 DCHECK(CalledOnValidThread()); 327 DCHECK(CalledOnValidThread());
273 DVLOG(1) << "Send ReadyState " << ready_state_; 328 DVLOG(1) << "Send ReadyState " << ready_state_;
274 int result = net::ERR_FAILED; 329 int result = net::ERR_FAILED;
275 if (ready_state_ != READY_STATE_OPEN) { 330 if (ready_state_ != READY_STATE_OPEN) {
276 callback.Run(result); 331 callback.Run(result);
277 return; 332 return;
278 } 333 }
279 WriteRequest write_request(callback);
280 CastMessage message_proto; 334 CastMessage message_proto;
281 if (!MessageInfoToCastMessage(message, &message_proto) || 335 if (!MessageInfoToCastMessage(message, &message_proto)) {
282 !write_request.SetContent(message_proto)) {
283 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE); 336 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
284 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the 337 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the
285 // caller. 338 // caller.
286 callback.Run(net::OK); 339 callback.Run(net::OK);
287 return; 340 return;
288 } 341 }
289 write_queue_.push(write_request); 342 result = SendMessageInternal(message_proto, callback);
290 WriteData(); 343 if (result == net::ERR_FAILED || result == net::OK)
Ryan Sleevi 2013/10/23 23:28:51 BUG: You fail to handle a number of cases here. S
Munjal (Google) 2013/10/24 00:00:56 Done.
344 {
Ryan Sleevi 2013/10/23 23:28:51 style: brace goes on line above
Munjal (Google) 2013/10/24 00:00:56 Done.
345 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
346 callback.Run(net::ERR_FAILED);
347 }
291 } 348 }
292 349
293 void CastSocket::WriteData() { 350 int CastSocket::SendMessageInternal(const CastMessage& message_proto,
351 const net::CompletionCallback& callback) {
352 WriteRequest write_request(callback);
353 if (!write_request.SetContent(message_proto))
354 return net::ERR_FAILED;
355 write_queue_.push(write_request);
356 return WriteData();
Ryan Sleevi 2013/10/23 23:28:51 BUG: Potentially bad recursion design SendMessage
Munjal (Google) 2013/10/24 00:00:56 The recursive nature of Write was already there in
357 }
358
359 int CastSocket::WriteData() {
294 DCHECK(CalledOnValidThread()); 360 DCHECK(CalledOnValidThread());
295 DVLOG(1) << "WriteData q = " << write_queue_.size(); 361 DVLOG(1) << "WriteData q = " << write_queue_.size();
296 if (write_queue_.empty() || write_callback_pending_) 362 if (write_queue_.empty() || write_callback_pending_)
297 return; 363 return net::ERR_FAILED;
298 364
299 WriteRequest& request = write_queue_.front(); 365 WriteRequest& request = write_queue_.front();
300 if (ready_state_ != READY_STATE_OPEN) {
301 request.callback.Run(net::ERR_FAILED);
302 return;
303 }
304 366
305 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() << 367 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() <<
306 " bytes_written " << request.io_buffer->BytesConsumed(); 368 " bytes_written " << request.io_buffer->BytesConsumed();
307 369
308 write_callback_pending_ = true; 370 write_callback_pending_ = true;
309 int result = socket_->Write( 371 int result = socket_->Write(
310 request.io_buffer.get(), 372 request.io_buffer.get(),
311 request.io_buffer->BytesRemaining(), 373 request.io_buffer->BytesRemaining(),
312 base::Bind(&CastSocket::OnWriteData, AsWeakPtr())); 374 base::Bind(&CastSocket::OnWriteData, AsWeakPtr()));
313 375
314 DVLOG(1) << "WriteData result = " << result;
315
316 if (result != net::ERR_IO_PENDING) 376 if (result != net::ERR_IO_PENDING)
317 OnWriteData(result); 377 OnWriteData(result);
378
379 return result;
318 } 380 }
319 381
320 void CastSocket::OnWriteData(int result) { 382 void CastSocket::OnWriteData(int result) {
321 DCHECK(CalledOnValidThread()); 383 DCHECK(CalledOnValidThread());
322 DVLOG(1) << "OnWriteComplete result = " << result; 384 DVLOG(1) << "OnWriteComplete result = " << result;
323 DCHECK(write_callback_pending_); 385 DCHECK(write_callback_pending_);
324 DCHECK(!write_queue_.empty()); 386 DCHECK(!write_queue_.empty());
325 write_callback_pending_ = false; 387 write_callback_pending_ = false;
326 WriteRequest& request = write_queue_.front(); 388 WriteRequest& request = write_queue_.front();
327 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer; 389 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer;
328 390
329 if (result >= 0) { 391 if (result >= 0) {
330 io_buffer->DidConsume(result); 392 io_buffer->DidConsume(result);
331 if (io_buffer->BytesRemaining() > 0) { 393 if (io_buffer->BytesRemaining() > 0) {
332 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() << 394 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() <<
333 " consumed " << io_buffer->BytesConsumed() << 395 " consumed " << io_buffer->BytesConsumed() <<
334 " remaining " << io_buffer->BytesRemaining() << 396 " remaining " << io_buffer->BytesRemaining() <<
335 " # requests " << write_queue_.size(); 397 " # requests " << write_queue_.size();
336 WriteData(); 398 WriteData();
337 return; 399 return;
338 } 400 }
339 DCHECK_EQ(io_buffer->BytesConsumed(), io_buffer->size()); 401 DCHECK_EQ(io_buffer->BytesConsumed(), io_buffer->size());
340 DCHECK_EQ(io_buffer->BytesRemaining(), 0); 402 DCHECK_EQ(io_buffer->BytesRemaining(), 0);
341 result = io_buffer->BytesConsumed(); 403 result = io_buffer->BytesConsumed();
342 } 404 }
343 405
344 request.callback.Run(result); 406 request.callback.Run(result);
Ryan Sleevi 2013/10/23 23:28:51 DESIGN: If this callback wants to delete the objec
Munjal (Google) 2013/10/24 00:00:56 Right. But let me address it separately since it w
345 write_queue_.pop(); 407 write_queue_.pop();
346 408
347 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() << 409 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() <<
348 " consumed " << io_buffer->BytesConsumed() << 410 " consumed " << io_buffer->BytesConsumed() <<
349 " remaining " << io_buffer->BytesRemaining() << 411 " remaining " << io_buffer->BytesRemaining() <<
350 " # requests " << write_queue_.size(); 412 " # requests " << write_queue_.size();
351 413
352 if (result < 0) { 414 if (result < 0) {
353 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 415 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
354 return; 416 return;
355 } 417 }
356 418
357 if (!write_queue_.empty()) 419 if (!write_queue_.empty())
358 WriteData(); 420 WriteData();
359 } 421 }
360 422
361 void CastSocket::ReadData() { 423 int CastSocket::ReadData() {
362 DCHECK(CalledOnValidThread()); 424 DCHECK(CalledOnValidThread());
363 if (!socket_.get() || ready_state_ != READY_STATE_OPEN) { 425 if (!socket_.get())
364 return; 426 return net::ERR_FAILED;
365 }
366 DCHECK(!read_callback_pending_); 427 DCHECK(!read_callback_pending_);
367 read_callback_pending_ = true; 428 read_callback_pending_ = true;
368 // Figure out if we are reading the header or body, and the remaining bytes. 429 // Figure out if we are reading the header or body, and the remaining bytes.
369 uint32 num_bytes_to_read = 0; 430 uint32 num_bytes_to_read = 0;
370 if (header_read_buffer_->RemainingCapacity() > 0) { 431 if (header_read_buffer_->RemainingCapacity() > 0) {
371 current_read_buffer_ = header_read_buffer_; 432 current_read_buffer_ = header_read_buffer_;
372 num_bytes_to_read = header_read_buffer_->RemainingCapacity(); 433 num_bytes_to_read = header_read_buffer_->RemainingCapacity();
373 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize); 434 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize);
374 } else { 435 } else {
375 DCHECK_GT(current_message_size_, 0U); 436 DCHECK_GT(current_message_size_, 0U);
376 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); 437 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset();
377 current_read_buffer_ = body_read_buffer_; 438 current_read_buffer_ = body_read_buffer_;
378 DCHECK_LE(num_bytes_to_read, kMaxMessageSize); 439 DCHECK_LE(num_bytes_to_read, kMaxMessageSize);
379 } 440 }
380 DCHECK_GT(num_bytes_to_read, 0U); 441 DCHECK_GT(num_bytes_to_read, 0U);
381 // We read up to num_bytes_to_read into |current_read_buffer_|. 442 // We read up to num_bytes_to_read into |current_read_buffer_|.
382 int result = socket_->Read( 443 int result = socket_->Read(
383 current_read_buffer_.get(), 444 current_read_buffer_.get(),
384 num_bytes_to_read, 445 num_bytes_to_read,
385 base::Bind(&CastSocket::OnReadData, AsWeakPtr())); 446 base::Bind(&CastSocket::OnReadData, AsWeakPtr()));
386 DVLOG(1) << "ReadData result = " << result; 447 DVLOG(1) << "ReadData result = " << result;
387 if (result > 0) { 448 if (result > 0) {
388 OnReadData(result); 449 OnReadData(result);
389 } else if (result != net::ERR_IO_PENDING) { 450 } else if (result != net::ERR_IO_PENDING) {
390 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 451 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
391 } 452 }
453 return result;
392 } 454 }
393 455
394 void CastSocket::OnReadData(int result) { 456 void CastSocket::OnReadData(int result) {
395 DCHECK(CalledOnValidThread()); 457 DCHECK(CalledOnValidThread());
396 DVLOG(1) << "OnReadData result = " << result << 458 DVLOG(1) << "OnReadData result = " << result
397 " header offset = " << header_read_buffer_->offset() << 459 << " header offset = " << header_read_buffer_->offset()
398 " body offset = " << body_read_buffer_->offset(); 460 << " body offset = " << body_read_buffer_->offset();
399 read_callback_pending_ = false; 461 read_callback_pending_ = false;
400 if (result <= 0) { 462 if (result <= 0) {
401 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 463 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
402 return; 464 return;
403 } 465 }
404 // We read some data. Move the offset in the current buffer forward. 466 // We read some data. Move the offset in the current buffer forward.
405 DCHECK_LE(current_read_buffer_->offset() + result, 467 DCHECK_LE(current_read_buffer_->offset() + result,
406 current_read_buffer_->capacity()); 468 current_read_buffer_->capacity());
407 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); 469 current_read_buffer_->set_offset(current_read_buffer_->offset() + result);
408 470
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 513
452 bool CastSocket::ParseMessageFromBody() { 514 bool CastSocket::ParseMessageFromBody() {
453 DCHECK(CalledOnValidThread()); 515 DCHECK(CalledOnValidThread());
454 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), 516 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()),
455 current_message_size_); 517 current_message_size_);
456 CastMessage message_proto; 518 CastMessage message_proto;
457 if (!message_proto.ParseFromArray( 519 if (!message_proto.ParseFromArray(
458 body_read_buffer_->StartOfBuffer(), 520 body_read_buffer_->StartOfBuffer(),
459 current_message_size_)) 521 current_message_size_))
460 return false; 522 return false;
461 DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto); 523 DVLOG(1) << "Parsed message " << CastMessageToString(message_proto);
462 if (delegate_) { 524 // If the message is an auth message then we handle it internally.
525 if (IsAuthMessage(message_proto)) {
526 challenge_reply_.reset(new CastMessage(message_proto));
527 OnChallengeEvent(net::OK);
528 } else if (delegate_) {
463 MessageInfo message; 529 MessageInfo message;
464 if (!CastMessageToMessageInfo(message_proto, &message)) 530 if (!CastMessageToMessageInfo(message_proto, &message))
465 return false; 531 return false;
466 delegate_->OnMessage(this, message); 532 delegate_->OnMessage(this, message);
467 } 533 }
468 return true; 534 return true;
469 } 535 }
470 536
471 // static 537 // static
472 bool CastSocket::Serialize(const CastMessage& message_proto, 538 bool CastSocket::Serialize(const CastMessage& message_proto,
(...skipping 16 matching lines...) Expand all
489 socket_.reset(NULL); 555 socket_.reset(NULL);
490 ready_state_ = READY_STATE_CLOSED; 556 ready_state_ = READY_STATE_CLOSED;
491 error_state_ = error; 557 error_state_ = error;
492 if (delegate_) 558 if (delegate_)
493 delegate_->OnError(this, error); 559 delegate_->OnError(this, error);
494 } 560 }
495 561
496 bool CastSocket::ParseChannelUrl(const GURL& url) { 562 bool CastSocket::ParseChannelUrl(const GURL& url) {
497 DVLOG(1) << "url = " + url.spec(); 563 DVLOG(1) << "url = " + url.spec();
498 if (url.SchemeIs(kCastInsecureScheme)) { 564 if (url.SchemeIs(kCastInsecureScheme)) {
499 is_secure_ = false; 565 auth_required_ = false;
500 } else if (url.SchemeIs(kCastSecureScheme)) { 566 } else if (url.SchemeIs(kCastSecureScheme)) {
501 is_secure_ = true; 567 auth_required_ = true;
502 } else { 568 } else {
503 return false; 569 return false;
504 } 570 }
505 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes? 571 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes?
506 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? 572 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets?
507 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local 573 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local
508 // networks 574 // networks
509 const std::string& path = url.path(); 575 const std::string& path = url.path();
510 // Shortest possible: //A:B 576 // Shortest possible: //A:B
511 if (path.size() < 5) { 577 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), 643 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data),
578 message_data.size()); 644 message_data.size());
579 return true; 645 return true;
580 } 646 }
581 647
582 CastSocket::WriteRequest::~WriteRequest() { } 648 CastSocket::WriteRequest::~WriteRequest() { }
583 649
584 } // namespace cast_channel 650 } // namespace cast_channel
585 } // namespace api 651 } // namespace api
586 } // namespace extensions 652 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698