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