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

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 DVLOG(1) << "Sending challenge: " << CastMessageToString(challenge_message);
156 return SendMessageInternal(
157 challenge_message,
158 base::Bind(&CastSocket::OnChallengeEvent, AsWeakPtr()));
159 }
160
161 int CastSocket::ReadAuthChallengeReply() {
162 return ReadData();
163 }
164
149 void CastSocket::OnConnectComplete(int result) { 165 void CastSocket::OnConnectComplete(int result) {
150 int rv = DoConnectLoop(result); 166 int rv = DoConnectLoop(result);
151 if (rv != net::ERR_IO_PENDING) 167 if (rv != net::ERR_IO_PENDING)
152 DoConnectCallback(rv); 168 DoConnectCallback(rv);
153 } 169 }
154 170
171 void CastSocket::OnChallengeEvent(int result) {
172 int rv = DoConnectLoop(result);
173 if (rv != net::ERR_IO_PENDING)
174 DoConnectCallback(rv);
175 }
176
155 void CastSocket::Connect(const net::CompletionCallback& callback) { 177 void CastSocket::Connect(const net::CompletionCallback& callback) {
156 DCHECK(CalledOnValidThread()); 178 DCHECK(CalledOnValidThread());
157 int result = net::ERR_CONNECTION_FAILED; 179 int result = net::ERR_CONNECTION_FAILED;
158 DVLOG(1) << "Connect readyState = " << ready_state_; 180 DVLOG(1) << "Connect readyState = " << ready_state_;
159 if (ready_state_ != READY_STATE_NONE) { 181 if (ready_state_ != READY_STATE_NONE) {
160 callback.Run(result); 182 callback.Run(result);
161 return; 183 return;
162 } 184 }
163 if (!ParseChannelUrl(url_)) { 185 if (!ParseChannelUrl(url_)) {
164 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR); 186 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR);
165 // TODO(mfoltz): Signal channel errors via |callback|
166 callback.Run(result); 187 callback.Run(result);
167 return; 188 return;
168 } 189 }
169 connect_callback_ = callback; 190 connect_callback_ = callback;
170 next_state_ = CONN_STATE_TCP_CONNECT; 191 next_state_ = CONN_STATE_TCP_CONNECT;
171 int rv = DoConnectLoop(net::OK); 192 int rv = DoConnectLoop(net::OK);
172 if (rv != net::ERR_IO_PENDING) 193 if (rv != net::ERR_IO_PENDING)
173 DoConnectCallback(rv); 194 DoConnectCallback(rv);
174 } 195 }
175 196
(...skipping 22 matching lines...) Expand all
198 case CONN_STATE_TCP_CONNECT_COMPLETE: 219 case CONN_STATE_TCP_CONNECT_COMPLETE:
199 rv = DoTcpConnectComplete(rv); 220 rv = DoTcpConnectComplete(rv);
200 break; 221 break;
201 case CONN_STATE_SSL_CONNECT: 222 case CONN_STATE_SSL_CONNECT:
202 DCHECK_EQ(net::OK, rv); 223 DCHECK_EQ(net::OK, rv);
203 rv = DoSslConnect(); 224 rv = DoSslConnect();
204 break; 225 break;
205 case CONN_STATE_SSL_CONNECT_COMPLETE: 226 case CONN_STATE_SSL_CONNECT_COMPLETE:
206 rv = DoSslConnectComplete(rv); 227 rv = DoSslConnectComplete(rv);
207 break; 228 break;
229 case CONN_STATE_AUTH_CHALLENGE_SEND:
230 rv = DoAuthChallengeSend();
231 break;
232 case CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE:
233 rv = DoAuthChallengeSendComplete(rv);
234 break;
235 case CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE:
236 rv = DoAuthChallengeReplyComplete(rv);
237 break;
238
208 default: 239 default:
209 NOTREACHED() << "BUG in CastSocket state machine code"; 240 NOTREACHED() << "BUG in CastSocket state machine code";
210 break; 241 break;
211 } 242 }
212 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE); 243 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE);
213 // Get out of the loop either when: 244 // Get out of the loop either when:
214 // a. A network operation is pending, OR 245 // a. A network operation is pending, OR
215 // b. The Do* method called did not change state 246 // b. The Do* method called did not change state
216 247
217 return rv; 248 return rv;
218 } 249 }
219 250
220 int CastSocket::DoTcpConnect() { 251 int CastSocket::DoTcpConnect() {
252 DVLOG(1) << "DoTcpConnect";
221 next_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; 253 next_state_ = CONN_STATE_TCP_CONNECT_COMPLETE;
222 tcp_socket_ = CreateTcpSocket(); 254 tcp_socket_ = CreateTcpSocket();
223 return tcp_socket_->Connect( 255 return tcp_socket_->Connect(
224 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr())); 256 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr()));
225 } 257 }
226 258
227 int CastSocket::DoTcpConnectComplete(int result) { 259 int CastSocket::DoTcpConnectComplete(int result) {
260 DVLOG(1) << "DoTcpConnectComplete: " << result;
228 if (result == net::OK) 261 if (result == net::OK)
229 next_state_ = CONN_STATE_SSL_CONNECT; 262 next_state_ = CONN_STATE_SSL_CONNECT;
230 return result; 263 return result;
231 } 264 }
232 265
233 int CastSocket::DoSslConnect() { 266 int CastSocket::DoSslConnect() {
267 DVLOG(1) << "DoSslConnect";
234 next_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; 268 next_state_ = CONN_STATE_SSL_CONNECT_COMPLETE;
235 socket_ = CreateSslSocket(); 269 socket_ = CreateSslSocket();
236 return socket_->Connect( 270 return socket_->Connect(
237 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr())); 271 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr()));
238 } 272 }
239 273
240 int CastSocket::DoSslConnectComplete(int result) { 274 int CastSocket::DoSslConnectComplete(int result) {
241 // TODO(mfoltz,munjal): Authenticate the channel if is_secure_ == true. 275 DVLOG(1) << "DoSslConnectComplete: " << result;
242 if (result == net::ERR_CERT_AUTHORITY_INVALID && 276 if (result == net::ERR_CERT_AUTHORITY_INVALID &&
243 peer_cert_.empty() && 277 peer_cert_.empty() &&
244 ExtractPeerCert(&peer_cert_)) { 278 ExtractPeerCert(&peer_cert_)) {
245 next_state_ = CONN_STATE_TCP_CONNECT; 279 next_state_ = CONN_STATE_TCP_CONNECT;
280 } else if (result == net::OK && auth_required_) {
281 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND;
246 } 282 }
247 return result; 283 return result;
248 } 284 }
249 285
286 int CastSocket::DoAuthChallengeSend() {
287 DVLOG(1) << "DoAuthChallengeSend";
288 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE;
289 return SendAuthChallenge();
290 }
291
292 int CastSocket::DoAuthChallengeSendComplete(int result) {
293 DVLOG(1) << "DoAuthChallengeSendComplete: " << result;
294 if (result != net::OK)
295 return result;
296 next_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE;
297 return ReadAuthChallengeReply();
298 }
299
300 int CastSocket::DoAuthChallengeReplyComplete(int result) {
301 DVLOG(1) << "DoAuthChallengeReplyComplete: " << result;
302 if (result != net::OK)
303 return result;
304 if (!VerifyChallengeReply())
305 return net::ERR_FAILED;
306 DVLOG(1) << "Auth challenge verification succeeded";
307 return net::OK;
308 }
309
310 bool CastSocket::VerifyChallengeReply() {
311 return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_);
312 }
313
250 void CastSocket::DoConnectCallback(int result) { 314 void CastSocket::DoConnectCallback(int result) {
251 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; 315 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
252 error_state_ = (result == net::OK) ? 316 error_state_ = (result == net::OK) ?
253 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; 317 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR;
254 base::ResetAndReturn(&connect_callback_).Run(result); 318 base::ResetAndReturn(&connect_callback_).Run(result);
255 if (result == net::OK) 319 if (result == net::OK)
256 ReadData(); 320 ReadData();
257 } 321 }
258 322
259 void CastSocket::Close(const net::CompletionCallback& callback) { 323 void CastSocket::Close(const net::CompletionCallback& callback) {
260 DCHECK(CalledOnValidThread()); 324 DCHECK(CalledOnValidThread());
261 DVLOG(1) << "Close ReadyState = " << ready_state_; 325 DVLOG(1) << "Close ReadyState = " << ready_state_;
262 tcp_socket_.reset(NULL); 326 tcp_socket_.reset(NULL);
263 socket_.reset(NULL); 327 socket_.reset(NULL);
264 cert_verifier_.reset(NULL); 328 cert_verifier_.reset(NULL);
265 transport_security_state_.reset(NULL); 329 transport_security_state_.reset(NULL);
266 ready_state_ = READY_STATE_CLOSED; 330 ready_state_ = READY_STATE_CLOSED;
267 callback.Run(net::OK); 331 callback.Run(net::OK);
268 } 332 }
269 333
270 void CastSocket::SendMessage(const MessageInfo& message, 334 void CastSocket::SendMessage(const MessageInfo& message,
271 const net::CompletionCallback& callback) { 335 const net::CompletionCallback& callback) {
272 DCHECK(CalledOnValidThread()); 336 DCHECK(CalledOnValidThread());
273 DVLOG(1) << "Send ReadyState " << ready_state_; 337 DVLOG(1) << "Send ReadyState " << ready_state_;
274 int result = net::ERR_FAILED; 338 int result = net::ERR_FAILED;
275 if (ready_state_ != READY_STATE_OPEN) { 339 if (ready_state_ != READY_STATE_OPEN) {
276 callback.Run(result); 340 callback.Run(result);
277 return; 341 return;
278 } 342 }
279 WriteRequest write_request(callback);
280 CastMessage message_proto; 343 CastMessage message_proto;
281 if (!MessageInfoToCastMessage(message, &message_proto) || 344 if (!MessageInfoToCastMessage(message, &message_proto)) {
282 !write_request.SetContent(message_proto)) {
283 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE); 345 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
284 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the 346 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the
285 // caller. 347 // caller.
286 callback.Run(net::OK); 348 callback.Run(net::OK);
287 return; 349 return;
288 } 350 }
289 write_queue_.push(write_request); 351 result = SendMessageInternal(message_proto, callback);
290 WriteData(); 352 if (result == net::ERR_FAILED || result == net::OK)
353 {
354 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
355 callback.Run(net::ERR_FAILED);
356 }
291 } 357 }
292 358
293 void CastSocket::WriteData() { 359 int CastSocket::SendMessageInternal(const CastMessage& message_proto,
360 const net::CompletionCallback& callback) {
361 WriteRequest write_request(callback);
362 if (!write_request.SetContent(message_proto))
363 return net::ERR_FAILED;
364 write_queue_.push(write_request);
365 return WriteData();
366 }
367
368 int CastSocket::WriteData() {
294 DCHECK(CalledOnValidThread()); 369 DCHECK(CalledOnValidThread());
295 DVLOG(1) << "WriteData q = " << write_queue_.size(); 370 DVLOG(1) << "WriteData q = " << write_queue_.size();
296 if (write_queue_.empty() || write_callback_pending_) 371 if (write_queue_.empty() || write_callback_pending_)
297 return; 372 return net::ERR_FAILED;
298 373
299 WriteRequest& request = write_queue_.front(); 374 WriteRequest& request = write_queue_.front();
300 if (ready_state_ != READY_STATE_OPEN) {
301 request.callback.Run(net::ERR_FAILED);
302 return;
303 }
304 375
305 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() << 376 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() <<
306 " bytes_written " << request.io_buffer->BytesConsumed(); 377 " bytes_written " << request.io_buffer->BytesConsumed();
307 378
308 write_callback_pending_ = true; 379 write_callback_pending_ = true;
309 int result = socket_->Write( 380 int result = socket_->Write(
310 request.io_buffer.get(), 381 request.io_buffer.get(),
311 request.io_buffer->BytesRemaining(), 382 request.io_buffer->BytesRemaining(),
312 base::Bind(&CastSocket::OnWriteData, AsWeakPtr())); 383 base::Bind(&CastSocket::OnWriteData, AsWeakPtr()));
313 384
314 DVLOG(1) << "WriteData result = " << result; 385 if (result >= 0 || result != net::ERR_IO_PENDING)
386 OnWriteData(result);
315 387
316 if (result != net::ERR_IO_PENDING) 388 // result >=0 means write succeeded synchronously.
317 OnWriteData(result); 389 return result >= 0 ? net::OK : result;
Ryan Sleevi 2013/10/23 23:28:51 It does not mean the full message was written, how
318 } 390 }
319 391
320 void CastSocket::OnWriteData(int result) { 392 void CastSocket::OnWriteData(int result) {
321 DCHECK(CalledOnValidThread()); 393 DCHECK(CalledOnValidThread());
322 DVLOG(1) << "OnWriteComplete result = " << result; 394 DVLOG(1) << "OnWriteComplete result = " << result;
323 DCHECK(write_callback_pending_); 395 DCHECK(write_callback_pending_);
324 DCHECK(!write_queue_.empty()); 396 DCHECK(!write_queue_.empty());
325 write_callback_pending_ = false; 397 write_callback_pending_ = false;
326 WriteRequest& request = write_queue_.front(); 398 WriteRequest& request = write_queue_.front();
327 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer; 399 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer;
328 400
329 if (result >= 0) { 401 if (result >= 0) {
330 io_buffer->DidConsume(result); 402 io_buffer->DidConsume(result);
331 if (io_buffer->BytesRemaining() > 0) { 403 if (io_buffer->BytesRemaining() > 0) {
332 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() << 404 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() <<
333 " consumed " << io_buffer->BytesConsumed() << 405 " consumed " << io_buffer->BytesConsumed() <<
334 " remaining " << io_buffer->BytesRemaining() << 406 " remaining " << io_buffer->BytesRemaining() <<
335 " # requests " << write_queue_.size(); 407 " # requests " << write_queue_.size();
336 WriteData(); 408 WriteData();
337 return; 409 return;
338 } 410 }
339 DCHECK_EQ(io_buffer->BytesConsumed(), io_buffer->size()); 411 DCHECK_EQ(io_buffer->BytesConsumed(), io_buffer->size());
340 DCHECK_EQ(io_buffer->BytesRemaining(), 0); 412 DCHECK_EQ(io_buffer->BytesRemaining(), 0);
341 result = io_buffer->BytesConsumed(); 413 result = io_buffer->BytesConsumed();
342 } 414 }
343 415
344 request.callback.Run(result); 416 int callback_result = result >= 0 ? net::OK : result;
417 request.callback.Run(callback_result);
345 write_queue_.pop(); 418 write_queue_.pop();
346 419
347 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() << 420 DVLOG(1) << "OnWriteComplete size = " << io_buffer->size() <<
348 " consumed " << io_buffer->BytesConsumed() << 421 " consumed " << io_buffer->BytesConsumed() <<
349 " remaining " << io_buffer->BytesRemaining() << 422 " remaining " << io_buffer->BytesRemaining() <<
350 " # requests " << write_queue_.size(); 423 " # requests " << write_queue_.size();
351 424
352 if (result < 0) { 425 if (result < 0) {
353 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 426 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
354 return; 427 return;
355 } 428 }
356 429
357 if (!write_queue_.empty()) 430 if (!write_queue_.empty())
358 WriteData(); 431 WriteData();
359 } 432 }
360 433
361 void CastSocket::ReadData() { 434 int CastSocket::ReadData() {
362 DCHECK(CalledOnValidThread()); 435 DCHECK(CalledOnValidThread());
363 if (!socket_.get() || ready_state_ != READY_STATE_OPEN) { 436 if (!socket_.get())
364 return; 437 return net::ERR_FAILED;
365 }
366 DCHECK(!read_callback_pending_); 438 DCHECK(!read_callback_pending_);
367 read_callback_pending_ = true; 439 read_callback_pending_ = true;
368 // Figure out if we are reading the header or body, and the remaining bytes. 440 // Figure out if we are reading the header or body, and the remaining bytes.
369 uint32 num_bytes_to_read = 0; 441 uint32 num_bytes_to_read = 0;
370 if (header_read_buffer_->RemainingCapacity() > 0) { 442 if (header_read_buffer_->RemainingCapacity() > 0) {
371 current_read_buffer_ = header_read_buffer_; 443 current_read_buffer_ = header_read_buffer_;
372 num_bytes_to_read = header_read_buffer_->RemainingCapacity(); 444 num_bytes_to_read = header_read_buffer_->RemainingCapacity();
373 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize); 445 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize);
374 } else { 446 } else {
375 DCHECK_GT(current_message_size_, 0U); 447 DCHECK_GT(current_message_size_, 0U);
376 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); 448 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset();
377 current_read_buffer_ = body_read_buffer_; 449 current_read_buffer_ = body_read_buffer_;
378 DCHECK_LE(num_bytes_to_read, kMaxMessageSize); 450 DCHECK_LE(num_bytes_to_read, kMaxMessageSize);
379 } 451 }
380 DCHECK_GT(num_bytes_to_read, 0U); 452 DCHECK_GT(num_bytes_to_read, 0U);
381 // We read up to num_bytes_to_read into |current_read_buffer_|. 453 // We read up to num_bytes_to_read into |current_read_buffer_|.
382 int result = socket_->Read( 454 int result = socket_->Read(
383 current_read_buffer_.get(), 455 current_read_buffer_.get(),
384 num_bytes_to_read, 456 num_bytes_to_read,
385 base::Bind(&CastSocket::OnReadData, AsWeakPtr())); 457 base::Bind(&CastSocket::OnReadData, AsWeakPtr()));
386 DVLOG(1) << "ReadData result = " << result; 458 DVLOG(1) << "ReadData result = " << result;
387 if (result > 0) { 459 if (result > 0) {
388 OnReadData(result); 460 OnReadData(result);
389 } else if (result != net::ERR_IO_PENDING) { 461 } else if (result != net::ERR_IO_PENDING) {
390 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 462 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
391 } 463 }
464 return result;
392 } 465 }
393 466
394 void CastSocket::OnReadData(int result) { 467 void CastSocket::OnReadData(int result) {
395 DCHECK(CalledOnValidThread()); 468 DCHECK(CalledOnValidThread());
396 DVLOG(1) << "OnReadData result = " << result << 469 DVLOG(1) << "OnReadData result = " << result
397 " header offset = " << header_read_buffer_->offset() << 470 << " header offset = " << header_read_buffer_->offset()
398 " body offset = " << body_read_buffer_->offset(); 471 << " body offset = " << body_read_buffer_->offset();
399 read_callback_pending_ = false; 472 read_callback_pending_ = false;
400 if (result <= 0) { 473 if (result <= 0) {
401 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 474 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
402 return; 475 return;
403 } 476 }
404 // We read some data. Move the offset in the current buffer forward. 477 // We read some data. Move the offset in the current buffer forward.
405 DCHECK_LE(current_read_buffer_->offset() + result, 478 DCHECK_LE(current_read_buffer_->offset() + result,
406 current_read_buffer_->capacity()); 479 current_read_buffer_->capacity());
407 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); 480 current_read_buffer_->set_offset(current_read_buffer_->offset() + result);
408 481
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 524
452 bool CastSocket::ParseMessageFromBody() { 525 bool CastSocket::ParseMessageFromBody() {
453 DCHECK(CalledOnValidThread()); 526 DCHECK(CalledOnValidThread());
454 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), 527 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()),
455 current_message_size_); 528 current_message_size_);
456 CastMessage message_proto; 529 CastMessage message_proto;
457 if (!message_proto.ParseFromArray( 530 if (!message_proto.ParseFromArray(
458 body_read_buffer_->StartOfBuffer(), 531 body_read_buffer_->StartOfBuffer(),
459 current_message_size_)) 532 current_message_size_))
460 return false; 533 return false;
461 DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto); 534 DVLOG(1) << "Parsed message " << CastMessageToString(message_proto);
462 if (delegate_) { 535 // If the message is an auth message then we handle it internally.
536 if (IsAuthMessage(message_proto)) {
537 challenge_reply_.reset(new CastMessage(message_proto));
538 OnChallengeEvent(net::OK);
539 } else if (delegate_) {
463 MessageInfo message; 540 MessageInfo message;
464 if (!CastMessageToMessageInfo(message_proto, &message)) 541 if (!CastMessageToMessageInfo(message_proto, &message))
465 return false; 542 return false;
466 delegate_->OnMessage(this, message); 543 delegate_->OnMessage(this, message);
467 } 544 }
468 return true; 545 return true;
469 } 546 }
470 547
471 // static 548 // static
472 bool CastSocket::Serialize(const CastMessage& message_proto, 549 bool CastSocket::Serialize(const CastMessage& message_proto,
(...skipping 16 matching lines...) Expand all
489 socket_.reset(NULL); 566 socket_.reset(NULL);
490 ready_state_ = READY_STATE_CLOSED; 567 ready_state_ = READY_STATE_CLOSED;
491 error_state_ = error; 568 error_state_ = error;
492 if (delegate_) 569 if (delegate_)
493 delegate_->OnError(this, error); 570 delegate_->OnError(this, error);
494 } 571 }
495 572
496 bool CastSocket::ParseChannelUrl(const GURL& url) { 573 bool CastSocket::ParseChannelUrl(const GURL& url) {
497 DVLOG(1) << "url = " + url.spec(); 574 DVLOG(1) << "url = " + url.spec();
498 if (url.SchemeIs(kCastInsecureScheme)) { 575 if (url.SchemeIs(kCastInsecureScheme)) {
499 is_secure_ = false; 576 auth_required_ = false;
500 } else if (url.SchemeIs(kCastSecureScheme)) { 577 } else if (url.SchemeIs(kCastSecureScheme)) {
501 is_secure_ = true; 578 auth_required_ = true;
502 } else { 579 } else {
503 return false; 580 return false;
504 } 581 }
505 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes? 582 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes?
506 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? 583 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets?
507 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local 584 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local
508 // networks 585 // networks
509 const std::string& path = url.path(); 586 const std::string& path = url.path();
510 // Shortest possible: //A:B 587 // Shortest possible: //A:B
511 if (path.size() < 5) { 588 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), 654 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data),
578 message_data.size()); 655 message_data.size());
579 return true; 656 return true;
580 } 657 }
581 658
582 CastSocket::WriteRequest::~WriteRequest() { } 659 CastSocket::WriteRequest::~WriteRequest() { }
583 660
584 } // namespace cast_channel 661 } // namespace cast_channel
585 } // namespace api 662 } // namespace api
586 } // namespace extensions 663 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698