• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2006-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 #include "net/http/http_network_transaction.h"
6 
7 #include "base/format_macros.h"
8 #include "base/scoped_ptr.h"
9 #include "base/compiler_specific.h"
10 #include "base/field_trial.h"
11 #include "base/histogram.h"
12 #include "base/stats_counters.h"
13 #include "base/string_util.h"
14 #include "base/trace_event.h"
15 #include "build/build_config.h"
16 #include "net/base/connection_type_histograms.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/load_flags.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/net_util.h"
21 #include "net/base/ssl_cert_request_info.h"
22 #include "net/base/upload_data_stream.h"
23 #include "net/flip/flip_session.h"
24 #include "net/flip/flip_session_pool.h"
25 #include "net/flip/flip_stream.h"
26 #include "net/http/http_auth.h"
27 #include "net/http/http_auth_handler.h"
28 #include "net/http/http_basic_stream.h"
29 #include "net/http/http_chunked_decoder.h"
30 #include "net/http/http_network_session.h"
31 #include "net/http/http_request_info.h"
32 #include "net/http/http_response_headers.h"
33 #include "net/http/http_response_info.h"
34 #include "net/http/http_util.h"
35 #include "net/socket/client_socket_factory.h"
36 #include "net/socket/socks5_client_socket.h"
37 #include "net/socket/socks_client_socket.h"
38 #include "net/socket/ssl_client_socket.h"
39 
40 using base::Time;
41 
42 namespace net {
43 
44 namespace {
45 
BuildRequestHeaders(const HttpRequestInfo * request_info,const std::string & authorization_headers,const UploadDataStream * upload_data_stream,bool using_proxy,std::string * request_headers)46 void BuildRequestHeaders(const HttpRequestInfo* request_info,
47                          const std::string& authorization_headers,
48                          const UploadDataStream* upload_data_stream,
49                          bool using_proxy,
50                          std::string* request_headers) {
51   const std::string path = using_proxy ?
52       HttpUtil::SpecForRequest(request_info->url) :
53       HttpUtil::PathForRequest(request_info->url);
54   *request_headers =
55       StringPrintf("%s %s HTTP/1.1\r\nHost: %s\r\n",
56                    request_info->method.c_str(), path.c_str(),
57                    GetHostAndOptionalPort(request_info->url).c_str());
58 
59   // For compat with HTTP/1.0 servers and proxies:
60   if (using_proxy)
61     *request_headers += "Proxy-";
62   *request_headers += "Connection: keep-alive\r\n";
63 
64   if (!request_info->user_agent.empty()) {
65     StringAppendF(request_headers, "User-Agent: %s\r\n",
66                   request_info->user_agent.c_str());
67   }
68 
69   // Our consumer should have made sure that this is a safe referrer.  See for
70   // instance WebCore::FrameLoader::HideReferrer.
71   if (request_info->referrer.is_valid())
72     StringAppendF(request_headers, "Referer: %s\r\n",
73                   request_info->referrer.spec().c_str());
74 
75   // Add a content length header?
76   if (upload_data_stream) {
77     StringAppendF(request_headers, "Content-Length: %" PRIu64 "\r\n",
78                   upload_data_stream->size());
79   } else if (request_info->method == "POST" || request_info->method == "PUT" ||
80              request_info->method == "HEAD") {
81     // An empty POST/PUT request still needs a content length.  As for HEAD,
82     // IE and Safari also add a content length header.  Presumably it is to
83     // support sending a HEAD request to an URL that only expects to be sent a
84     // POST or some other method that normally would have a message body.
85     *request_headers += "Content-Length: 0\r\n";
86   }
87 
88   // Honor load flags that impact proxy caches.
89   if (request_info->load_flags & LOAD_BYPASS_CACHE) {
90     *request_headers += "Pragma: no-cache\r\nCache-Control: no-cache\r\n";
91   } else if (request_info->load_flags & LOAD_VALIDATE_CACHE) {
92     *request_headers += "Cache-Control: max-age=0\r\n";
93   }
94 
95   if (!authorization_headers.empty()) {
96     *request_headers += authorization_headers;
97   }
98 
99   // TODO(darin): Need to prune out duplicate headers.
100 
101   *request_headers += request_info->extra_headers;
102   *request_headers += "\r\n";
103 }
104 
105 // The HTTP CONNECT method for establishing a tunnel connection is documented
106 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and
107 // 5.3.
BuildTunnelRequest(const HttpRequestInfo * request_info,const std::string & authorization_headers,std::string * request_headers)108 void BuildTunnelRequest(const HttpRequestInfo* request_info,
109                         const std::string& authorization_headers,
110                         std::string* request_headers) {
111   // RFC 2616 Section 9 says the Host request-header field MUST accompany all
112   // HTTP/1.1 requests.  Add "Proxy-Connection: keep-alive" for compat with
113   // HTTP/1.0 proxies such as Squid (required for NTLM authentication).
114   *request_headers = StringPrintf(
115       "CONNECT %s HTTP/1.1\r\nHost: %s\r\nProxy-Connection: keep-alive\r\n",
116       GetHostAndPort(request_info->url).c_str(),
117       GetHostAndOptionalPort(request_info->url).c_str());
118 
119   if (!request_info->user_agent.empty())
120     StringAppendF(request_headers, "User-Agent: %s\r\n",
121                   request_info->user_agent.c_str());
122 
123   if (!authorization_headers.empty()) {
124     *request_headers += authorization_headers;
125   }
126 
127   *request_headers += "\r\n";
128 }
129 
130 }  // namespace
131 
132 //-----------------------------------------------------------------------------
133 
134 std::string* HttpNetworkTransaction::g_next_protos = NULL;
135 
HttpNetworkTransaction(HttpNetworkSession * session)136 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session)
137     : pending_auth_target_(HttpAuth::AUTH_NONE),
138       ALLOW_THIS_IN_INITIALIZER_LIST(
139           io_callback_(this, &HttpNetworkTransaction::OnIOComplete)),
140       user_callback_(NULL),
141       session_(session),
142       request_(NULL),
143       pac_request_(NULL),
144       connection_(new ClientSocketHandle),
145       reused_socket_(false),
146       headers_valid_(false),
147       logged_response_time(false),
148       using_ssl_(false),
149       proxy_mode_(kDirectConnection),
150       establishing_tunnel_(false),
151       embedded_identity_used_(false),
152       read_buf_len_(0),
153       next_state_(STATE_NONE) {
154   session->ssl_config_service()->GetSSLConfig(&ssl_config_);
155   if (g_next_protos)
156     ssl_config_.next_protos = *g_next_protos;
157 }
158 
159 // static
SetNextProtos(const std::string & next_protos)160 void HttpNetworkTransaction::SetNextProtos(const std::string& next_protos) {
161   delete g_next_protos;
162   g_next_protos = new std::string(next_protos);
163 }
164 
Start(const HttpRequestInfo * request_info,CompletionCallback * callback,LoadLog * load_log)165 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
166                                   CompletionCallback* callback,
167                                   LoadLog* load_log) {
168   SIMPLE_STATS_COUNTER("HttpNetworkTransaction.Count");
169 
170   load_log_ = load_log;
171   request_ = request_info;
172   start_time_ = base::Time::Now();
173 
174   next_state_ = STATE_RESOLVE_PROXY;
175   int rv = DoLoop(OK);
176   if (rv == ERR_IO_PENDING)
177     user_callback_ = callback;
178   return rv;
179 }
180 
RestartIgnoringLastError(CompletionCallback * callback)181 int HttpNetworkTransaction::RestartIgnoringLastError(
182     CompletionCallback* callback) {
183   if (connection_->socket()->IsConnectedAndIdle()) {
184     next_state_ = STATE_SEND_REQUEST;
185   } else {
186     connection_->socket()->Disconnect();
187     connection_->Reset();
188     next_state_ = STATE_INIT_CONNECTION;
189   }
190   int rv = DoLoop(OK);
191   if (rv == ERR_IO_PENDING)
192     user_callback_ = callback;
193   return rv;
194 }
195 
RestartWithCertificate(X509Certificate * client_cert,CompletionCallback * callback)196 int HttpNetworkTransaction::RestartWithCertificate(
197     X509Certificate* client_cert,
198     CompletionCallback* callback) {
199   ssl_config_.client_cert = client_cert;
200   if (client_cert) {
201     session_->ssl_client_auth_cache()->Add(GetHostAndPort(request_->url),
202                                            client_cert);
203   }
204   ssl_config_.send_client_cert = true;
205   next_state_ = STATE_INIT_CONNECTION;
206   // Reset the other member variables.
207   // Note: this is necessary only with SSL renegotiation.
208   ResetStateForRestart();
209   int rv = DoLoop(OK);
210   if (rv == ERR_IO_PENDING)
211     user_callback_ = callback;
212   return rv;
213 }
214 
RestartWithAuth(const std::wstring & username,const std::wstring & password,CompletionCallback * callback)215 int HttpNetworkTransaction::RestartWithAuth(
216     const std::wstring& username,
217     const std::wstring& password,
218     CompletionCallback* callback) {
219   HttpAuth::Target target = pending_auth_target_;
220   if (target == HttpAuth::AUTH_NONE) {
221     NOTREACHED();
222     return ERR_UNEXPECTED;
223   }
224 
225   pending_auth_target_ = HttpAuth::AUTH_NONE;
226 
227   DCHECK(auth_identity_[target].invalid ||
228          (username.empty() && password.empty()));
229 
230   if (auth_identity_[target].invalid) {
231     // Update the username/password.
232     auth_identity_[target].source = HttpAuth::IDENT_SRC_EXTERNAL;
233     auth_identity_[target].invalid = false;
234     auth_identity_[target].username = username;
235     auth_identity_[target].password = password;
236   }
237 
238   PrepareForAuthRestart(target);
239 
240   DCHECK(user_callback_ == NULL);
241   int rv = DoLoop(OK);
242   if (rv == ERR_IO_PENDING)
243     user_callback_ = callback;
244 
245   return rv;
246 }
247 
PrepareForAuthRestart(HttpAuth::Target target)248 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) {
249   DCHECK(HaveAuth(target));
250   DCHECK(auth_identity_[target].source != HttpAuth::IDENT_SRC_PATH_LOOKUP);
251 
252   // Add the auth entry to the cache before restarting. We don't know whether
253   // the identity is valid yet, but if it is valid we want other transactions
254   // to know about it. If an entry for (origin, handler->realm()) already
255   // exists, we update it.
256   //
257   // If auth_identity_[target].source is HttpAuth::IDENT_SRC_NONE,
258   // auth_identity_[target] contains no identity because identity is not
259   // required yet.
260   //
261   // TODO(wtc): For NTLM_SSPI, we add the same auth entry to the cache in
262   // round 1 and round 2, which is redundant but correct.  It would be nice
263   // to add an auth entry to the cache only once, preferrably in round 1.
264   // See http://crbug.com/21015.
265   bool has_auth_identity =
266       auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE;
267   if (has_auth_identity) {
268     session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target],
269         auth_identity_[target].username, auth_identity_[target].password,
270         AuthPath(target));
271   }
272 
273   bool keep_alive = false;
274   // Even if the server says the connection is keep-alive, we have to be
275   // able to find the end of each response in order to reuse the connection.
276   if (GetResponseHeaders()->IsKeepAlive() &&
277       http_stream_->CanFindEndOfResponse()) {
278     // If the response body hasn't been completely read, we need to drain
279     // it first.
280     if (!http_stream_->IsResponseBodyComplete()) {
281       next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
282       read_buf_ = new IOBuffer(kDrainBodyBufferSize);  // A bit bucket.
283       read_buf_len_ = kDrainBodyBufferSize;
284       return;
285     }
286     keep_alive = true;
287   }
288 
289   // We don't need to drain the response body, so we act as if we had drained
290   // the response body.
291   DidDrainBodyForAuthRestart(keep_alive);
292 }
293 
DidDrainBodyForAuthRestart(bool keep_alive)294 void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
295   if (keep_alive && connection_->socket()->IsConnectedAndIdle()) {
296     // We should call connection_->set_idle_time(), but this doesn't occur
297     // often enough to be worth the trouble.
298     next_state_ = STATE_SEND_REQUEST;
299     connection_->set_is_reused(true);
300     reused_socket_ = true;
301   } else {
302     next_state_ = STATE_INIT_CONNECTION;
303     connection_->socket()->Disconnect();
304     connection_->Reset();
305   }
306 
307   // Reset the other member variables.
308   ResetStateForRestart();
309 }
310 
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)311 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len,
312                                  CompletionCallback* callback) {
313   DCHECK(buf);
314   DCHECK_LT(0, buf_len);
315 
316   State next_state = STATE_NONE;
317 
318   // Are we using SPDY or HTTP?
319   if (spdy_stream_.get()) {
320     DCHECK(!http_stream_.get());
321     DCHECK(spdy_stream_->GetResponseInfo()->headers);
322     next_state = STATE_SPDY_READ_BODY;
323   } else {
324     scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
325     DCHECK(headers.get());
326     next_state = STATE_READ_BODY;
327 
328     if (!connection_->is_initialized())
329       return 0;  // connection_->has been reset.  Treat like EOF.
330 
331     if (establishing_tunnel_) {
332       // We're trying to read the body of the response but we're still trying
333       // to establish an SSL tunnel through the proxy.  We can't read these
334       // bytes when establishing a tunnel because they might be controlled by
335       // an active network attacker.  We don't worry about this for HTTP
336       // because an active network attacker can already control HTTP sessions.
337       // We reach this case when the user cancels a 407 proxy auth prompt.
338       // See http://crbug.com/8473.
339       DCHECK_EQ(407, headers->response_code());
340       LogBlockedTunnelResponse(headers->response_code());
341       return ERR_TUNNEL_CONNECTION_FAILED;
342     }
343   }
344 
345   read_buf_ = buf;
346   read_buf_len_ = buf_len;
347 
348   next_state_ = next_state;
349   int rv = DoLoop(OK);
350   if (rv == ERR_IO_PENDING)
351     user_callback_ = callback;
352   return rv;
353 }
354 
GetResponseInfo() const355 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const {
356   return ((headers_valid_ && response_.headers) || response_.ssl_info.cert ||
357           response_.cert_request_info) ? &response_ : NULL;
358 }
359 
GetLoadState() const360 LoadState HttpNetworkTransaction::GetLoadState() const {
361   // TODO(wtc): Define a new LoadState value for the
362   // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request.
363   switch (next_state_) {
364     case STATE_RESOLVE_PROXY_COMPLETE:
365       return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
366     case STATE_INIT_CONNECTION_COMPLETE:
367       return connection_->GetLoadState();
368     case STATE_SEND_REQUEST_COMPLETE:
369       return LOAD_STATE_SENDING_REQUEST;
370     case STATE_READ_HEADERS_COMPLETE:
371       return LOAD_STATE_WAITING_FOR_RESPONSE;
372     case STATE_READ_BODY_COMPLETE:
373       return LOAD_STATE_READING_RESPONSE;
374     default:
375       return LOAD_STATE_IDLE;
376   }
377 }
378 
GetUploadProgress() const379 uint64 HttpNetworkTransaction::GetUploadProgress() const {
380   if (!http_stream_.get())
381     return 0;
382 
383   return http_stream_->GetUploadProgress();
384 }
385 
~HttpNetworkTransaction()386 HttpNetworkTransaction::~HttpNetworkTransaction() {
387   // If we still have an open socket, then make sure to disconnect it so it
388   // won't call us back and we don't try to reuse it later on.
389   if (connection_.get() && connection_->is_initialized())
390     connection_->socket()->Disconnect();
391 
392   if (pac_request_)
393     session_->proxy_service()->CancelPacRequest(pac_request_);
394 
395   if (spdy_stream_.get())
396     spdy_stream_->Cancel();
397 }
398 
DoCallback(int rv)399 void HttpNetworkTransaction::DoCallback(int rv) {
400   DCHECK(rv != ERR_IO_PENDING);
401   DCHECK(user_callback_);
402 
403   // Since Run may result in Read being called, clear user_callback_ up front.
404   CompletionCallback* c = user_callback_;
405   user_callback_ = NULL;
406   c->Run(rv);
407 }
408 
OnIOComplete(int result)409 void HttpNetworkTransaction::OnIOComplete(int result) {
410   int rv = DoLoop(result);
411   if (rv != ERR_IO_PENDING)
412     DoCallback(rv);
413 }
414 
DoLoop(int result)415 int HttpNetworkTransaction::DoLoop(int result) {
416   DCHECK(next_state_ != STATE_NONE);
417 
418   int rv = result;
419   do {
420     State state = next_state_;
421     next_state_ = STATE_NONE;
422     switch (state) {
423       case STATE_RESOLVE_PROXY:
424         DCHECK_EQ(OK, rv);
425         TRACE_EVENT_BEGIN("http.resolve_proxy", request_, request_->url.spec());
426         rv = DoResolveProxy();
427         break;
428       case STATE_RESOLVE_PROXY_COMPLETE:
429         rv = DoResolveProxyComplete(rv);
430         TRACE_EVENT_END("http.resolve_proxy", request_, request_->url.spec());
431         break;
432       case STATE_INIT_CONNECTION:
433         DCHECK_EQ(OK, rv);
434         TRACE_EVENT_BEGIN("http.init_conn", request_, request_->url.spec());
435         rv = DoInitConnection();
436         break;
437       case STATE_INIT_CONNECTION_COMPLETE:
438         rv = DoInitConnectionComplete(rv);
439         TRACE_EVENT_END("http.init_conn", request_, request_->url.spec());
440         break;
441       case STATE_SOCKS_CONNECT:
442         DCHECK_EQ(OK, rv);
443         TRACE_EVENT_BEGIN("http.socks_connect", request_, request_->url.spec());
444         rv = DoSOCKSConnect();
445         break;
446       case STATE_SOCKS_CONNECT_COMPLETE:
447         rv = DoSOCKSConnectComplete(rv);
448         TRACE_EVENT_END("http.socks_connect", request_, request_->url.spec());
449         break;
450       case STATE_SSL_CONNECT:
451         DCHECK_EQ(OK, rv);
452         TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec());
453         rv = DoSSLConnect();
454         break;
455       case STATE_SSL_CONNECT_COMPLETE:
456         rv = DoSSLConnectComplete(rv);
457         TRACE_EVENT_END("http.ssl_connect", request_, request_->url.spec());
458         break;
459       case STATE_SEND_REQUEST:
460         DCHECK_EQ(OK, rv);
461         TRACE_EVENT_BEGIN("http.send_request", request_, request_->url.spec());
462         LoadLog::BeginEvent(load_log_,
463                             LoadLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST);
464         rv = DoSendRequest();
465         break;
466       case STATE_SEND_REQUEST_COMPLETE:
467         rv = DoSendRequestComplete(rv);
468         TRACE_EVENT_END("http.send_request", request_, request_->url.spec());
469         LoadLog::EndEvent(load_log_,
470                           LoadLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST);
471         break;
472       case STATE_READ_HEADERS:
473         DCHECK_EQ(OK, rv);
474         TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec());
475         LoadLog::BeginEvent(load_log_,
476                             LoadLog::TYPE_HTTP_TRANSACTION_READ_HEADERS);
477         rv = DoReadHeaders();
478         break;
479       case STATE_READ_HEADERS_COMPLETE:
480         rv = DoReadHeadersComplete(rv);
481         TRACE_EVENT_END("http.read_headers", request_, request_->url.spec());
482         LoadLog::EndEvent(load_log_,
483                           LoadLog::TYPE_HTTP_TRANSACTION_READ_HEADERS);
484         break;
485       case STATE_READ_BODY:
486         DCHECK_EQ(OK, rv);
487         TRACE_EVENT_BEGIN("http.read_body", request_, request_->url.spec());
488         LoadLog::BeginEvent(load_log_,
489                             LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY);
490         rv = DoReadBody();
491         break;
492       case STATE_READ_BODY_COMPLETE:
493         rv = DoReadBodyComplete(rv);
494         TRACE_EVENT_END("http.read_body", request_, request_->url.spec());
495         LoadLog::EndEvent(load_log_,
496                           LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY);
497         break;
498       case STATE_DRAIN_BODY_FOR_AUTH_RESTART:
499         DCHECK_EQ(OK, rv);
500         TRACE_EVENT_BEGIN("http.drain_body_for_auth_restart",
501                           request_, request_->url.spec());
502         LoadLog::BeginEvent(
503             load_log_,
504             LoadLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART);
505         rv = DoDrainBodyForAuthRestart();
506         break;
507       case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE:
508         rv = DoDrainBodyForAuthRestartComplete(rv);
509         TRACE_EVENT_END("http.drain_body_for_auth_restart",
510                         request_, request_->url.spec());
511         LoadLog::EndEvent(
512             load_log_,
513             LoadLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART);
514         break;
515       case STATE_SPDY_SEND_REQUEST:
516         DCHECK_EQ(OK, rv);
517         TRACE_EVENT_BEGIN("http.send_request", request_, request_->url.spec());
518         LoadLog::BeginEvent(load_log_,
519                             LoadLog::TYPE_FLIP_TRANSACTION_SEND_REQUEST);
520         rv = DoSpdySendRequest();
521         break;
522       case STATE_SPDY_SEND_REQUEST_COMPLETE:
523         rv = DoSpdySendRequestComplete(rv);
524         TRACE_EVENT_END("http.send_request", request_, request_->url.spec());
525         LoadLog::EndEvent(load_log_,
526                           LoadLog::TYPE_FLIP_TRANSACTION_SEND_REQUEST);
527         break;
528       case STATE_SPDY_READ_HEADERS:
529         DCHECK_EQ(OK, rv);
530         TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec());
531         LoadLog::BeginEvent(load_log_,
532                             LoadLog::TYPE_FLIP_TRANSACTION_READ_HEADERS);
533         rv = DoSpdyReadHeaders();
534         break;
535       case STATE_SPDY_READ_HEADERS_COMPLETE:
536         rv = DoSpdyReadHeadersComplete(rv);
537         TRACE_EVENT_END("http.read_headers", request_, request_->url.spec());
538         LoadLog::EndEvent(load_log_,
539                           LoadLog::TYPE_FLIP_TRANSACTION_READ_HEADERS);
540         break;
541       case STATE_SPDY_READ_BODY:
542         DCHECK_EQ(OK, rv);
543         TRACE_EVENT_BEGIN("http.read_body", request_, request_->url.spec());
544         LoadLog::BeginEvent(load_log_,
545                             LoadLog::TYPE_FLIP_TRANSACTION_READ_BODY);
546         rv = DoSpdyReadBody();
547         break;
548       case STATE_SPDY_READ_BODY_COMPLETE:
549         rv = DoSpdyReadBodyComplete(rv);
550         TRACE_EVENT_END("http.read_body", request_, request_->url.spec());
551         LoadLog::EndEvent(load_log_,
552                           LoadLog::TYPE_FLIP_TRANSACTION_READ_BODY);
553         break;
554       default:
555         NOTREACHED() << "bad state";
556         rv = ERR_FAILED;
557         break;
558     }
559   } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
560 
561   return rv;
562 }
563 
DoResolveProxy()564 int HttpNetworkTransaction::DoResolveProxy() {
565   DCHECK(!pac_request_);
566 
567   next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
568 
569   if (request_->load_flags & LOAD_BYPASS_PROXY) {
570     proxy_info_.UseDirect();
571     return OK;
572   }
573 
574   return session_->proxy_service()->ResolveProxy(
575       request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_);
576 }
577 
DoResolveProxyComplete(int result)578 int HttpNetworkTransaction::DoResolveProxyComplete(int result) {
579 
580   pac_request_ = NULL;
581 
582   if (result != OK) {
583     DLOG(ERROR) << "Failed to resolve proxy: " << result;
584     // Fall-back to direct when there were runtime errors in the PAC script,
585     // or some other failure with the settings.
586     proxy_info_.UseDirect();
587   }
588 
589   // Remove unsupported proxies from the list.
590   proxy_info_.RemoveProxiesWithoutScheme(
591       ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP |
592       ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5);
593 
594   // There are four possible outcomes of having run the ProxyService:
595   //   (1) The ProxyService decided we should connect through a proxy.
596   //   (2) The ProxyService decided we should direct-connect.
597   //   (3) The ProxyService decided we should give up, as there are no more
598   //       proxies to try (this is more likely to happen during
599   //       ReconsiderProxyAfterError()).
600   //   (4) The ProxyService failed (which can happen if the PAC script
601   //       we were configured with threw a runtime exception).
602   //
603   // It is important that we fail the connection in case (3) rather than
604   // falling-back to a direct connection, since sending traffic through
605   // a proxy may be integral to the user's privacy/security model.
606   //
607   // For example if a user had configured traffic to go through the TOR
608   // anonymizing proxy to protect their privacy, it would be bad if we
609   // silently fell-back to direct connect if the proxy server were to
610   // become unreachable.
611   //
612   // In case (4) it is less obvious what the right thing to do is. On the
613   // one hand, for consistency it would be natural to hard-fail as well.
614   // However, both Firefox 3.5 and Internet Explorer 8 will silently fall-back
615   // to DIRECT in this case, so we will do the same for compatibility.
616   //
617   // For more information, see:
618   // http://www.chromium.org/developers/design-documents/proxy-settings-fallback
619 
620   if (proxy_info_.is_empty()) {
621     // No proxies/direct to choose from. This happens when we don't support any
622     // of the proxies in the returned list.
623     return ERR_NO_SUPPORTED_PROXIES;
624   }
625 
626   next_state_ = STATE_INIT_CONNECTION;
627   return OK;
628 }
629 
DoInitConnection()630 int HttpNetworkTransaction::DoInitConnection() {
631   DCHECK(!connection_->is_initialized());
632   DCHECK(proxy_info_.proxy_server().is_valid());
633 
634   next_state_ = STATE_INIT_CONNECTION_COMPLETE;
635 
636   using_ssl_ = request_->url.SchemeIs("https");
637 
638   if (proxy_info_.is_direct())
639     proxy_mode_ = kDirectConnection;
640   else if (proxy_info_.proxy_server().is_socks())
641     proxy_mode_ = kSOCKSProxy;
642   else if (using_ssl_)
643     proxy_mode_ = kHTTPProxyUsingTunnel;
644   else
645     proxy_mode_ = kHTTPProxy;
646 
647   // Build the string used to uniquely identify connections of this type.
648   // Determine the host and port to connect to.
649   std::string connection_group;
650   std::string host;
651   int port;
652   if (proxy_mode_ != kDirectConnection) {
653     ProxyServer proxy_server = proxy_info_.proxy_server();
654     connection_group = "proxy/" + proxy_server.ToURI() + "/";
655     host = proxy_server.HostNoBrackets();
656     port = proxy_server.port();
657   } else {
658     host = request_->url.HostNoBrackets();
659     port = request_->url.EffectiveIntPort();
660   }
661 
662   // Use the fixed testing ports if they've been provided.
663   if (using_ssl_) {
664     if (session_->fixed_https_port() != 0)
665       port = session_->fixed_https_port();
666   } else if (session_->fixed_http_port() != 0) {
667     port = session_->fixed_http_port();
668   }
669 
670   // For a connection via HTTP proxy not using CONNECT, the connection
671   // is to the proxy server only. For all other cases
672   // (direct, HTTP proxy CONNECT, SOCKS), the connection is upto the
673   // url endpoint. Hence we append the url data into the connection_group.
674   if (proxy_mode_ != kHTTPProxy)
675     connection_group.append(request_->url.GetOrigin().spec());
676 
677   DCHECK(!connection_group.empty());
678 
679   HostResolver::RequestInfo resolve_info(host, port);
680   resolve_info.set_priority(request_->priority);
681 
682   // The referrer is used by the DNS prefetch system to correlate resolutions
683   // with the page that triggered them. It doesn't impact the actual addresses
684   // that we resolve to.
685   resolve_info.set_referrer(request_->referrer);
686 
687   // If the user is refreshing the page, bypass the host cache.
688   if (request_->load_flags & LOAD_BYPASS_CACHE ||
689       request_->load_flags & LOAD_DISABLE_CACHE) {
690     resolve_info.set_allow_cached_response(false);
691   }
692 
693   // Check first if we have a flip session for this group.  If so, then go
694   // straight to using that.
695   if (session_->flip_session_pool()->HasSession(resolve_info))
696     return OK;
697 
698   int rv = connection_->Init(connection_group, resolve_info, request_->priority,
699                              &io_callback_, session_->tcp_socket_pool(),
700                              load_log_);
701   return rv;
702 }
703 
DoInitConnectionComplete(int result)704 int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
705   if (result < 0) {
706     UpdateConnectionTypeHistograms(CONNECTION_HTTP, false);
707     return ReconsiderProxyAfterError(result);
708   }
709 
710   DCHECK_EQ(OK, result);
711 
712   // If we don't have an initialized connection, that means we have a flip
713   // connection waiting for us.
714   if (!connection_->is_initialized()) {
715     next_state_ = STATE_SPDY_SEND_REQUEST;
716     return OK;
717   }
718 
719   LogTCPConnectedMetrics(*connection_);
720 
721   // Set the reused_socket_ flag to indicate that we are using a keep-alive
722   // connection.  This flag is used to handle errors that occur while we are
723   // trying to reuse a keep-alive connection.
724   reused_socket_ = connection_->is_reused();
725   if (reused_socket_) {
726     next_state_ = STATE_SEND_REQUEST;
727   } else {
728     // Now we have a TCP connected socket.  Perform other connection setup as
729     // needed.
730     UpdateConnectionTypeHistograms(CONNECTION_HTTP, true);
731     if (proxy_mode_ == kSOCKSProxy)
732       next_state_ = STATE_SOCKS_CONNECT;
733     else if (using_ssl_ && proxy_mode_ == kDirectConnection) {
734       next_state_ = STATE_SSL_CONNECT;
735     } else {
736       next_state_ = STATE_SEND_REQUEST;
737       if (proxy_mode_ == kHTTPProxyUsingTunnel)
738         establishing_tunnel_ = true;
739     }
740   }
741 
742   return OK;
743 }
744 
DoSOCKSConnect()745 int HttpNetworkTransaction::DoSOCKSConnect() {
746   DCHECK_EQ(kSOCKSProxy, proxy_mode_);
747 
748   next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
749 
750   // Add a SOCKS connection on top of our existing transport socket.
751   ClientSocket* s = connection_->release_socket();
752   HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(),
753                                      request_->url.EffectiveIntPort());
754   req_info.set_referrer(request_->referrer);
755   req_info.set_priority(request_->priority);
756 
757   if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5)
758     s = new SOCKS5ClientSocket(s, req_info);
759   else
760     s = new SOCKSClientSocket(s, req_info, session_->host_resolver());
761   connection_->set_socket(s);
762   return connection_->socket()->Connect(&io_callback_, load_log_);
763 }
764 
DoSOCKSConnectComplete(int result)765 int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) {
766   DCHECK_EQ(kSOCKSProxy, proxy_mode_);
767 
768   if (result == OK) {
769     if (using_ssl_) {
770       next_state_ = STATE_SSL_CONNECT;
771     } else {
772       next_state_ = STATE_SEND_REQUEST;
773     }
774   } else {
775     result = ReconsiderProxyAfterError(result);
776   }
777   return result;
778 }
779 
DoSSLConnect()780 int HttpNetworkTransaction::DoSSLConnect() {
781   next_state_ = STATE_SSL_CONNECT_COMPLETE;
782 
783   if (request_->load_flags & LOAD_VERIFY_EV_CERT)
784     ssl_config_.verify_ev_cert = true;
785 
786   ssl_connect_start_time_ = base::TimeTicks::Now();
787 
788   // Add a SSL socket on top of our existing transport socket.
789   ClientSocket* s = connection_->release_socket();
790   s = session_->socket_factory()->CreateSSLClientSocket(
791       s, request_->url.HostNoBrackets(), ssl_config_);
792   connection_->set_socket(s);
793   return connection_->socket()->Connect(&io_callback_, load_log_);
794 }
795 
DoSSLConnectComplete(int result)796 int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
797   SSLClientSocket* ssl_socket =
798       reinterpret_cast<SSLClientSocket*>(connection_->socket());
799 
800   SSLClientSocket::NextProtoStatus status =
801       SSLClientSocket::kNextProtoUnsupported;
802   std::string proto;
803   // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
804   // that hasn't had SSL_ImportFD called on it. If we get a certificate error
805   // here, then we know that we called SSL_ImportFD.
806   if (result == OK || IsCertificateError(result))
807     status = ssl_socket->GetNextProto(&proto);
808   static const char kSpdyProto[] = "spdy";
809   const bool use_spdy = (status == SSLClientSocket::kNextProtoNegotiated &&
810                          proto == kSpdyProto);
811 
812   if (IsCertificateError(result)) {
813     if (use_spdy) {
814       // TODO(agl/willchan/wtc): We currently ignore certificate errors for
815       // spdy but we shouldn't. http://crbug.com/32020
816       result = OK;
817     } else {
818       result = HandleCertificateError(result);
819     }
820   }
821 
822   if (result == OK) {
823     DCHECK(ssl_connect_start_time_ != base::TimeTicks());
824     base::TimeDelta connect_duration =
825         base::TimeTicks::Now() - ssl_connect_start_time_;
826 
827     if (use_spdy) {
828       UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency",
829           connect_duration,
830           base::TimeDelta::FromMilliseconds(1),
831           base::TimeDelta::FromMinutes(10),
832           100);
833 
834       UpdateConnectionTypeHistograms(CONNECTION_SPDY, true);
835       next_state_ = STATE_SPDY_SEND_REQUEST;
836     } else {
837       UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency",
838           connect_duration,
839           base::TimeDelta::FromMilliseconds(1),
840           base::TimeDelta::FromMinutes(10),
841           100);
842 
843       next_state_ = STATE_SEND_REQUEST;
844     }
845   } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
846     result = HandleCertificateRequest(result);
847   } else {
848     result = HandleSSLHandshakeError(result);
849   }
850   return result;
851 }
852 
DoSendRequest()853 int HttpNetworkTransaction::DoSendRequest() {
854   next_state_ = STATE_SEND_REQUEST_COMPLETE;
855 
856   UploadDataStream* request_body = NULL;
857   if (!establishing_tunnel_ && request_->upload_data)
858     request_body = new UploadDataStream(request_->upload_data);
859 
860   // This is constructed lazily (instead of within our Start method), so that
861   // we have proxy info available.
862   if (request_headers_.empty()) {
863     // Figure out if we can/should add Proxy-Authentication & Authentication
864     // headers.
865     bool have_proxy_auth =
866         ShouldApplyProxyAuth() &&
867         (HaveAuth(HttpAuth::AUTH_PROXY) ||
868          SelectPreemptiveAuth(HttpAuth::AUTH_PROXY));
869     bool have_server_auth =
870         ShouldApplyServerAuth() &&
871         (HaveAuth(HttpAuth::AUTH_SERVER) ||
872          SelectPreemptiveAuth(HttpAuth::AUTH_SERVER));
873 
874     std::string authorization_headers;
875 
876     // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization
877     // header with no credentials), we should return an error to prevent
878     // entering an infinite auth restart loop.  See http://crbug.com/21050.
879     if (have_proxy_auth)
880       authorization_headers.append(
881           BuildAuthorizationHeader(HttpAuth::AUTH_PROXY));
882     if (have_server_auth)
883       authorization_headers.append(
884           BuildAuthorizationHeader(HttpAuth::AUTH_SERVER));
885 
886     if (establishing_tunnel_) {
887       BuildTunnelRequest(request_, authorization_headers, &request_headers_);
888     } else {
889       BuildRequestHeaders(request_, authorization_headers, request_body,
890                           proxy_mode_ == kHTTPProxy, &request_headers_);
891     }
892   }
893 
894   headers_valid_ = false;
895   http_stream_.reset(new HttpBasicStream(connection_.get(), load_log_));
896 
897   return http_stream_->SendRequest(request_, request_headers_,
898                                    request_body, &response_, &io_callback_);
899 }
900 
DoSendRequestComplete(int result)901 int HttpNetworkTransaction::DoSendRequestComplete(int result) {
902   if (result < 0)
903     return HandleIOError(result);
904 
905   next_state_ = STATE_READ_HEADERS;
906 
907   return OK;
908 }
909 
DoReadHeaders()910 int HttpNetworkTransaction::DoReadHeaders() {
911   next_state_ = STATE_READ_HEADERS_COMPLETE;
912 
913   return http_stream_->ReadResponseHeaders(&io_callback_);
914 }
915 
HandleConnectionClosedBeforeEndOfHeaders()916 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() {
917   if (establishing_tunnel_) {
918     // The connection was closed before the tunnel could be established.
919     return ERR_TUNNEL_CONNECTION_FAILED;
920   }
921 
922   if (!response_.headers) {
923     // The connection was closed before any data was sent. Likely an error
924     // rather than empty HTTP/0.9 response.
925     return ERR_EMPTY_RESPONSE;
926   }
927 
928   return OK;
929 }
930 
DoReadHeadersComplete(int result)931 int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
932   // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here
933   // due to SSL renegotiation.
934   if (using_ssl_) {
935     if (IsCertificateError(result)) {
936       // We don't handle a certificate error during SSL renegotiation, so we
937       // have to return an error that's not in the certificate error range
938       // (-2xx).
939       LOG(ERROR) << "Got a server certificate with error " << result
940                  << " during SSL renegotiation";
941       result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION;
942     } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
943       result = HandleCertificateRequest(result);
944       if (result == OK)
945         return result;
946     }
947   }
948 
949   if (result < 0 && result != ERR_CONNECTION_CLOSED)
950     return HandleIOError(result);
951 
952   if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) {
953     ResetConnectionAndRequestForResend();
954     return OK;
955   }
956 
957   // After we call RestartWithAuth a new response_time will be recorded, and
958   // we need to be cautious about incorrectly logging the duration across the
959   // authentication activity.
960   if (!logged_response_time) {
961     LogTransactionConnectedMetrics();
962     logged_response_time = true;
963   }
964 
965   if (result == ERR_CONNECTION_CLOSED) {
966     int rv = HandleConnectionClosedBeforeEndOfHeaders();
967     if (rv != OK)
968       return rv;
969     // TODO(wtc): Traditionally this code has returned 0 when reading a closed
970     // socket.  That is partially corrected in classes that we call, but
971     // callers need to be updated.
972     result = 0;
973   }
974 
975   if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
976     // Require the "HTTP/1.x" status line for SSL CONNECT.
977     if (establishing_tunnel_)
978       return ERR_TUNNEL_CONNECTION_FAILED;
979 
980     // HTTP/0.9 doesn't support the PUT method, so lack of response headers
981     // indicates a buggy server.  See:
982     // https://bugzilla.mozilla.org/show_bug.cgi?id=193921
983     if (request_->method == "PUT")
984       return ERR_METHOD_NOT_SUPPORTED;
985   }
986 
987   if (establishing_tunnel_) {
988     switch (response_.headers->response_code()) {
989       case 200:  // OK
990         if (http_stream_->IsMoreDataBuffered()) {
991           // The proxy sent extraneous data after the headers.
992           return ERR_TUNNEL_CONNECTION_FAILED;
993         }
994         next_state_ = STATE_SSL_CONNECT;
995         // Reset for the real request and response headers.
996         request_headers_.clear();
997         http_stream_.reset(new HttpBasicStream(connection_.get(), load_log_));
998         headers_valid_ = false;
999         establishing_tunnel_ = false;
1000         return OK;
1001 
1002       // We aren't able to CONNECT to the remote host through the proxy.  We
1003       // need to be very suspicious about the response because an active network
1004       // attacker can force us into this state by masquerading as the proxy.
1005       // The only safe thing to do here is to fail the connection because our
1006       // client is expecting an SSL protected response.
1007       // See http://crbug.com/7338.
1008       case 407:  // Proxy Authentication Required
1009         // We need this status code to allow proxy authentication.  Our
1010         // authentication code is smart enough to avoid being tricked by an
1011         // active network attacker.
1012         break;
1013       default:
1014         // For all other status codes, we conservatively fail the CONNECT
1015         // request.
1016         // We lose something by doing this.  We have seen proxy 403, 404, and
1017         // 501 response bodies that contain a useful error message.  For
1018         // example, Squid uses a 404 response to report the DNS error: "The
1019         // domain name does not exist."
1020         LogBlockedTunnelResponse(response_.headers->response_code());
1021         return ERR_TUNNEL_CONNECTION_FAILED;
1022     }
1023   }
1024 
1025   // Check for an intermediate 100 Continue response.  An origin server is
1026   // allowed to send this response even if we didn't ask for it, so we just
1027   // need to skip over it.
1028   // We treat any other 1xx in this same way (although in practice getting
1029   // a 1xx that isn't a 100 is rare).
1030   if (response_.headers->response_code() / 100 == 1) {
1031     response_.headers = new HttpResponseHeaders("");
1032     next_state_ = STATE_READ_HEADERS;
1033     return OK;
1034   }
1035 
1036   int rv = HandleAuthChallenge();
1037   if (rv != OK)
1038     return rv;
1039 
1040   if (using_ssl_ && !establishing_tunnel_) {
1041     SSLClientSocket* ssl_socket =
1042         reinterpret_cast<SSLClientSocket*>(connection_->socket());
1043     ssl_socket->GetSSLInfo(&response_.ssl_info);
1044   }
1045 
1046   headers_valid_ = true;
1047   return OK;
1048 }
1049 
DoReadBody()1050 int HttpNetworkTransaction::DoReadBody() {
1051   DCHECK(read_buf_);
1052   DCHECK_GT(read_buf_len_, 0);
1053   DCHECK(connection_->is_initialized());
1054 
1055   next_state_ = STATE_READ_BODY_COMPLETE;
1056   return http_stream_->ReadResponseBody(read_buf_, read_buf_len_,
1057                                         &io_callback_);
1058 }
1059 
DoReadBodyComplete(int result)1060 int HttpNetworkTransaction::DoReadBodyComplete(int result) {
1061   // We are done with the Read call.
1062   DCHECK(!establishing_tunnel_) <<
1063       "We should never read a response body of a tunnel.";
1064 
1065   bool done = false, keep_alive = false;
1066   if (result < 0) {
1067     // Error or closed connection while reading the socket.
1068     done = true;
1069     // TODO(wtc): Traditionally this code has returned 0 when reading a closed
1070     // socket.  That is partially corrected in classes that we call, but
1071     // callers need to be updated.
1072     if (result == ERR_CONNECTION_CLOSED)
1073       result = 0;
1074   } else if (http_stream_->IsResponseBodyComplete()) {
1075     done = true;
1076     keep_alive = GetResponseHeaders()->IsKeepAlive();
1077   }
1078 
1079   // Clean up connection_->if we are done.
1080   if (done) {
1081     LogTransactionMetrics();
1082     if (!keep_alive)
1083       connection_->socket()->Disconnect();
1084     connection_->Reset();
1085     // The next Read call will return 0 (EOF).
1086   }
1087 
1088   // Clear these to avoid leaving around old state.
1089   read_buf_ = NULL;
1090   read_buf_len_ = 0;
1091 
1092   return result;
1093 }
1094 
DoDrainBodyForAuthRestart()1095 int HttpNetworkTransaction::DoDrainBodyForAuthRestart() {
1096   // This method differs from DoReadBody only in the next_state_.  So we just
1097   // call DoReadBody and override the next_state_.  Perhaps there is a more
1098   // elegant way for these two methods to share code.
1099   int rv = DoReadBody();
1100   DCHECK(next_state_ == STATE_READ_BODY_COMPLETE);
1101   next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE;
1102   return rv;
1103 }
1104 
1105 // TODO(wtc): This method and the DoReadBodyComplete method are almost
1106 // the same.  Figure out a good way for these two methods to share code.
DoDrainBodyForAuthRestartComplete(int result)1107 int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) {
1108   // keep_alive defaults to true because the very reason we're draining the
1109   // response body is to reuse the connection for auth restart.
1110   bool done = false, keep_alive = true;
1111   if (result < 0) {
1112     // Error or closed connection while reading the socket.
1113     done = true;
1114     keep_alive = false;
1115   } else if (http_stream_->IsResponseBodyComplete()) {
1116     done = true;
1117   }
1118 
1119   if (done) {
1120     DidDrainBodyForAuthRestart(keep_alive);
1121   } else {
1122     // Keep draining.
1123     next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
1124   }
1125 
1126   return OK;
1127 }
1128 
DoSpdySendRequest()1129 int HttpNetworkTransaction::DoSpdySendRequest() {
1130   next_state_ = STATE_SPDY_SEND_REQUEST_COMPLETE;
1131   CHECK(!spdy_stream_.get());
1132 
1133   // First we get a SPDY session.  Theoretically, we've just negotiated one, but
1134   // if one already exists, then screw it, use the existing one!  Otherwise,
1135   // use the existing TCP socket.
1136 
1137   HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(),
1138                                      request_->url.EffectiveIntPort());
1139   req_info.set_priority(request_->priority);
1140   const scoped_refptr<FlipSessionPool> spdy_pool =
1141       session_->flip_session_pool();
1142   scoped_refptr<FlipSession> spdy_session;
1143 
1144   if (spdy_pool->HasSession(req_info)) {
1145     spdy_session = spdy_pool->Get(req_info, session_);
1146   } else {
1147     spdy_session = spdy_pool->GetFlipSessionFromSocket(
1148         req_info, session_, connection_.release());
1149   }
1150 
1151   CHECK(spdy_session.get());
1152 
1153   UploadDataStream* upload_data = request_->upload_data ?
1154       new UploadDataStream(request_->upload_data) : NULL;
1155   headers_valid_ = false;
1156   spdy_stream_ = spdy_session->GetOrCreateStream(
1157       *request_, upload_data, load_log_);
1158   return spdy_stream_->SendRequest(upload_data, &response_, &io_callback_);
1159 }
1160 
DoSpdySendRequestComplete(int result)1161 int HttpNetworkTransaction::DoSpdySendRequestComplete(int result) {
1162   if (result < 0)
1163     return result;
1164 
1165   next_state_ = STATE_SPDY_READ_HEADERS;
1166   return OK;
1167 }
1168 
DoSpdyReadHeaders()1169 int HttpNetworkTransaction::DoSpdyReadHeaders() {
1170   next_state_ = STATE_SPDY_READ_HEADERS_COMPLETE;
1171   return spdy_stream_->ReadResponseHeaders(&io_callback_);
1172 }
1173 
DoSpdyReadHeadersComplete(int result)1174 int HttpNetworkTransaction::DoSpdyReadHeadersComplete(int result) {
1175   // TODO(willchan): Flesh out the support for HTTP authentication here.
1176   if (result == OK)
1177     headers_valid_ = true;
1178   return result;
1179 }
1180 
DoSpdyReadBody()1181 int HttpNetworkTransaction::DoSpdyReadBody() {
1182   next_state_ = STATE_SPDY_READ_BODY_COMPLETE;
1183 
1184   return spdy_stream_->ReadResponseBody(
1185       read_buf_, read_buf_len_, &io_callback_);
1186 }
1187 
DoSpdyReadBodyComplete(int result)1188 int HttpNetworkTransaction::DoSpdyReadBodyComplete(int result) {
1189   read_buf_ = NULL;
1190   read_buf_len_ = 0;
1191 
1192   if (result <= 0)
1193     spdy_stream_ = NULL;
1194 
1195   return result;
1196 }
1197 
LogTCPConnectedMetrics(const ClientSocketHandle & handle)1198 void HttpNetworkTransaction::LogTCPConnectedMetrics(
1199     const ClientSocketHandle& handle) {
1200   const base::TimeDelta time_to_obtain_connected_socket =
1201       base::TimeTicks::Now() - handle.init_time();
1202 
1203   static const bool use_late_binding_histogram =
1204       !FieldTrial::MakeName("", "SocketLateBinding").empty();
1205 
1206   if (handle.reuse_type() == ClientSocketHandle::UNUSED) {
1207     UMA_HISTOGRAM_CUSTOM_TIMES(
1208         "Net.HttpConnectionLatency",
1209         time_to_obtain_connected_socket,
1210         base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1211         100);
1212   }
1213 
1214   UMA_HISTOGRAM_ENUMERATION("Net.TCPSocketType", handle.reuse_type(),
1215       ClientSocketHandle::NUM_TYPES);
1216 
1217   if (use_late_binding_histogram) {
1218     UMA_HISTOGRAM_ENUMERATION(
1219         FieldTrial::MakeName("Net.TCPSocketType", "SocketLateBinding"),
1220         handle.reuse_type(), ClientSocketHandle::NUM_TYPES);
1221   }
1222 
1223   UMA_HISTOGRAM_CLIPPED_TIMES(
1224       "Net.TransportSocketRequestTime",
1225       time_to_obtain_connected_socket,
1226       base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1227       100);
1228 
1229   if (use_late_binding_histogram) {
1230     UMA_HISTOGRAM_CUSTOM_TIMES(
1231         FieldTrial::MakeName("Net.TransportSocketRequestTime",
1232                              "SocketLateBinding").data(),
1233         time_to_obtain_connected_socket,
1234         base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1235         100);
1236   }
1237 
1238   switch (handle.reuse_type()) {
1239     case ClientSocketHandle::UNUSED:
1240       break;
1241     case ClientSocketHandle::UNUSED_IDLE:
1242       UMA_HISTOGRAM_CUSTOM_TIMES(
1243           "Net.SocketIdleTimeBeforeNextUse_UnusedSocket",
1244           handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1245           base::TimeDelta::FromMinutes(6), 100);
1246       if (use_late_binding_histogram) {
1247         UMA_HISTOGRAM_CUSTOM_TIMES(
1248             FieldTrial::MakeName("Net.SocketIdleTimeBeforeNextUse_UnusedSocket",
1249                                  "SocketLateBinding").data(),
1250             handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1251             base::TimeDelta::FromMinutes(6), 100);
1252       }
1253       break;
1254     case ClientSocketHandle::REUSED_IDLE:
1255       UMA_HISTOGRAM_CUSTOM_TIMES(
1256           "Net.SocketIdleTimeBeforeNextUse_ReusedSocket",
1257           handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1258           base::TimeDelta::FromMinutes(6), 100);
1259       if (use_late_binding_histogram) {
1260         UMA_HISTOGRAM_CUSTOM_TIMES(
1261             FieldTrial::MakeName("Net.SocketIdleTimeBeforeNextUse_ReusedSocket",
1262                                  "SocketLateBinding").data(),
1263             handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1264             base::TimeDelta::FromMinutes(6), 100);
1265       }
1266       break;
1267     default:
1268       NOTREACHED();
1269       break;
1270   }
1271 }
1272 
LogIOErrorMetrics(const ClientSocketHandle & handle)1273 void HttpNetworkTransaction::LogIOErrorMetrics(
1274     const ClientSocketHandle& handle) {
1275   static const bool use_late_binding_histogram =
1276       !FieldTrial::MakeName("", "SocketLateBinding").empty();
1277 
1278   UMA_HISTOGRAM_ENUMERATION("Net.IOError_SocketReuseType",
1279        handle.reuse_type(), ClientSocketHandle::NUM_TYPES);
1280 
1281   if (use_late_binding_histogram) {
1282     UMA_HISTOGRAM_ENUMERATION(
1283         FieldTrial::MakeName("Net.IOError_SocketReuseType",
1284                              "SocketLateBinding"),
1285         handle.reuse_type(), ClientSocketHandle::NUM_TYPES);
1286   }
1287 
1288   switch (handle.reuse_type()) {
1289     case ClientSocketHandle::UNUSED:
1290       break;
1291     case ClientSocketHandle::UNUSED_IDLE:
1292       UMA_HISTOGRAM_CUSTOM_TIMES(
1293           "Net.SocketIdleTimeOnIOError2_UnusedSocket",
1294           handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1295           base::TimeDelta::FromMinutes(6), 100);
1296       if (use_late_binding_histogram) {
1297         UMA_HISTOGRAM_CUSTOM_TIMES(
1298             FieldTrial::MakeName("Net.SocketIdleTimeOnIOError2_UnusedSocket",
1299                                  "SocketLateBinding").data(),
1300             handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1301             base::TimeDelta::FromMinutes(6), 100);
1302       }
1303       break;
1304     case ClientSocketHandle::REUSED_IDLE:
1305       UMA_HISTOGRAM_CUSTOM_TIMES(
1306           "Net.SocketIdleTimeOnIOError2_ReusedSocket",
1307           handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1308           base::TimeDelta::FromMinutes(6), 100);
1309       if (use_late_binding_histogram) {
1310         UMA_HISTOGRAM_CUSTOM_TIMES(
1311             FieldTrial::MakeName("Net.SocketIdleTimeOnIOError2_ReusedSocket",
1312                                  "SocketLateBinding").data(),
1313             handle.idle_time(), base::TimeDelta::FromMilliseconds(1),
1314             base::TimeDelta::FromMinutes(6), 100);
1315       }
1316       break;
1317     default:
1318       NOTREACHED();
1319       break;
1320   }
1321 }
1322 
LogTransactionConnectedMetrics() const1323 void HttpNetworkTransaction::LogTransactionConnectedMetrics() const {
1324   base::TimeDelta total_duration = response_.response_time - start_time_;
1325 
1326   UMA_HISTOGRAM_CLIPPED_TIMES(
1327       "Net.Transaction_Connected_Under_10",
1328       total_duration,
1329       base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1330       100);
1331 
1332   static const bool use_late_binding_histogram =
1333       !FieldTrial::MakeName("", "SocketLateBinding").empty();
1334 
1335   if (use_late_binding_histogram) {
1336     UMA_HISTOGRAM_CUSTOM_TIMES(
1337         FieldTrial::MakeName("Net.Transaction_Connected_Under_10",
1338                              "SocketLateBinding").data(),
1339         total_duration,
1340         base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1341         100);
1342   }
1343 
1344   if (!reused_socket_) {
1345     UMA_HISTOGRAM_CLIPPED_TIMES(
1346         "Net.Transaction_Connected_New",
1347         total_duration,
1348         base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1349         100);
1350   }
1351 
1352   // Currently, non-zero priority requests are frame or sub-frame resource
1353   // types.  This will change when we also prioritize certain subresources like
1354   // css, js, etc.
1355   if (request_->priority) {
1356     UMA_HISTOGRAM_CLIPPED_TIMES(
1357         "Net.Priority_High_Latency",
1358         total_duration,
1359         base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1360         100);
1361   } else {
1362     UMA_HISTOGRAM_CLIPPED_TIMES(
1363         "Net.Priority_Low_Latency",
1364         total_duration,
1365         base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1366         100);
1367   }
1368 }
1369 
LogTransactionMetrics() const1370 void HttpNetworkTransaction::LogTransactionMetrics() const {
1371   base::TimeDelta duration = base::Time::Now() -
1372       response_.request_time;
1373   if (60 < duration.InMinutes())
1374     return;
1375 
1376   base::TimeDelta total_duration = base::Time::Now() - start_time_;
1377 
1378   UMA_HISTOGRAM_LONG_TIMES("Net.Transaction_Latency", duration);
1379   UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Under_10", duration,
1380       base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1381       100);
1382   UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Total_Under_10",
1383       total_duration, base::TimeDelta::FromMilliseconds(1),
1384       base::TimeDelta::FromMinutes(10), 100);
1385   if (!reused_socket_) {
1386     UMA_HISTOGRAM_CLIPPED_TIMES(
1387         "Net.Transaction_Latency_Total_New_Connection_Under_10",
1388         total_duration, base::TimeDelta::FromMilliseconds(1),
1389         base::TimeDelta::FromMinutes(10), 100);
1390   }
1391 }
1392 
LogBlockedTunnelResponse(int response_code) const1393 void HttpNetworkTransaction::LogBlockedTunnelResponse(
1394     int response_code) const {
1395   LOG(WARNING) << "Blocked proxy response with status " << response_code
1396                << " to CONNECT request for "
1397                << GetHostAndPort(request_->url) << ".";
1398 }
1399 
HandleCertificateError(int error)1400 int HttpNetworkTransaction::HandleCertificateError(int error) {
1401   DCHECK(using_ssl_);
1402 
1403   const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID |
1404                          LOAD_IGNORE_CERT_DATE_INVALID |
1405                          LOAD_IGNORE_CERT_AUTHORITY_INVALID |
1406                          LOAD_IGNORE_CERT_WRONG_USAGE;
1407   if (request_->load_flags & kCertFlags) {
1408     switch (error) {
1409       case ERR_CERT_COMMON_NAME_INVALID:
1410         if (request_->load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID)
1411           error = OK;
1412         break;
1413       case ERR_CERT_DATE_INVALID:
1414         if (request_->load_flags & LOAD_IGNORE_CERT_DATE_INVALID)
1415           error = OK;
1416         break;
1417       case ERR_CERT_AUTHORITY_INVALID:
1418         if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID)
1419           error = OK;
1420         break;
1421     }
1422   }
1423 
1424   if (error != OK) {
1425     SSLClientSocket* ssl_socket =
1426         reinterpret_cast<SSLClientSocket*>(connection_->socket());
1427     ssl_socket->GetSSLInfo(&response_.ssl_info);
1428 
1429     // Add the bad certificate to the set of allowed certificates in the
1430     // SSL info object. This data structure will be consulted after calling
1431     // RestartIgnoringLastError(). And the user will be asked interactively
1432     // before RestartIgnoringLastError() is ever called.
1433     SSLConfig::CertAndStatus bad_cert;
1434     bad_cert.cert = response_.ssl_info.cert;
1435     bad_cert.cert_status = response_.ssl_info.cert_status;
1436     ssl_config_.allowed_bad_certs.push_back(bad_cert);
1437   }
1438   return error;
1439 }
1440 
HandleCertificateRequest(int error)1441 int HttpNetworkTransaction::HandleCertificateRequest(int error) {
1442   // Assert that the socket did not send a client certificate.
1443   // Note: If we got a reused socket, it was created with some other
1444   // transaction's ssl_config_, so we need to disable this assertion.  We can
1445   // get a certificate request on a reused socket when the server requested
1446   // renegotiation (rehandshake).
1447   // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query
1448   // the SSL parameters it was created with and get rid of the reused_socket_
1449   // test.
1450   DCHECK(reused_socket_ || !ssl_config_.send_client_cert);
1451 
1452   response_.cert_request_info = new SSLCertRequestInfo;
1453   SSLClientSocket* ssl_socket =
1454       reinterpret_cast<SSLClientSocket*>(connection_->socket());
1455   ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info);
1456 
1457   // Close the connection while the user is selecting a certificate to send
1458   // to the server.
1459   connection_->socket()->Disconnect();
1460   connection_->Reset();
1461 
1462   // If the user selected one of the certificate in client_certs for this
1463   // server before, use it automatically.
1464   X509Certificate* client_cert = session_->ssl_client_auth_cache()->
1465       Lookup(GetHostAndPort(request_->url));
1466   if (client_cert) {
1467     const std::vector<scoped_refptr<X509Certificate> >& client_certs =
1468         response_.cert_request_info->client_certs;
1469     for (size_t i = 0; i < client_certs.size(); ++i) {
1470       if (client_cert->fingerprint().Equals(client_certs[i]->fingerprint())) {
1471         ssl_config_.client_cert = client_cert;
1472         ssl_config_.send_client_cert = true;
1473         next_state_ = STATE_INIT_CONNECTION;
1474         // Reset the other member variables.
1475         // Note: this is necessary only with SSL renegotiation.
1476         ResetStateForRestart();
1477         return OK;
1478       }
1479     }
1480   }
1481   return error;
1482 }
1483 
HandleSSLHandshakeError(int error)1484 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
1485   if (ssl_config_.send_client_cert &&
1486      (error == ERR_SSL_PROTOCOL_ERROR ||
1487       error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) {
1488     session_->ssl_client_auth_cache()->Remove(GetHostAndPort(request_->url));
1489   }
1490 
1491   switch (error) {
1492     case ERR_SSL_PROTOCOL_ERROR:
1493     case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1494       if (ssl_config_.tls1_enabled) {
1495         // This could be a TLS-intolerant server or an SSL 3.0 server that
1496         // chose a TLS-only cipher suite.  Turn off TLS 1.0 and retry.
1497         ssl_config_.tls1_enabled = false;
1498         connection_->socket()->Disconnect();
1499         connection_->Reset();
1500         next_state_ = STATE_INIT_CONNECTION;
1501         error = OK;
1502       }
1503       break;
1504   }
1505   return error;
1506 }
1507 
1508 // This method determines whether it is safe to resend the request after an
1509 // IO error.  It can only be called in response to request header or body
1510 // write errors or response header read errors.  It should not be used in
1511 // other cases, such as a Connect error.
HandleIOError(int error)1512 int HttpNetworkTransaction::HandleIOError(int error) {
1513   switch (error) {
1514     // If we try to reuse a connection that the server is in the process of
1515     // closing, we may end up successfully writing out our request (or a
1516     // portion of our request) only to find a connection error when we try to
1517     // read from (or finish writing to) the socket.
1518     case ERR_CONNECTION_RESET:
1519     case ERR_CONNECTION_CLOSED:
1520     case ERR_CONNECTION_ABORTED:
1521       LogIOErrorMetrics(*connection_);
1522       if (ShouldResendRequest(error)) {
1523         ResetConnectionAndRequestForResend();
1524         error = OK;
1525       }
1526       break;
1527   }
1528   return error;
1529 }
1530 
ResetStateForRestart()1531 void HttpNetworkTransaction::ResetStateForRestart() {
1532   pending_auth_target_ = HttpAuth::AUTH_NONE;
1533   read_buf_ = NULL;
1534   read_buf_len_ = 0;
1535   http_stream_.reset();
1536   headers_valid_ = false;
1537   request_headers_.clear();
1538   response_ = HttpResponseInfo();
1539 }
1540 
GetResponseHeaders() const1541 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const {
1542   return response_.headers;
1543 }
1544 
ShouldResendRequest(int error) const1545 bool HttpNetworkTransaction::ShouldResendRequest(int error) const {
1546   // NOTE: we resend a request only if we reused a keep-alive connection.
1547   // This automatically prevents an infinite resend loop because we'll run
1548   // out of the cached keep-alive connections eventually.
1549   if (establishing_tunnel_ ||
1550       !connection_->ShouldResendFailedRequest(error) ||
1551       GetResponseHeaders()) {  // We have received some response headers.
1552     return false;
1553   }
1554   return true;
1555 }
1556 
ResetConnectionAndRequestForResend()1557 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() {
1558   connection_->socket()->Disconnect();
1559   connection_->Reset();
1560   // We need to clear request_headers_ because it contains the real request
1561   // headers, but we may need to resend the CONNECT request first to recreate
1562   // the SSL tunnel.
1563   request_headers_.clear();
1564   next_state_ = STATE_INIT_CONNECTION;  // Resend the request.
1565 }
1566 
ReconsiderProxyAfterError(int error)1567 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) {
1568   DCHECK(!pac_request_);
1569 
1570   // A failure to resolve the hostname or any error related to establishing a
1571   // TCP connection could be grounds for trying a new proxy configuration.
1572   //
1573   // Why do this when a hostname cannot be resolved?  Some URLs only make sense
1574   // to proxy servers.  The hostname in those URLs might fail to resolve if we
1575   // are still using a non-proxy config.  We need to check if a proxy config
1576   // now exists that corresponds to a proxy server that could load the URL.
1577   //
1578   switch (error) {
1579     case ERR_NAME_NOT_RESOLVED:
1580     case ERR_INTERNET_DISCONNECTED:
1581     case ERR_ADDRESS_UNREACHABLE:
1582     case ERR_CONNECTION_CLOSED:
1583     case ERR_CONNECTION_RESET:
1584     case ERR_CONNECTION_REFUSED:
1585     case ERR_CONNECTION_ABORTED:
1586     case ERR_TIMED_OUT:
1587     case ERR_TUNNEL_CONNECTION_FAILED:
1588       break;
1589     default:
1590       return error;
1591   }
1592 
1593   if (request_->load_flags & LOAD_BYPASS_PROXY) {
1594     return error;
1595   }
1596 
1597   int rv = session_->proxy_service()->ReconsiderProxyAfterError(
1598       request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_);
1599   if (rv == OK || rv == ERR_IO_PENDING) {
1600     // If the error was during connection setup, there is no socket to
1601     // disconnect.
1602     if (connection_->socket())
1603       connection_->socket()->Disconnect();
1604     connection_->Reset();
1605     next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
1606   } else {
1607     // If ReconsiderProxyAfterError() failed synchronously, it means
1608     // there was nothing left to fall-back to, so fail the transaction
1609     // with the last connection error we got.
1610     // TODO(eroman): This is a confusing contract, make it more obvious.
1611     rv = error;
1612   }
1613 
1614   return rv;
1615 }
1616 
ShouldApplyProxyAuth() const1617 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const {
1618   return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_;
1619 }
1620 
ShouldApplyServerAuth() const1621 bool HttpNetworkTransaction::ShouldApplyServerAuth() const {
1622   return !establishing_tunnel_ &&
1623       !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA);
1624 }
1625 
BuildAuthorizationHeader(HttpAuth::Target target) const1626 std::string HttpNetworkTransaction::BuildAuthorizationHeader(
1627     HttpAuth::Target target) const {
1628   DCHECK(HaveAuth(target));
1629 
1630   // Add a Authorization/Proxy-Authorization header line.
1631   std::string credentials = auth_handler_[target]->GenerateCredentials(
1632       auth_identity_[target].username,
1633       auth_identity_[target].password,
1634       request_,
1635       &proxy_info_);
1636 
1637   return HttpAuth::GetAuthorizationHeaderName(target) +
1638       ": "  + credentials + "\r\n";
1639 }
1640 
AuthOrigin(HttpAuth::Target target) const1641 GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const {
1642   return target == HttpAuth::AUTH_PROXY ?
1643       GURL("http://" + proxy_info_.proxy_server().host_and_port()) :
1644       request_->url.GetOrigin();
1645 }
1646 
AuthPath(HttpAuth::Target target) const1647 std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target)
1648     const {
1649   // Proxy authentication realms apply to all paths. So we will use
1650   // empty string in place of an absolute path.
1651   return target == HttpAuth::AUTH_PROXY ?
1652       std::string() : request_->url.path();
1653 }
1654 
1655 // static
AuthTargetString(HttpAuth::Target target)1656 std::string HttpNetworkTransaction::AuthTargetString(
1657     HttpAuth::Target target) {
1658   return target == HttpAuth::AUTH_PROXY ? "proxy" : "server";
1659 }
1660 
InvalidateRejectedAuthFromCache(HttpAuth::Target target,const GURL & auth_origin)1661 void HttpNetworkTransaction::InvalidateRejectedAuthFromCache(
1662     HttpAuth::Target target,
1663     const GURL& auth_origin) {
1664   DCHECK(HaveAuth(target));
1665 
1666   // TODO(eroman): this short-circuit can be relaxed. If the realm of
1667   // the preemptively used auth entry matches the realm of the subsequent
1668   // challenge, then we can invalidate the preemptively used entry.
1669   // Otherwise as-is we may send the failed credentials one extra time.
1670   if (auth_identity_[target].source == HttpAuth::IDENT_SRC_PATH_LOOKUP)
1671     return;
1672 
1673   // Clear the cache entry for the identity we just failed on.
1674   // Note: we require the username/password to match before invalidating
1675   // since the entry in the cache may be newer than what we used last time.
1676   session_->auth_cache()->Remove(auth_origin,
1677                                  auth_handler_[target]->realm(),
1678                                  auth_identity_[target].username,
1679                                  auth_identity_[target].password);
1680 }
1681 
SelectPreemptiveAuth(HttpAuth::Target target)1682 bool HttpNetworkTransaction::SelectPreemptiveAuth(HttpAuth::Target target) {
1683   DCHECK(!HaveAuth(target));
1684 
1685   // Don't do preemptive authorization if the URL contains a username/password,
1686   // since we must first be challenged in order to use the URL's identity.
1687   if (request_->url.has_username())
1688     return false;
1689 
1690   // SelectPreemptiveAuth() is on the critical path for each request, so it
1691   // is expected to be fast. LookupByPath() is fast in the common case, since
1692   // the number of http auth cache entries is expected to be very small.
1693   // (For most users in fact, it will be 0.)
1694 
1695   HttpAuthCache::Entry* entry = session_->auth_cache()->LookupByPath(
1696       AuthOrigin(target), AuthPath(target));
1697 
1698   // We don't support preemptive authentication for connection-based
1699   // authentication schemes because they can't reuse entry->handler().
1700   // Hopefully we can remove this limitation in the future.
1701   if (entry && !entry->handler()->is_connection_based()) {
1702     auth_identity_[target].source = HttpAuth::IDENT_SRC_PATH_LOOKUP;
1703     auth_identity_[target].invalid = false;
1704     auth_identity_[target].username = entry->username();
1705     auth_identity_[target].password = entry->password();
1706     auth_handler_[target] = entry->handler();
1707     return true;
1708   }
1709   return false;
1710 }
1711 
SelectNextAuthIdentityToTry(HttpAuth::Target target,const GURL & auth_origin)1712 bool HttpNetworkTransaction::SelectNextAuthIdentityToTry(
1713     HttpAuth::Target target,
1714     const GURL& auth_origin) {
1715   DCHECK(auth_handler_[target]);
1716   DCHECK(auth_identity_[target].invalid);
1717 
1718   // Try to use the username/password encoded into the URL first.
1719   if (target == HttpAuth::AUTH_SERVER && request_->url.has_username() &&
1720       !embedded_identity_used_) {
1721     auth_identity_[target].source = HttpAuth::IDENT_SRC_URL;
1722     auth_identity_[target].invalid = false;
1723     // Extract the username:password from the URL.
1724     GetIdentityFromURL(request_->url,
1725                        &auth_identity_[target].username,
1726                        &auth_identity_[target].password);
1727     embedded_identity_used_ = true;
1728     // TODO(eroman): If the password is blank, should we also try combining
1729     // with a password from the cache?
1730     return true;
1731   }
1732 
1733   // Check the auth cache for a realm entry.
1734   HttpAuthCache::Entry* entry = session_->auth_cache()->LookupByRealm(
1735       auth_origin, auth_handler_[target]->realm());
1736 
1737   if (entry) {
1738     // Disallow re-using of identity if the scheme of the originating challenge
1739     // does not match. This protects against the following situation:
1740     // 1. Browser prompts user to sign into DIGEST realm="Foo".
1741     // 2. Since the auth-scheme is not BASIC, the user is reasured that it
1742     //    will not be sent over the wire in clear text. So they use their
1743     //    most trusted password.
1744     // 3. Next, the browser receives a challenge for BASIC realm="Foo". This
1745     //    is the same realm that we have a cached identity for. However if
1746     //    we use that identity, it would get sent over the wire in
1747     //    clear text (which isn't what the user agreed to when entering it).
1748     if (entry->handler()->scheme() != auth_handler_[target]->scheme()) {
1749       LOG(WARNING) << "The scheme of realm " << auth_handler_[target]->realm()
1750                    << " has changed from " << entry->handler()->scheme()
1751                    << " to " << auth_handler_[target]->scheme();
1752       return false;
1753     }
1754 
1755     auth_identity_[target].source = HttpAuth::IDENT_SRC_REALM_LOOKUP;
1756     auth_identity_[target].invalid = false;
1757     auth_identity_[target].username = entry->username();
1758     auth_identity_[target].password = entry->password();
1759     return true;
1760   }
1761   return false;
1762 }
1763 
AuthChallengeLogMessage() const1764 std::string HttpNetworkTransaction::AuthChallengeLogMessage() const {
1765   std::string msg;
1766   std::string header_val;
1767   void* iter = NULL;
1768   scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
1769   while (headers->EnumerateHeader(&iter, "proxy-authenticate", &header_val)) {
1770     msg.append("\n  Has header Proxy-Authenticate: ");
1771     msg.append(header_val);
1772   }
1773 
1774   iter = NULL;
1775   while (headers->EnumerateHeader(&iter, "www-authenticate", &header_val)) {
1776     msg.append("\n  Has header WWW-Authenticate: ");
1777     msg.append(header_val);
1778   }
1779 
1780   // RFC 4559 requires that a proxy indicate its support of NTLM/Negotiate
1781   // authentication with a "Proxy-Support: Session-Based-Authentication"
1782   // response header.
1783   iter = NULL;
1784   while (headers->EnumerateHeader(&iter, "proxy-support", &header_val)) {
1785     msg.append("\n  Has header Proxy-Support: ");
1786     msg.append(header_val);
1787   }
1788 
1789   return msg;
1790 }
1791 
HandleAuthChallenge()1792 int HttpNetworkTransaction::HandleAuthChallenge() {
1793   scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
1794   DCHECK(headers);
1795 
1796   int status = headers->response_code();
1797   if (status != 401 && status != 407)
1798     return OK;
1799   HttpAuth::Target target = status == 407 ?
1800       HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER;
1801   GURL auth_origin = AuthOrigin(target);
1802 
1803   LOG(INFO) << "The " << AuthTargetString(target) << " "
1804             << auth_origin << " requested auth"
1805             << AuthChallengeLogMessage();
1806 
1807   if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
1808     return ERR_UNEXPECTED_PROXY_AUTH;
1809 
1810   // The auth we tried just failed, hence it can't be valid. Remove it from
1811   // the cache so it won't be used again.
1812   // TODO(wtc): IsFinalRound is not the right condition.  In a multi-round
1813   // auth sequence, the server may fail the auth in round 1 if our first
1814   // authorization header is broken.  We should inspect response_.headers to
1815   // determine if the server already failed the auth or wants us to continue.
1816   // See http://crbug.com/21015.
1817   if (HaveAuth(target) && auth_handler_[target]->IsFinalRound()) {
1818     InvalidateRejectedAuthFromCache(target, auth_origin);
1819     auth_handler_[target] = NULL;
1820     auth_identity_[target] = HttpAuth::Identity();
1821   }
1822 
1823   auth_identity_[target].invalid = true;
1824 
1825   if (target != HttpAuth::AUTH_SERVER ||
1826       !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA)) {
1827     // Find the best authentication challenge that we support.
1828     HttpAuth::ChooseBestChallenge(headers, target, auth_origin,
1829                                   &auth_handler_[target]);
1830   }
1831 
1832   if (!auth_handler_[target]) {
1833     if (establishing_tunnel_) {
1834       LOG(ERROR) << "Can't perform auth to the " << AuthTargetString(target)
1835                  << " " << auth_origin << " when establishing a tunnel"
1836                  << AuthChallengeLogMessage();
1837 
1838       // We are establishing a tunnel, we can't show the error page because an
1839       // active network attacker could control its contents.  Instead, we just
1840       // fail to establish the tunnel.
1841       DCHECK(target == HttpAuth::AUTH_PROXY);
1842       return ERR_PROXY_AUTH_REQUESTED;
1843     }
1844     // We found no supported challenge -- let the transaction continue
1845     // so we end up displaying the error page.
1846     return OK;
1847   }
1848 
1849   if (auth_handler_[target]->NeedsIdentity()) {
1850     // Pick a new auth identity to try, by looking to the URL and auth cache.
1851     // If an identity to try is found, it is saved to auth_identity_[target].
1852     SelectNextAuthIdentityToTry(target, auth_origin);
1853   } else {
1854     // Proceed with the existing identity or a null identity.
1855     //
1856     // TODO(wtc): Add a safeguard against infinite transaction restarts, if
1857     // the server keeps returning "NTLM".
1858     auth_identity_[target].invalid = false;
1859   }
1860 
1861   // Make a note that we are waiting for auth. This variable is inspected
1862   // when the client calls RestartWithAuth() to pick up where we left off.
1863   pending_auth_target_ = target;
1864 
1865   if (auth_identity_[target].invalid) {
1866     // We have exhausted all identity possibilities, all we can do now is
1867     // pass the challenge information back to the client.
1868     PopulateAuthChallenge(target, auth_origin);
1869   }
1870   return OK;
1871 }
1872 
PopulateAuthChallenge(HttpAuth::Target target,const GURL & auth_origin)1873 void HttpNetworkTransaction::PopulateAuthChallenge(HttpAuth::Target target,
1874                                                    const GURL& auth_origin) {
1875   // Populates response_.auth_challenge with the authentication challenge info.
1876   // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo().
1877 
1878   AuthChallengeInfo* auth_info = new AuthChallengeInfo;
1879   auth_info->is_proxy = target == HttpAuth::AUTH_PROXY;
1880   auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin));
1881   auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme());
1882   // TODO(eroman): decode realm according to RFC 2047.
1883   auth_info->realm = ASCIIToWide(auth_handler_[target]->realm());
1884   response_.auth_challenge = auth_info;
1885 }
1886 
1887 }  // namespace net
1888