socket_stream.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4// 5// TODO(ukai): code is similar with http_network_transaction.cc. We should 6// think about ways to share code, if possible. 7 8#include "net/socket_stream/socket_stream.h" 9 10#include <set> 11#include <string> 12 13#include "base/compiler_specific.h" 14#include "base/logging.h" 15#include "base/message_loop.h" 16#include "base/string_util.h" 17#include "base/stringprintf.h" 18#include "base/utf_string_conversions.h" 19#include "net/base/auth.h" 20#include "net/base/host_resolver.h" 21#include "net/base/io_buffer.h" 22#include "net/base/net_errors.h" 23#include "net/base/net_util.h" 24#include "net/http/http_auth_handler_factory.h" 25#include "net/http/http_request_info.h" 26#include "net/http/http_response_headers.h" 27#include "net/http/http_util.h" 28#include "net/socket/client_socket_factory.h" 29#include "net/socket/socks5_client_socket.h" 30#include "net/socket/socks_client_socket.h" 31#include "net/socket/ssl_client_socket.h" 32#include "net/socket/tcp_client_socket.h" 33#include "net/socket_stream/socket_stream_metrics.h" 34#include "net/url_request/url_request.h" 35 36static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. 37static const int kReadBufferSize = 4096; 38 39namespace net { 40 41SocketStream::ResponseHeaders::ResponseHeaders() : IOBuffer() {} 42SocketStream::ResponseHeaders::~ResponseHeaders() { data_ = NULL; } 43 44void SocketStream::ResponseHeaders::Realloc(size_t new_size) { 45 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size))); 46} 47 48SocketStream::SocketStream(const GURL& url, Delegate* delegate) 49 : delegate_(delegate), 50 url_(url), 51 max_pending_send_allowed_(kMaxPendingSendAllowed), 52 next_state_(STATE_NONE), 53 host_resolver_(NULL), 54 cert_verifier_(NULL), 55 http_auth_handler_factory_(NULL), 56 factory_(ClientSocketFactory::GetDefaultFactory()), 57 proxy_mode_(kDirectConnection), 58 proxy_url_(url), 59 pac_request_(NULL), 60 ALLOW_THIS_IN_INITIALIZER_LIST( 61 io_callback_(this, &SocketStream::OnIOCompleted)), 62 ALLOW_THIS_IN_INITIALIZER_LIST( 63 read_callback_(this, &SocketStream::OnReadCompleted)), 64 ALLOW_THIS_IN_INITIALIZER_LIST( 65 write_callback_(this, &SocketStream::OnWriteCompleted)), 66 read_buf_(NULL), 67 write_buf_(NULL), 68 current_write_buf_(NULL), 69 write_buf_offset_(0), 70 write_buf_size_(0), 71 closing_(false), 72 server_closed_(false), 73 metrics_(new SocketStreamMetrics(url)) { 74 DCHECK(MessageLoop::current()) << 75 "The current MessageLoop must exist"; 76 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 77 "The current MessageLoop must be TYPE_IO"; 78 DCHECK(delegate_); 79} 80 81SocketStream::~SocketStream() { 82 set_context(NULL); 83 DCHECK(!delegate_); 84 DCHECK(!pac_request_); 85} 86 87SocketStream::UserData* SocketStream::GetUserData( 88 const void* key) const { 89 UserDataMap::const_iterator found = user_data_.find(key); 90 if (found != user_data_.end()) 91 return found->second.get(); 92 return NULL; 93} 94 95void SocketStream::SetUserData(const void* key, UserData* data) { 96 user_data_[key] = linked_ptr<UserData>(data); 97} 98 99void SocketStream::set_context(URLRequestContext* context) { 100 scoped_refptr<URLRequestContext> prev_context = context_; 101 102 context_ = context; 103 104 if (prev_context != context) { 105 if (prev_context && pac_request_) { 106 prev_context->proxy_service()->CancelPacRequest(pac_request_); 107 pac_request_ = NULL; 108 } 109 110 net_log_.EndEvent(NetLog::TYPE_REQUEST_ALIVE, NULL); 111 net_log_ = BoundNetLog(); 112 113 if (context) { 114 net_log_ = BoundNetLog::Make( 115 context->net_log(), 116 NetLog::SOURCE_SOCKET_STREAM); 117 118 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE, NULL); 119 } 120 } 121 122 if (context_) { 123 host_resolver_ = context_->host_resolver(); 124 cert_verifier_ = context_->cert_verifier(); 125 http_auth_handler_factory_ = context_->http_auth_handler_factory(); 126 } 127} 128 129void SocketStream::Connect() { 130 DCHECK(MessageLoop::current()) << 131 "The current MessageLoop must exist"; 132 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 133 "The current MessageLoop must be TYPE_IO"; 134 if (context_) 135 ssl_config_service()->GetSSLConfig(&ssl_config_); 136 DCHECK_EQ(next_state_, STATE_NONE); 137 138 AddRef(); // Released in Finish() 139 // Open a connection asynchronously, so that delegate won't be called 140 // back before returning Connect(). 141 next_state_ = STATE_RESOLVE_PROXY; 142 net_log_.BeginEvent( 143 NetLog::TYPE_SOCKET_STREAM_CONNECT, 144 make_scoped_refptr( 145 new NetLogStringParameter("url", url_.possibly_invalid_spec()))); 146 MessageLoop::current()->PostTask( 147 FROM_HERE, 148 NewRunnableMethod(this, &SocketStream::DoLoop, OK)); 149} 150 151bool SocketStream::SendData(const char* data, int len) { 152 DCHECK(MessageLoop::current()) << 153 "The current MessageLoop must exist"; 154 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 155 "The current MessageLoop must be TYPE_IO"; 156 if (!socket_.get() || !socket_->IsConnected() || next_state_ == STATE_NONE) 157 return false; 158 if (write_buf_) { 159 int current_amount_send = write_buf_size_ - write_buf_offset_; 160 for (PendingDataQueue::const_iterator iter = pending_write_bufs_.begin(); 161 iter != pending_write_bufs_.end(); 162 ++iter) 163 current_amount_send += (*iter)->size(); 164 165 current_amount_send += len; 166 if (current_amount_send > max_pending_send_allowed_) 167 return false; 168 169 pending_write_bufs_.push_back(make_scoped_refptr( 170 new IOBufferWithSize(len))); 171 memcpy(pending_write_bufs_.back()->data(), data, len); 172 return true; 173 } 174 DCHECK(!current_write_buf_); 175 write_buf_ = new IOBuffer(len); 176 memcpy(write_buf_->data(), data, len); 177 write_buf_size_ = len; 178 write_buf_offset_ = 0; 179 // Send pending data asynchronously, so that delegate won't be called 180 // back before returning SendData(). 181 MessageLoop::current()->PostTask( 182 FROM_HERE, 183 NewRunnableMethod(this, &SocketStream::DoLoop, OK)); 184 return true; 185} 186 187void SocketStream::Close() { 188 DCHECK(MessageLoop::current()) << 189 "The current MessageLoop must exist"; 190 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 191 "The current MessageLoop must be TYPE_IO"; 192 // If next_state_ is STATE_NONE, the socket was not opened, or already 193 // closed. So, return immediately. 194 // Otherwise, it might call Finish() more than once, so breaks balance 195 // of AddRef() and Release() in Connect() and Finish(), respectively. 196 if (next_state_ == STATE_NONE) 197 return; 198 MessageLoop::current()->PostTask( 199 FROM_HERE, 200 NewRunnableMethod(this, &SocketStream::DoClose)); 201} 202 203void SocketStream::DoClose() { 204 closing_ = true; 205 // If next_state_ is STATE_TCP_CONNECT, it's waiting other socket establishing 206 // connection. If next_state_ is STATE_AUTH_REQUIRED, it's waiting for 207 // restarting. In these states, we'll close the SocketStream now. 208 if (next_state_ == STATE_TCP_CONNECT || next_state_ == STATE_AUTH_REQUIRED) { 209 DoLoop(ERR_ABORTED); 210 return; 211 } 212 // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close 213 // the SocketStream. 214 // If it's writing now, we should defer the closing after the current 215 // writing is completed. 216 if (next_state_ == STATE_READ_WRITE && !current_write_buf_) 217 DoLoop(ERR_ABORTED); 218 219 // In other next_state_, we'll wait for callback of other APIs, such as 220 // ResolveProxy(). 221} 222 223void SocketStream::RestartWithAuth( 224 const string16& username, const string16& password) { 225 DCHECK(MessageLoop::current()) << 226 "The current MessageLoop must exist"; 227 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 228 "The current MessageLoop must be TYPE_IO"; 229 DCHECK(auth_handler_.get()); 230 if (!socket_.get()) { 231 LOG(ERROR) << "Socket is closed before restarting with auth."; 232 return; 233 } 234 235 if (auth_identity_.invalid) { 236 // Update the username/password. 237 auth_identity_.source = HttpAuth::IDENT_SRC_EXTERNAL; 238 auth_identity_.invalid = false; 239 auth_identity_.username = username; 240 auth_identity_.password = password; 241 } 242 243 MessageLoop::current()->PostTask( 244 FROM_HERE, 245 NewRunnableMethod(this, &SocketStream::DoRestartWithAuth)); 246} 247 248void SocketStream::DetachDelegate() { 249 if (!delegate_) 250 return; 251 delegate_ = NULL; 252 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); 253 // We don't need to send pending data when client detach the delegate. 254 pending_write_bufs_.clear(); 255 Close(); 256} 257 258void SocketStream::Finish(int result) { 259 DCHECK(MessageLoop::current()) << 260 "The current MessageLoop must exist"; 261 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << 262 "The current MessageLoop must be TYPE_IO"; 263 DCHECK_LE(result, OK); 264 if (result == OK) 265 result = ERR_CONNECTION_CLOSED; 266 DCHECK_EQ(next_state_, STATE_NONE); 267 DVLOG(1) << "Finish result=" << net::ErrorToString(result); 268 if (delegate_) 269 delegate_->OnError(this, result); 270 271 metrics_->OnClose(); 272 Delegate* delegate = delegate_; 273 delegate_ = NULL; 274 if (delegate) { 275 delegate->OnClose(this); 276 } 277 Release(); 278} 279 280void SocketStream::SetHostResolver(HostResolver* host_resolver) { 281 DCHECK(host_resolver); 282 host_resolver_ = host_resolver; 283} 284 285void SocketStream::SetClientSocketFactory( 286 ClientSocketFactory* factory) { 287 DCHECK(factory); 288 factory_ = factory; 289} 290 291void SocketStream::CopyAddrInfo(struct addrinfo* head) { 292 addresses_.Copy(head, true); 293} 294 295int SocketStream::DidEstablishConnection() { 296 if (!socket_.get() || !socket_->IsConnected()) { 297 next_state_ = STATE_CLOSE; 298 return ERR_CONNECTION_FAILED; 299 } 300 next_state_ = STATE_READ_WRITE; 301 metrics_->OnConnected(); 302 303 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); 304 if (delegate_) 305 delegate_->OnConnected(this, max_pending_send_allowed_); 306 307 return OK; 308} 309 310int SocketStream::DidReceiveData(int result) { 311 DCHECK(read_buf_); 312 DCHECK_GT(result, 0); 313 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_RECEIVED, NULL); 314 int len = result; 315 metrics_->OnRead(len); 316 if (delegate_) { 317 // Notify recevied data to delegate. 318 delegate_->OnReceivedData(this, read_buf_->data(), len); 319 } 320 read_buf_ = NULL; 321 return OK; 322} 323 324int SocketStream::DidSendData(int result) { 325 DCHECK_GT(result, 0); 326 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_SENT, NULL); 327 int len = result; 328 metrics_->OnWrite(len); 329 current_write_buf_ = NULL; 330 if (delegate_) 331 delegate_->OnSentData(this, len); 332 333 int remaining_size = write_buf_size_ - write_buf_offset_ - len; 334 if (remaining_size == 0) { 335 if (!pending_write_bufs_.empty()) { 336 write_buf_size_ = pending_write_bufs_.front()->size(); 337 write_buf_ = pending_write_bufs_.front(); 338 pending_write_bufs_.pop_front(); 339 } else { 340 write_buf_size_ = 0; 341 write_buf_ = NULL; 342 } 343 write_buf_offset_ = 0; 344 } else { 345 write_buf_offset_ += len; 346 } 347 return OK; 348} 349 350void SocketStream::OnIOCompleted(int result) { 351 DoLoop(result); 352} 353 354void SocketStream::OnReadCompleted(int result) { 355 if (result == 0) { 356 // 0 indicates end-of-file, so socket was closed. 357 // Don't close the socket if it's still writing. 358 server_closed_ = true; 359 } else if (result > 0 && read_buf_) { 360 result = DidReceiveData(result); 361 } 362 DoLoop(result); 363} 364 365void SocketStream::OnWriteCompleted(int result) { 366 if (result >= 0 && write_buf_) { 367 result = DidSendData(result); 368 } 369 DoLoop(result); 370} 371 372void SocketStream::DoLoop(int result) { 373 // If context was not set, close immediately. 374 if (!context_) 375 next_state_ = STATE_CLOSE; 376 377 if (next_state_ == STATE_NONE) 378 return; 379 380 do { 381 State state = next_state_; 382 next_state_ = STATE_NONE; 383 switch (state) { 384 case STATE_RESOLVE_PROXY: 385 DCHECK_EQ(OK, result); 386 result = DoResolveProxy(); 387 break; 388 case STATE_RESOLVE_PROXY_COMPLETE: 389 result = DoResolveProxyComplete(result); 390 break; 391 case STATE_RESOLVE_HOST: 392 DCHECK_EQ(OK, result); 393 result = DoResolveHost(); 394 break; 395 case STATE_RESOLVE_HOST_COMPLETE: 396 result = DoResolveHostComplete(result); 397 break; 398 case STATE_TCP_CONNECT: 399 result = DoTcpConnect(result); 400 break; 401 case STATE_TCP_CONNECT_COMPLETE: 402 result = DoTcpConnectComplete(result); 403 break; 404 case STATE_WRITE_TUNNEL_HEADERS: 405 DCHECK_EQ(OK, result); 406 result = DoWriteTunnelHeaders(); 407 break; 408 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE: 409 result = DoWriteTunnelHeadersComplete(result); 410 break; 411 case STATE_READ_TUNNEL_HEADERS: 412 DCHECK_EQ(OK, result); 413 result = DoReadTunnelHeaders(); 414 break; 415 case STATE_READ_TUNNEL_HEADERS_COMPLETE: 416 result = DoReadTunnelHeadersComplete(result); 417 break; 418 case STATE_SOCKS_CONNECT: 419 DCHECK_EQ(OK, result); 420 result = DoSOCKSConnect(); 421 break; 422 case STATE_SOCKS_CONNECT_COMPLETE: 423 result = DoSOCKSConnectComplete(result); 424 break; 425 case STATE_SSL_CONNECT: 426 DCHECK_EQ(OK, result); 427 result = DoSSLConnect(); 428 break; 429 case STATE_SSL_CONNECT_COMPLETE: 430 result = DoSSLConnectComplete(result); 431 break; 432 case STATE_READ_WRITE: 433 result = DoReadWrite(result); 434 break; 435 case STATE_AUTH_REQUIRED: 436 // It might be called when DoClose is called while waiting in 437 // STATE_AUTH_REQUIRED. 438 Finish(result); 439 return; 440 case STATE_CLOSE: 441 DCHECK_LE(result, OK); 442 Finish(result); 443 return; 444 default: 445 NOTREACHED() << "bad state " << state; 446 Finish(result); 447 return; 448 } 449 // If the connection is not established yet and had actual errors, 450 // close the connection. 451 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { 452 DCHECK_EQ(next_state_, STATE_CLOSE); 453 net_log_.EndEvent( 454 NetLog::TYPE_SOCKET_STREAM_CONNECT, 455 make_scoped_refptr(new NetLogIntegerParameter("net_error", result))); 456 } 457 } while (result != ERR_IO_PENDING); 458} 459 460int SocketStream::DoResolveProxy() { 461 DCHECK(!pac_request_); 462 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 463 464 if (!proxy_url_.is_valid()) { 465 next_state_ = STATE_CLOSE; 466 return ERR_INVALID_ARGUMENT; 467 } 468 469 return proxy_service()->ResolveProxy( 470 proxy_url_, &proxy_info_, &io_callback_, &pac_request_, net_log_); 471} 472 473int SocketStream::DoResolveProxyComplete(int result) { 474 pac_request_ = NULL; 475 if (result != OK) { 476 LOG(ERROR) << "Failed to resolve proxy: " << result; 477 if (delegate_) 478 delegate_->OnError(this, result); 479 proxy_info_.UseDirect(); 480 } 481 if (proxy_info_.is_direct()) { 482 // If proxy was not found for original URL (i.e. websocket URL), 483 // try again with https URL, like Safari implementation. 484 // Note that we don't want to use http proxy, because we'll use tunnel 485 // proxy using CONNECT method, which is used by https proxy. 486 if (!proxy_url_.SchemeIs("https")) { 487 const std::string scheme = "https"; 488 GURL::Replacements repl; 489 repl.SetSchemeStr(scheme); 490 proxy_url_ = url_.ReplaceComponents(repl); 491 DVLOG(1) << "Try https proxy: " << proxy_url_; 492 next_state_ = STATE_RESOLVE_PROXY; 493 return OK; 494 } 495 } 496 497 if (proxy_info_.is_empty()) { 498 // No proxies/direct to choose from. This happens when we don't support any 499 // of the proxies in the returned list. 500 return ERR_NO_SUPPORTED_PROXIES; 501 } 502 503 next_state_ = STATE_RESOLVE_HOST; 504 return OK; 505} 506 507int SocketStream::DoResolveHost() { 508 next_state_ = STATE_RESOLVE_HOST_COMPLETE; 509 510 DCHECK(!proxy_info_.is_empty()); 511 if (proxy_info_.is_direct()) 512 proxy_mode_ = kDirectConnection; 513 else if (proxy_info_.proxy_server().is_socks()) 514 proxy_mode_ = kSOCKSProxy; 515 else 516 proxy_mode_ = kTunnelProxy; 517 518 // Determine the host and port to connect to. 519 HostPortPair host_port_pair; 520 if (proxy_mode_ != kDirectConnection) { 521 host_port_pair = proxy_info_.proxy_server().host_port_pair(); 522 } else { 523 host_port_pair = HostPortPair::FromURL(url_); 524 } 525 526 HostResolver::RequestInfo resolve_info(host_port_pair); 527 528 DCHECK(host_resolver_); 529 resolver_.reset(new SingleRequestHostResolver(host_resolver_)); 530 return resolver_->Resolve(resolve_info, &addresses_, &io_callback_, 531 net_log_); 532} 533 534int SocketStream::DoResolveHostComplete(int result) { 535 if (result == OK && delegate_) { 536 next_state_ = STATE_TCP_CONNECT; 537 result = delegate_->OnStartOpenConnection(this, &io_callback_); 538 if (result == net::ERR_IO_PENDING) 539 metrics_->OnWaitConnection(); 540 } else { 541 next_state_ = STATE_CLOSE; 542 } 543 // TODO(ukai): if error occured, reconsider proxy after error. 544 return result; 545} 546 547int SocketStream::DoTcpConnect(int result) { 548 if (result != OK) { 549 next_state_ = STATE_CLOSE; 550 return result; 551 } 552 next_state_ = STATE_TCP_CONNECT_COMPLETE; 553 DCHECK(factory_); 554 socket_.reset(factory_->CreateTCPClientSocket(addresses_, 555 net_log_.net_log(), 556 net_log_.source())); 557 metrics_->OnStartConnection(); 558 return socket_->Connect(&io_callback_); 559} 560 561int SocketStream::DoTcpConnectComplete(int result) { 562 // TODO(ukai): if error occured, reconsider proxy after error. 563 if (result != OK) { 564 next_state_ = STATE_CLOSE; 565 return result; 566 } 567 568 if (proxy_mode_ == kTunnelProxy) 569 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 570 else if (proxy_mode_ == kSOCKSProxy) 571 next_state_ = STATE_SOCKS_CONNECT; 572 else if (is_secure()) { 573 next_state_ = STATE_SSL_CONNECT; 574 } else { 575 result = DidEstablishConnection(); 576 } 577 return result; 578} 579 580int SocketStream::DoWriteTunnelHeaders() { 581 DCHECK_EQ(kTunnelProxy, proxy_mode_); 582 583 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE; 584 585 if (!tunnel_request_headers_.get()) { 586 metrics_->OnTunnelProxy(); 587 tunnel_request_headers_ = new RequestHeaders(); 588 tunnel_request_headers_bytes_sent_ = 0; 589 } 590 if (tunnel_request_headers_->headers_.empty()) { 591 std::string authorization_headers; 592 593 if (!auth_handler_.get()) { 594 // Do preemptive authentication. 595 HttpAuthCache::Entry* entry = auth_cache_.LookupByPath( 596 ProxyAuthOrigin(), std::string()); 597 if (entry) { 598 scoped_ptr<HttpAuthHandler> handler_preemptive; 599 int rv_create = http_auth_handler_factory_-> 600 CreatePreemptiveAuthHandlerFromString( 601 entry->auth_challenge(), HttpAuth::AUTH_PROXY, 602 ProxyAuthOrigin(), entry->IncrementNonceCount(), 603 net_log_, &handler_preemptive); 604 if (rv_create == OK) { 605 auth_identity_.source = HttpAuth::IDENT_SRC_PATH_LOOKUP; 606 auth_identity_.invalid = false; 607 auth_identity_.username = entry->username(); 608 auth_identity_.password = entry->password(); 609 auth_handler_.swap(handler_preemptive); 610 } 611 } 612 } 613 614 // Support basic authentication scheme only, because we don't have 615 // HttpRequestInfo. 616 // TODO(ukai): Add support other authentication scheme. 617 if (auth_handler_.get() && auth_handler_->scheme() == "basic") { 618 HttpRequestInfo request_info; 619 std::string auth_token; 620 int rv = auth_handler_->GenerateAuthToken( 621 &auth_identity_.username, 622 &auth_identity_.password, 623 &request_info, 624 NULL, 625 &auth_token); 626 // TODO(cbentzel): Support async auth handlers. 627 DCHECK_NE(ERR_IO_PENDING, rv); 628 if (rv != OK) 629 return rv; 630 authorization_headers.append( 631 HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY) + 632 ": " + auth_token + "\r\n"); 633 } 634 635 tunnel_request_headers_->headers_ = base::StringPrintf( 636 "CONNECT %s HTTP/1.1\r\n" 637 "Host: %s\r\n" 638 "Proxy-Connection: keep-alive\r\n", 639 GetHostAndPort(url_).c_str(), 640 GetHostAndOptionalPort(url_).c_str()); 641 if (!authorization_headers.empty()) 642 tunnel_request_headers_->headers_ += authorization_headers; 643 tunnel_request_headers_->headers_ += "\r\n"; 644 } 645 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_); 646 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() - 647 tunnel_request_headers_bytes_sent_); 648 DCHECK_GT(buf_len, 0); 649 return socket_->Write(tunnel_request_headers_, buf_len, &io_callback_); 650} 651 652int SocketStream::DoWriteTunnelHeadersComplete(int result) { 653 DCHECK_EQ(kTunnelProxy, proxy_mode_); 654 655 if (result < 0) { 656 next_state_ = STATE_CLOSE; 657 return result; 658 } 659 660 tunnel_request_headers_bytes_sent_ += result; 661 if (tunnel_request_headers_bytes_sent_ < 662 tunnel_request_headers_->headers_.size()) 663 next_state_ = STATE_WRITE_TUNNEL_HEADERS; 664 else 665 next_state_ = STATE_READ_TUNNEL_HEADERS; 666 return OK; 667} 668 669int SocketStream::DoReadTunnelHeaders() { 670 DCHECK_EQ(kTunnelProxy, proxy_mode_); 671 672 next_state_ = STATE_READ_TUNNEL_HEADERS_COMPLETE; 673 674 if (!tunnel_response_headers_.get()) { 675 tunnel_response_headers_ = new ResponseHeaders(); 676 tunnel_response_headers_capacity_ = kMaxTunnelResponseHeadersSize; 677 tunnel_response_headers_->Realloc(tunnel_response_headers_capacity_); 678 tunnel_response_headers_len_ = 0; 679 } 680 681 int buf_len = tunnel_response_headers_capacity_ - 682 tunnel_response_headers_len_; 683 tunnel_response_headers_->SetDataOffset(tunnel_response_headers_len_); 684 CHECK(tunnel_response_headers_->data()); 685 686 return socket_->Read(tunnel_response_headers_, buf_len, &io_callback_); 687} 688 689int SocketStream::DoReadTunnelHeadersComplete(int result) { 690 DCHECK_EQ(kTunnelProxy, proxy_mode_); 691 692 if (result < 0) { 693 next_state_ = STATE_CLOSE; 694 return result; 695 } 696 697 if (result == 0) { 698 // 0 indicates end-of-file, so socket was closed. 699 next_state_ = STATE_CLOSE; 700 return ERR_CONNECTION_CLOSED; 701 } 702 703 tunnel_response_headers_len_ += result; 704 DCHECK(tunnel_response_headers_len_ <= tunnel_response_headers_capacity_); 705 706 int eoh = HttpUtil::LocateEndOfHeaders( 707 tunnel_response_headers_->headers(), tunnel_response_headers_len_, 0); 708 if (eoh == -1) { 709 if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize) { 710 next_state_ = STATE_CLOSE; 711 return ERR_RESPONSE_HEADERS_TOO_BIG; 712 } 713 714 next_state_ = STATE_READ_TUNNEL_HEADERS; 715 return OK; 716 } 717 // DidReadResponseHeaders 718 scoped_refptr<HttpResponseHeaders> headers; 719 headers = new HttpResponseHeaders( 720 HttpUtil::AssembleRawHeaders(tunnel_response_headers_->headers(), eoh)); 721 if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { 722 // Require the "HTTP/1.x" status line. 723 next_state_ = STATE_CLOSE; 724 return ERR_TUNNEL_CONNECTION_FAILED; 725 } 726 switch (headers->response_code()) { 727 case 200: // OK 728 if (is_secure()) { 729 DCHECK_EQ(eoh, tunnel_response_headers_len_); 730 next_state_ = STATE_SSL_CONNECT; 731 } else { 732 result = DidEstablishConnection(); 733 if (result < 0) { 734 next_state_ = STATE_CLOSE; 735 return result; 736 } 737 if ((eoh < tunnel_response_headers_len_) && delegate_) 738 delegate_->OnReceivedData( 739 this, tunnel_response_headers_->headers() + eoh, 740 tunnel_response_headers_len_ - eoh); 741 } 742 return OK; 743 case 407: // Proxy Authentication Required. 744 result = HandleAuthChallenge(headers.get()); 745 if (result == ERR_PROXY_AUTH_UNSUPPORTED && 746 auth_handler_.get() && delegate_) { 747 DCHECK(!proxy_info_.is_empty()); 748 auth_info_ = new AuthChallengeInfo; 749 auth_info_->is_proxy = true; 750 auth_info_->host_and_port = 751 ASCIIToWide(proxy_info_.proxy_server().host_port_pair().ToString()); 752 auth_info_->scheme = ASCIIToWide(auth_handler_->scheme()); 753 auth_info_->realm = ASCIIToWide(auth_handler_->realm()); 754 // Wait until RestartWithAuth or Close is called. 755 MessageLoop::current()->PostTask( 756 FROM_HERE, 757 NewRunnableMethod(this, &SocketStream::DoAuthRequired)); 758 next_state_ = STATE_AUTH_REQUIRED; 759 return ERR_IO_PENDING; 760 } 761 default: 762 break; 763 } 764 next_state_ = STATE_CLOSE; 765 return ERR_TUNNEL_CONNECTION_FAILED; 766} 767 768int SocketStream::DoSOCKSConnect() { 769 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 770 771 next_state_ = STATE_SOCKS_CONNECT_COMPLETE; 772 773 ClientSocket* s = socket_.release(); 774 HostResolver::RequestInfo req_info(HostPortPair::FromURL(url_)); 775 776 DCHECK(!proxy_info_.is_empty()); 777 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) 778 s = new SOCKS5ClientSocket(s, req_info); 779 else 780 s = new SOCKSClientSocket(s, req_info, host_resolver_); 781 socket_.reset(s); 782 metrics_->OnSOCKSProxy(); 783 return socket_->Connect(&io_callback_); 784} 785 786int SocketStream::DoSOCKSConnectComplete(int result) { 787 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 788 789 if (result == OK) { 790 if (is_secure()) 791 next_state_ = STATE_SSL_CONNECT; 792 else 793 result = DidEstablishConnection(); 794 } else { 795 next_state_ = STATE_CLOSE; 796 } 797 return result; 798} 799 800int SocketStream::DoSSLConnect() { 801 DCHECK(factory_); 802 // TODO(agl): look into plumbing SSLHostInfo here. 803 socket_.reset(factory_->CreateSSLClientSocket(socket_.release(), 804 HostPortPair::FromURL(url_), 805 ssl_config_, 806 NULL /* ssl_host_info */, 807 cert_verifier_)); 808 next_state_ = STATE_SSL_CONNECT_COMPLETE; 809 metrics_->OnSSLConnection(); 810 return socket_->Connect(&io_callback_); 811} 812 813int SocketStream::DoSSLConnectComplete(int result) { 814 if (IsCertificateError(result)) { 815 if (socket_->IsConnectedAndIdle()) { 816 result = HandleCertificateError(result); 817 } else { 818 // SSLClientSocket for Mac will report socket is not connected, 819 // if it returns cert verification error. It didn't perform 820 // SSLHandshake yet. 821 // So, we should restart establishing connection with the 822 // certificate in allowed bad certificates in |ssl_config_|. 823 // See also net/http/http_network_transaction.cc 824 // HandleCertificateError() and RestartIgnoringLastError(). 825 SSLClientSocket* ssl_socket = 826 reinterpret_cast<SSLClientSocket*>(socket_.get()); 827 SSLInfo ssl_info; 828 ssl_socket->GetSSLInfo(&ssl_info); 829 SSLConfig::CertAndStatus bad_cert; 830 bad_cert.cert = ssl_info.cert; 831 bad_cert.cert_status = ssl_info.cert_status; 832 if (ssl_config_.IsAllowedBadCert(ssl_info.cert)) { 833 // If we already have the certificate in the set of allowed bad 834 // certificates, we did try it and failed again, so we should not 835 // retry again: the connection should fail at last. 836 next_state_ = STATE_CLOSE; 837 return result; 838 } 839 // Add the bad certificate to the set of allowed certificates in the 840 // SSL info object. 841 ssl_config_.allowed_bad_certs.push_back(bad_cert); 842 // Restart connection ignoring the bad certificate. 843 socket_->Disconnect(); 844 socket_.reset(); 845 next_state_ = STATE_TCP_CONNECT; 846 return OK; 847 } 848 } 849 850 if (result == OK) 851 result = DidEstablishConnection(); 852 else 853 next_state_ = STATE_CLOSE; 854 return result; 855} 856 857int SocketStream::DoReadWrite(int result) { 858 if (result < OK) { 859 next_state_ = STATE_CLOSE; 860 return result; 861 } 862 if (!socket_.get() || !socket_->IsConnected()) { 863 next_state_ = STATE_CLOSE; 864 return ERR_CONNECTION_CLOSED; 865 } 866 867 // If client has requested close(), and there's nothing to write, then 868 // let's close the socket. 869 // We don't care about receiving data after the socket is closed. 870 if (closing_ && !write_buf_ && pending_write_bufs_.empty()) { 871 socket_->Disconnect(); 872 next_state_ = STATE_CLOSE; 873 return OK; 874 } 875 876 next_state_ = STATE_READ_WRITE; 877 878 // If server already closed the socket, we don't try to read. 879 if (!server_closed_) { 880 if (!read_buf_) { 881 // No read pending and server didn't close the socket. 882 read_buf_ = new IOBuffer(kReadBufferSize); 883 result = socket_->Read(read_buf_, kReadBufferSize, &read_callback_); 884 if (result > 0) { 885 return DidReceiveData(result); 886 } else if (result == 0) { 887 // 0 indicates end-of-file, so socket was closed. 888 next_state_ = STATE_CLOSE; 889 server_closed_ = true; 890 return ERR_CONNECTION_CLOSED; 891 } 892 // If read is pending, try write as well. 893 // Otherwise, return the result and do next loop (to close the 894 // connection). 895 if (result != ERR_IO_PENDING) { 896 next_state_ = STATE_CLOSE; 897 server_closed_ = true; 898 return result; 899 } 900 } 901 // Read is pending. 902 DCHECK(read_buf_); 903 } 904 905 if (write_buf_ && !current_write_buf_) { 906 // No write pending. 907 current_write_buf_ = new DrainableIOBuffer(write_buf_, write_buf_size_); 908 current_write_buf_->SetOffset(write_buf_offset_); 909 result = socket_->Write(current_write_buf_, 910 current_write_buf_->BytesRemaining(), 911 &write_callback_); 912 if (result > 0) { 913 return DidSendData(result); 914 } 915 // If write is not pending, return the result and do next loop (to close 916 // the connection). 917 if (result != 0 && result != ERR_IO_PENDING) { 918 next_state_ = STATE_CLOSE; 919 return result; 920 } 921 return result; 922 } 923 924 // We arrived here when both operation is pending. 925 return ERR_IO_PENDING; 926} 927 928GURL SocketStream::ProxyAuthOrigin() const { 929 DCHECK(!proxy_info_.is_empty()); 930 return GURL("http://" + 931 proxy_info_.proxy_server().host_port_pair().ToString()); 932} 933 934int SocketStream::HandleAuthChallenge(const HttpResponseHeaders* headers) { 935 GURL auth_origin(ProxyAuthOrigin()); 936 937 VLOG(1) << "The proxy " << auth_origin << " requested auth"; 938 939 // TODO(cbentzel): Since SocketStream only suppports basic authentication 940 // right now, another challenge is always treated as a rejection. 941 // Ultimately this should be converted to use HttpAuthController like the 942 // HttpNetworkTransaction has. 943 if (auth_handler_.get() && !auth_identity_.invalid) { 944 if (auth_identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP) 945 auth_cache_.Remove(auth_origin, 946 auth_handler_->realm(), 947 auth_handler_->scheme(), 948 auth_identity_.username, 949 auth_identity_.password); 950 auth_handler_.reset(); 951 auth_identity_ = HttpAuth::Identity(); 952 } 953 954 auth_identity_.invalid = true; 955 std::set<std::string> disabled_schemes; 956 HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, headers, 957 HttpAuth::AUTH_PROXY, 958 auth_origin, disabled_schemes, 959 net_log_, &auth_handler_); 960 if (!auth_handler_.get()) { 961 LOG(ERROR) << "Can't perform auth to the proxy " << auth_origin; 962 return ERR_TUNNEL_CONNECTION_FAILED; 963 } 964 if (auth_handler_->NeedsIdentity()) { 965 // We only support basic authentication scheme now. 966 // TODO(ukai): Support other authentication scheme. 967 HttpAuthCache::Entry* entry = 968 auth_cache_.Lookup(auth_origin, auth_handler_->realm(), "basic"); 969 if (entry) { 970 auth_identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP; 971 auth_identity_.invalid = false; 972 auth_identity_.username = entry->username(); 973 auth_identity_.password = entry->password(); 974 // Restart with auth info. 975 } 976 return ERR_PROXY_AUTH_UNSUPPORTED; 977 } else { 978 auth_identity_.invalid = false; 979 } 980 return ERR_TUNNEL_CONNECTION_FAILED; 981} 982 983void SocketStream::DoAuthRequired() { 984 if (delegate_ && auth_info_.get()) 985 delegate_->OnAuthRequired(this, auth_info_.get()); 986 else 987 DoLoop(net::ERR_UNEXPECTED); 988} 989 990void SocketStream::DoRestartWithAuth() { 991 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED); 992 auth_cache_.Add(ProxyAuthOrigin(), 993 auth_handler_->realm(), 994 auth_handler_->scheme(), 995 auth_handler_->challenge(), 996 auth_identity_.username, 997 auth_identity_.password, 998 std::string()); 999 1000 tunnel_request_headers_ = NULL; 1001 tunnel_request_headers_bytes_sent_ = 0; 1002 tunnel_response_headers_ = NULL; 1003 tunnel_response_headers_capacity_ = 0; 1004 tunnel_response_headers_len_ = 0; 1005 1006 next_state_ = STATE_TCP_CONNECT; 1007 DoLoop(OK); 1008} 1009 1010int SocketStream::HandleCertificateError(int result) { 1011 // TODO(ukai): handle cert error properly. 1012 switch (result) { 1013 case ERR_CERT_COMMON_NAME_INVALID: 1014 case ERR_CERT_DATE_INVALID: 1015 case ERR_CERT_AUTHORITY_INVALID: 1016 result = OK; 1017 break; 1018 default: 1019 break; 1020 } 1021 return result; 1022} 1023 1024bool SocketStream::is_secure() const { 1025 return url_.SchemeIs("wss"); 1026} 1027 1028SSLConfigService* SocketStream::ssl_config_service() const { 1029 return context_->ssl_config_service(); 1030} 1031 1032ProxyService* SocketStream::proxy_service() const { 1033 return context_->proxy_service(); 1034} 1035 1036} // namespace net 1037