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