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

Side by Side Diff: net/socket_stream/socket_stream.cc

Issue 7484065: secure proxy support in websocket (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: don't set next_state_ to STATE_CLOSE when error in DoLoop Created 9 years, 5 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
« no previous file with comments | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_metrics.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // TODO(ukai): code is similar with http_network_transaction.cc. We should 5 // TODO(ukai): code is similar with http_network_transaction.cc. We should
6 // think about ways to share code, if possible. 6 // think about ways to share code, if possible.
7 7
8 #include "net/socket_stream/socket_stream.h" 8 #include "net/socket_stream/socket_stream.h"
9 9
10 #include <set> 10 #include <set>
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 Delegate* delegate = delegate_; 297 Delegate* delegate = delegate_;
298 delegate_ = NULL; 298 delegate_ = NULL;
299 if (delegate) { 299 if (delegate) {
300 delegate->OnError(this, result); 300 delegate->OnError(this, result);
301 if (result != ERR_PROTOCOL_SWITCHED) 301 if (result != ERR_PROTOCOL_SWITCHED)
302 delegate->OnClose(this); 302 delegate->OnClose(this);
303 } 303 }
304 Release(); 304 Release();
305 } 305 }
306 306
307 int SocketStream::DidEstablishSSL(int result) {
308 if (IsCertificateError(result)) {
309 if (socket_->IsConnectedAndIdle()) {
310 result = HandleCertificateError(result);
311 } else {
312 // SSLClientSocket for Mac will report socket is not connected,
313 // if it returns cert verification error. It didn't perform
314 // SSLHandshake yet.
315 // So, we should restart establishing connection with the
316 // certificate in allowed bad certificates in |ssl_config_|.
317 // See also net/http/http_network_transaction.cc
318 // HandleCertificateError() and RestartIgnoringLastError().
319 SSLClientSocket* ssl_socket =
320 reinterpret_cast<SSLClientSocket*>(socket_.get());
321 SSLInfo ssl_info;
322 ssl_socket->GetSSLInfo(&ssl_info);
323 if (ssl_info.cert == NULL ||
324 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) {
325 // If we already have the certificate in the set of allowed bad
326 // certificates, we did try it and failed again, so we should not
327 // retry again: the connection should fail at last.
328 next_state_ = STATE_CLOSE;
329 return result;
330 }
331 // Add the bad certificate to the set of allowed certificates in the
332 // SSL config object.
333 SSLConfig::CertAndStatus bad_cert;
334 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) {
335 next_state_ = STATE_CLOSE;
336 return result;
337 }
338 bad_cert.cert_status = ssl_info.cert_status;
339 ssl_config_.allowed_bad_certs.push_back(bad_cert);
340 // Restart connection ignoring the bad certificate.
341 socket_->Disconnect();
342 socket_.reset();
343 next_state_ = STATE_TCP_CONNECT;
344 return OK;
345 }
346 }
347 return result;
348 }
349
307 int SocketStream::DidEstablishConnection() { 350 int SocketStream::DidEstablishConnection() {
308 if (!socket_.get() || !socket_->IsConnected()) { 351 if (!socket_.get() || !socket_->IsConnected()) {
309 next_state_ = STATE_CLOSE; 352 next_state_ = STATE_CLOSE;
310 return ERR_CONNECTION_FAILED; 353 return ERR_CONNECTION_FAILED;
311 } 354 }
312 next_state_ = STATE_READ_WRITE; 355 next_state_ = STATE_READ_WRITE;
313 metrics_->OnConnected(); 356 metrics_->OnConnected();
314 357
315 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); 358 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL);
316 if (delegate_) 359 if (delegate_)
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 case STATE_READ_TUNNEL_HEADERS_COMPLETE: 476 case STATE_READ_TUNNEL_HEADERS_COMPLETE:
434 result = DoReadTunnelHeadersComplete(result); 477 result = DoReadTunnelHeadersComplete(result);
435 break; 478 break;
436 case STATE_SOCKS_CONNECT: 479 case STATE_SOCKS_CONNECT:
437 DCHECK_EQ(OK, result); 480 DCHECK_EQ(OK, result);
438 result = DoSOCKSConnect(); 481 result = DoSOCKSConnect();
439 break; 482 break;
440 case STATE_SOCKS_CONNECT_COMPLETE: 483 case STATE_SOCKS_CONNECT_COMPLETE:
441 result = DoSOCKSConnectComplete(result); 484 result = DoSOCKSConnectComplete(result);
442 break; 485 break;
486 case STATE_SECURE_PROXY_CONNECT:
487 DCHECK_EQ(OK, result);
488 result = DoSecureProxyConnect();
489 break;
490 case STATE_SECURE_PROXY_CONNECT_COMPLETE:
491 result = DoSecureProxyConnectComplete(result);
492 break;
443 case STATE_SSL_CONNECT: 493 case STATE_SSL_CONNECT:
444 DCHECK_EQ(OK, result); 494 DCHECK_EQ(OK, result);
445 result = DoSSLConnect(); 495 result = DoSSLConnect();
446 break; 496 break;
447 case STATE_SSL_CONNECT_COMPLETE: 497 case STATE_SSL_CONNECT_COMPLETE:
448 result = DoSSLConnectComplete(result); 498 result = DoSSLConnectComplete(result);
449 break; 499 break;
450 case STATE_READ_WRITE: 500 case STATE_READ_WRITE:
451 result = DoReadWrite(result); 501 result = DoReadWrite(result);
452 break; 502 break;
453 case STATE_AUTH_REQUIRED: 503 case STATE_AUTH_REQUIRED:
454 // It might be called when DoClose is called while waiting in 504 // It might be called when DoClose is called while waiting in
455 // STATE_AUTH_REQUIRED. 505 // STATE_AUTH_REQUIRED.
456 Finish(result); 506 Finish(result);
457 return; 507 return;
458 case STATE_CLOSE: 508 case STATE_CLOSE:
459 DCHECK_LE(result, OK); 509 DCHECK_LE(result, OK);
460 Finish(result); 510 Finish(result);
461 return; 511 return;
462 default: 512 default:
463 NOTREACHED() << "bad state " << state; 513 NOTREACHED() << "bad state " << state;
464 Finish(result); 514 Finish(result);
465 return; 515 return;
466 } 516 }
467 if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED) 517 if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED)
468 continue; 518 continue;
469 // If the connection is not established yet and had actual errors, 519 // If the connection is not established yet and had actual errors,
470 // close the connection. 520 // record the error. In next iteration, it will close the connection.
471 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { 521 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) {
472 DCHECK_EQ(next_state_, STATE_CLOSE);
473 net_log_.EndEventWithNetErrorCode( 522 net_log_.EndEventWithNetErrorCode(
474 NetLog::TYPE_SOCKET_STREAM_CONNECT, result); 523 NetLog::TYPE_SOCKET_STREAM_CONNECT, result);
475 } 524 }
476 } while (result != ERR_IO_PENDING); 525 } while (result != ERR_IO_PENDING);
477 } 526 }
478 527
479 int SocketStream::DoResolveProxy() { 528 int SocketStream::DoResolveProxy() {
480 DCHECK(!pac_request_); 529 DCHECK(!pac_request_);
481 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 530 next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
482 531
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 return socket_->Connect(&io_callback_); 658 return socket_->Connect(&io_callback_);
610 } 659 }
611 660
612 int SocketStream::DoTcpConnectComplete(int result) { 661 int SocketStream::DoTcpConnectComplete(int result) {
613 // TODO(ukai): if error occured, reconsider proxy after error. 662 // TODO(ukai): if error occured, reconsider proxy after error.
614 if (result != OK) { 663 if (result != OK) {
615 next_state_ = STATE_CLOSE; 664 next_state_ = STATE_CLOSE;
616 return result; 665 return result;
617 } 666 }
618 667
619 if (proxy_mode_ == kTunnelProxy) 668 if (proxy_mode_ == kTunnelProxy) {
620 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 669 if (proxy_info_.is_https())
621 else if (proxy_mode_ == kSOCKSProxy) 670 next_state_ = STATE_SECURE_PROXY_CONNECT;
671 else
672 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
673 } else if (proxy_mode_ == kSOCKSProxy) {
622 next_state_ = STATE_SOCKS_CONNECT; 674 next_state_ = STATE_SOCKS_CONNECT;
623 else if (is_secure()) { 675 } else if (is_secure()) {
624 next_state_ = STATE_SSL_CONNECT; 676 next_state_ = STATE_SSL_CONNECT;
625 } else { 677 } else {
626 result = DidEstablishConnection(); 678 result = DidEstablishConnection();
627 } 679 }
628 return result; 680 return result;
629 } 681 }
630 682
631 int SocketStream::DoWriteTunnelHeaders() { 683 int SocketStream::DoWriteTunnelHeaders() {
632 DCHECK_EQ(kTunnelProxy, proxy_mode_); 684 DCHECK_EQ(kTunnelProxy, proxy_mode_);
633 685
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 if (is_secure()) 895 if (is_secure())
844 next_state_ = STATE_SSL_CONNECT; 896 next_state_ = STATE_SSL_CONNECT;
845 else 897 else
846 result = DidEstablishConnection(); 898 result = DidEstablishConnection();
847 } else { 899 } else {
848 next_state_ = STATE_CLOSE; 900 next_state_ = STATE_CLOSE;
849 } 901 }
850 return result; 902 return result;
851 } 903 }
852 904
905 int SocketStream::DoSecureProxyConnect() {
906 DCHECK(factory_);
907 SSLClientSocketContext ssl_context;
908 ssl_context.cert_verifier = cert_verifier_;
909 ssl_context.origin_bound_cert_service = origin_bound_cert_service_;
910 // TODO(agl): look into plumbing SSLHostInfo here.
911 socket_.reset(factory_->CreateSSLClientSocket(
912 socket_.release(),
913 proxy_info_.proxy_server().host_port_pair(),
914 ssl_config_,
915 NULL /* ssl_host_info */,
916 ssl_context));
917 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE;
918 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION);
919 return socket_->Connect(&io_callback_);
920 }
921
922 int SocketStream::DoSecureProxyConnectComplete(int result) {
923 DCHECK_EQ(STATE_NONE, next_state_);
924 result = DidEstablishSSL(result);
925 if (next_state_ != STATE_NONE)
926 return result;
927 if (result == OK)
928 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
929 else
930 next_state_ = STATE_CLOSE;
931 return result;
932 }
933
853 int SocketStream::DoSSLConnect() { 934 int SocketStream::DoSSLConnect() {
854 DCHECK(factory_); 935 DCHECK(factory_);
855 SSLClientSocketContext ssl_context; 936 SSLClientSocketContext ssl_context;
856 ssl_context.cert_verifier = cert_verifier_; 937 ssl_context.cert_verifier = cert_verifier_;
857 ssl_context.origin_bound_cert_service = origin_bound_cert_service_; 938 ssl_context.origin_bound_cert_service = origin_bound_cert_service_;
858 // TODO(agl): look into plumbing SSLHostInfo here. 939 // TODO(agl): look into plumbing SSLHostInfo here.
859 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), 940 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(),
860 HostPortPair::FromURL(url_), 941 HostPortPair::FromURL(url_),
861 ssl_config_, 942 ssl_config_,
862 NULL /* ssl_host_info */, 943 NULL /* ssl_host_info */,
863 ssl_context)); 944 ssl_context));
864 next_state_ = STATE_SSL_CONNECT_COMPLETE; 945 next_state_ = STATE_SSL_CONNECT_COMPLETE;
865 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION); 946 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION);
866 return socket_->Connect(&io_callback_); 947 return socket_->Connect(&io_callback_);
867 } 948 }
868 949
869 int SocketStream::DoSSLConnectComplete(int result) { 950 int SocketStream::DoSSLConnectComplete(int result) {
870 if (IsCertificateError(result)) { 951 DCHECK_EQ(STATE_NONE, next_state_);
871 if (socket_->IsConnectedAndIdle()) { 952 result = DidEstablishSSL(result);
872 result = HandleCertificateError(result); 953 if (next_state_ != STATE_NONE)
873 } else { 954 return result;
874 // SSLClientSocket for Mac will report socket is not connected,
875 // if it returns cert verification error. It didn't perform
876 // SSLHandshake yet.
877 // So, we should restart establishing connection with the
878 // certificate in allowed bad certificates in |ssl_config_|.
879 // See also net/http/http_network_transaction.cc
880 // HandleCertificateError() and RestartIgnoringLastError().
881 SSLClientSocket* ssl_socket =
882 reinterpret_cast<SSLClientSocket*>(socket_.get());
883 SSLInfo ssl_info;
884 ssl_socket->GetSSLInfo(&ssl_info);
885 if (ssl_info.cert == NULL ||
886 ssl_config_.IsAllowedBadCert(ssl_info.cert, NULL)) {
887 // If we already have the certificate in the set of allowed bad
888 // certificates, we did try it and failed again, so we should not
889 // retry again: the connection should fail at last.
890 next_state_ = STATE_CLOSE;
891 return result;
892 }
893 // Add the bad certificate to the set of allowed certificates in the
894 // SSL config object.
895 SSLConfig::CertAndStatus bad_cert;
896 if (!ssl_info.cert->GetDEREncoded(&bad_cert.der_cert)) {
897 next_state_ = STATE_CLOSE;
898 return result;
899 }
900 bad_cert.cert_status = ssl_info.cert_status;
901 ssl_config_.allowed_bad_certs.push_back(bad_cert);
902 // Restart connection ignoring the bad certificate.
903 socket_->Disconnect();
904 socket_.reset();
905 next_state_ = STATE_TCP_CONNECT;
906 return OK;
907 }
908 }
909
910 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible. 955 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible.
911 // If we use HTTPS and this is the first connection to the SPDY server, 956 // If we use HTTPS and this is the first connection to the SPDY server,
912 // we should take care of TLS NPN extension here. 957 // we should take care of TLS NPN extension here.
913 958
914 if (result == OK) 959 if (result == OK)
915 result = DidEstablishConnection(); 960 result = DidEstablishConnection();
916 else 961 else
917 next_state_ = STATE_CLOSE; 962 next_state_ = STATE_CLOSE;
918 return result; 963 return result;
919 } 964 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 1132
1088 SSLConfigService* SocketStream::ssl_config_service() const { 1133 SSLConfigService* SocketStream::ssl_config_service() const {
1089 return context_->ssl_config_service(); 1134 return context_->ssl_config_service();
1090 } 1135 }
1091 1136
1092 ProxyService* SocketStream::proxy_service() const { 1137 ProxyService* SocketStream::proxy_service() const {
1093 return context_->proxy_service(); 1138 return context_->proxy_service();
1094 } 1139 }
1095 1140
1096 } // namespace net 1141 } // namespace net
OLDNEW
« no previous file with comments | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698