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 #include "net/http/http_network_transaction.h"
6
7 #include <set>
8 #include <vector>
9
10 #include "base/compiler_specific.h"
11 #include "base/format_macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/metrics/field_trial.h"
14 #include "base/metrics/histogram.h"
15 #include "base/metrics/stats_counters.h"
16 #include "base/stl_util-inl.h"
17 #include "base/string_number_conversions.h"
18 #include "base/string_util.h"
19 #include "base/stringprintf.h"
20 #include "build/build_config.h"
21 #include "googleurl/src/gurl.h"
22 #include "net/base/auth.h"
23 #include "net/base/host_port_pair.h"
24 #include "net/base/io_buffer.h"
25 #include "net/base/load_flags.h"
26 #include "net/base/net_errors.h"
27 #include "net/base/net_util.h"
28 #include "net/base/network_delegate.h"
29 #include "net/base/ssl_cert_request_info.h"
30 #include "net/base/ssl_connection_status_flags.h"
31 #include "net/base/upload_data_stream.h"
32 #include "net/http/http_auth.h"
33 #include "net/http/http_auth_handler.h"
34 #include "net/http/http_auth_handler_factory.h"
35 #include "net/http/http_basic_stream.h"
36 #include "net/http/http_chunked_decoder.h"
37 #include "net/http/http_net_log_params.h"
38 #include "net/http/http_network_session.h"
39 #include "net/http/http_proxy_client_socket.h"
40 #include "net/http/http_proxy_client_socket_pool.h"
41 #include "net/http/http_request_headers.h"
42 #include "net/http/http_request_info.h"
43 #include "net/http/http_response_body_drainer.h"
44 #include "net/http/http_response_headers.h"
45 #include "net/http/http_response_info.h"
46 #include "net/http/http_stream_factory.h"
47 #include "net/http/http_util.h"
48 #include "net/http/url_security_manager.h"
49 #include "net/socket/client_socket_factory.h"
50 #include "net/socket/socks_client_socket_pool.h"
51 #include "net/socket/ssl_client_socket.h"
52 #include "net/socket/ssl_client_socket_pool.h"
53 #include "net/socket/transport_client_socket_pool.h"
54 #include "net/spdy/spdy_http_stream.h"
55 #include "net/spdy/spdy_session.h"
56 #include "net/spdy/spdy_session_pool.h"
57
58 using base::Time;
59
60 namespace net {
61
62 namespace {
63
ProcessAlternateProtocol(HttpStreamFactory * factory,HttpAlternateProtocols * alternate_protocols,const HttpResponseHeaders & headers,const HostPortPair & http_host_port_pair)64 void ProcessAlternateProtocol(HttpStreamFactory* factory,
65 HttpAlternateProtocols* alternate_protocols,
66 const HttpResponseHeaders& headers,
67 const HostPortPair& http_host_port_pair) {
68 std::string alternate_protocol_str;
69
70 if (!headers.EnumerateHeader(NULL, HttpAlternateProtocols::kHeader,
71 &alternate_protocol_str)) {
72 // Header is not present.
73 return;
74 }
75
76 factory->ProcessAlternateProtocol(alternate_protocols,
77 alternate_protocol_str,
78 http_host_port_pair);
79 }
80
81 // Returns true if |error| is a client certificate authentication error.
IsClientCertificateError(int error)82 bool IsClientCertificateError(int error) {
83 switch (error) {
84 case ERR_BAD_SSL_CLIENT_AUTH_CERT:
85 case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED:
86 case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY:
87 case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED:
88 return true;
89 default:
90 return false;
91 }
92 }
93
94 } // namespace
95
96 //-----------------------------------------------------------------------------
97
HttpNetworkTransaction(HttpNetworkSession * session)98 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session)
99 : pending_auth_target_(HttpAuth::AUTH_NONE),
100 ALLOW_THIS_IN_INITIALIZER_LIST(
101 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)),
102 ALLOW_THIS_IN_INITIALIZER_LIST(delegate_callback_(
103 new CancelableCompletionCallback<HttpNetworkTransaction>(
104 this, &HttpNetworkTransaction::OnIOComplete))),
105 user_callback_(NULL),
106 session_(session),
107 request_(NULL),
108 headers_valid_(false),
109 logged_response_time_(false),
110 request_headers_(),
111 read_buf_len_(0),
112 next_state_(STATE_NONE),
113 establishing_tunnel_(false) {
114 session->ssl_config_service()->GetSSLConfig(&ssl_config_);
115 if (session->http_stream_factory()->next_protos())
116 ssl_config_.next_protos = *session->http_stream_factory()->next_protos();
117 }
118
~HttpNetworkTransaction()119 HttpNetworkTransaction::~HttpNetworkTransaction() {
120 if (stream_.get()) {
121 HttpResponseHeaders* headers = GetResponseHeaders();
122 // TODO(mbelshe): The stream_ should be able to compute whether or not the
123 // stream should be kept alive. No reason to compute here
124 // and pass it in.
125 bool try_to_keep_alive =
126 next_state_ == STATE_NONE &&
127 stream_->CanFindEndOfResponse() &&
128 (!headers || headers->IsKeepAlive());
129 if (!try_to_keep_alive) {
130 stream_->Close(true /* not reusable */);
131 } else {
132 if (stream_->IsResponseBodyComplete()) {
133 // If the response body is complete, we can just reuse the socket.
134 stream_->Close(false /* reusable */);
135 } else if (stream_->IsSpdyHttpStream()) {
136 // Doesn't really matter for SpdyHttpStream. Just close it.
137 stream_->Close(true /* not reusable */);
138 } else {
139 // Otherwise, we try to drain the response body.
140 // TODO(willchan): Consider moving this response body draining to the
141 // stream implementation. For SPDY, there's clearly no point. For
142 // HTTP, it can vary depending on whether or not we're pipelining. It's
143 // stream dependent, so the different subtypes should be implementing
144 // their solutions.
145 HttpResponseBodyDrainer* drainer =
146 new HttpResponseBodyDrainer(stream_.release());
147 drainer->Start(session_);
148 // |drainer| will delete itself.
149 }
150 }
151 }
152
153 delegate_callback_->Cancel();
154 }
155
Start(const HttpRequestInfo * request_info,CompletionCallback * callback,const BoundNetLog & net_log)156 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
157 CompletionCallback* callback,
158 const BoundNetLog& net_log) {
159 SIMPLE_STATS_COUNTER("HttpNetworkTransaction.Count");
160
161 net_log_ = net_log;
162 request_ = request_info;
163 start_time_ = base::Time::Now();
164
165 next_state_ = STATE_CREATE_STREAM;
166 int rv = DoLoop(OK);
167 if (rv == ERR_IO_PENDING)
168 user_callback_ = callback;
169 return rv;
170 }
171
RestartIgnoringLastError(CompletionCallback * callback)172 int HttpNetworkTransaction::RestartIgnoringLastError(
173 CompletionCallback* callback) {
174 DCHECK(!stream_.get());
175 DCHECK(!stream_request_.get());
176 DCHECK_EQ(STATE_NONE, next_state_);
177
178 next_state_ = STATE_CREATE_STREAM;
179
180 int rv = DoLoop(OK);
181 if (rv == ERR_IO_PENDING)
182 user_callback_ = callback;
183 return rv;
184 }
185
RestartWithCertificate(X509Certificate * client_cert,CompletionCallback * callback)186 int HttpNetworkTransaction::RestartWithCertificate(
187 X509Certificate* client_cert,
188 CompletionCallback* callback) {
189 // In HandleCertificateRequest(), we always tear down existing stream
190 // requests to force a new connection. So we shouldn't have one here.
191 DCHECK(!stream_request_.get());
192 DCHECK(!stream_.get());
193 DCHECK_EQ(STATE_NONE, next_state_);
194
195 ssl_config_.client_cert = client_cert;
196 session_->ssl_client_auth_cache()->Add(
197 response_.cert_request_info->host_and_port, client_cert);
198 ssl_config_.send_client_cert = true;
199 // Reset the other member variables.
200 // Note: this is necessary only with SSL renegotiation.
201 ResetStateForRestart();
202 next_state_ = STATE_CREATE_STREAM;
203 int rv = DoLoop(OK);
204 if (rv == ERR_IO_PENDING)
205 user_callback_ = callback;
206 return rv;
207 }
208
RestartWithAuth(const string16 & username,const string16 & password,CompletionCallback * callback)209 int HttpNetworkTransaction::RestartWithAuth(
210 const string16& username,
211 const string16& password,
212 CompletionCallback* callback) {
213 HttpAuth::Target target = pending_auth_target_;
214 if (target == HttpAuth::AUTH_NONE) {
215 NOTREACHED();
216 return ERR_UNEXPECTED;
217 }
218 pending_auth_target_ = HttpAuth::AUTH_NONE;
219
220 auth_controllers_[target]->ResetAuth(username, password);
221
222 DCHECK(user_callback_ == NULL);
223
224 int rv = OK;
225 if (target == HttpAuth::AUTH_PROXY && establishing_tunnel_) {
226 // In this case, we've gathered credentials for use with proxy
227 // authentication of a tunnel.
228 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
229 DCHECK(stream_request_ != NULL);
230 auth_controllers_[target] = NULL;
231 ResetStateForRestart();
232 rv = stream_request_->RestartTunnelWithProxyAuth(username, password);
233 } else {
234 // In this case, we've gathered credentials for the server or the proxy
235 // but it is not during the tunneling phase.
236 DCHECK(stream_request_ == NULL);
237 PrepareForAuthRestart(target);
238 rv = DoLoop(OK);
239 }
240
241 if (rv == ERR_IO_PENDING)
242 user_callback_ = callback;
243 return rv;
244 }
245
PrepareForAuthRestart(HttpAuth::Target target)246 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) {
247 DCHECK(HaveAuth(target));
248 DCHECK(!stream_request_.get());
249
250 bool keep_alive = false;
251 // Even if the server says the connection is keep-alive, we have to be
252 // able to find the end of each response in order to reuse the connection.
253 if (GetResponseHeaders()->IsKeepAlive() &&
254 stream_->CanFindEndOfResponse()) {
255 // If the response body hasn't been completely read, we need to drain
256 // it first.
257 if (!stream_->IsResponseBodyComplete()) {
258 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
259 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket.
260 read_buf_len_ = kDrainBodyBufferSize;
261 return;
262 }
263 keep_alive = true;
264 }
265
266 // We don't need to drain the response body, so we act as if we had drained
267 // the response body.
268 DidDrainBodyForAuthRestart(keep_alive);
269 }
270
DidDrainBodyForAuthRestart(bool keep_alive)271 void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
272 DCHECK(!stream_request_.get());
273
274 if (stream_.get()) {
275 HttpStream* new_stream = NULL;
276 if (keep_alive && stream_->IsConnectionReusable()) {
277 // We should call connection_->set_idle_time(), but this doesn't occur
278 // often enough to be worth the trouble.
279 stream_->SetConnectionReused();
280 new_stream = stream_->RenewStreamForAuth();
281 }
282
283 if (!new_stream) {
284 // Close the stream and mark it as not_reusable. Even in the
285 // keep_alive case, we've determined that the stream_ is not
286 // reusable if new_stream is NULL.
287 stream_->Close(true);
288 next_state_ = STATE_CREATE_STREAM;
289 } else {
290 next_state_ = STATE_INIT_STREAM;
291 }
292 stream_.reset(new_stream);
293 }
294
295 // Reset the other member variables.
296 ResetStateForAuthRestart();
297 }
298
IsReadyToRestartForAuth()299 bool HttpNetworkTransaction::IsReadyToRestartForAuth() {
300 return pending_auth_target_ != HttpAuth::AUTH_NONE &&
301 HaveAuth(pending_auth_target_);
302 }
303
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)304 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len,
305 CompletionCallback* callback) {
306 DCHECK(buf);
307 DCHECK_LT(0, buf_len);
308
309 State next_state = STATE_NONE;
310
311 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders());
312 if (headers_valid_ && headers.get() && stream_request_.get()) {
313 // We're trying to read the body of the response but we're still trying
314 // to establish an SSL tunnel through an HTTP proxy. We can't read these
315 // bytes when establishing a tunnel because they might be controlled by
316 // an active network attacker. We don't worry about this for HTTP
317 // because an active network attacker can already control HTTP sessions.
318 // We reach this case when the user cancels a 407 proxy auth prompt. We
319 // also don't worry about this for an HTTPS Proxy, because the
320 // communication with the proxy is secure.
321 // See http://crbug.com/8473.
322 DCHECK(proxy_info_.is_http() || proxy_info_.is_https());
323 DCHECK_EQ(headers->response_code(), 407);
324 LOG(WARNING) << "Blocked proxy response with status "
325 << headers->response_code() << " to CONNECT request for "
326 << GetHostAndPort(request_->url) << ".";
327 return ERR_TUNNEL_CONNECTION_FAILED;
328 }
329
330 // Are we using SPDY or HTTP?
331 next_state = STATE_READ_BODY;
332
333 read_buf_ = buf;
334 read_buf_len_ = buf_len;
335
336 next_state_ = next_state;
337 int rv = DoLoop(OK);
338 if (rv == ERR_IO_PENDING)
339 user_callback_ = callback;
340 return rv;
341 }
342
GetResponseInfo() const343 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const {
344 return ((headers_valid_ && response_.headers) || response_.ssl_info.cert ||
345 response_.cert_request_info) ? &response_ : NULL;
346 }
347
GetLoadState() const348 LoadState HttpNetworkTransaction::GetLoadState() const {
349 // TODO(wtc): Define a new LoadState value for the
350 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request.
351 switch (next_state_) {
352 case STATE_CREATE_STREAM_COMPLETE:
353 return stream_request_->GetLoadState();
354 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
355 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
356 case STATE_SEND_REQUEST_COMPLETE:
357 return LOAD_STATE_SENDING_REQUEST;
358 case STATE_READ_HEADERS_COMPLETE:
359 return LOAD_STATE_WAITING_FOR_RESPONSE;
360 case STATE_READ_BODY_COMPLETE:
361 return LOAD_STATE_READING_RESPONSE;
362 default:
363 return LOAD_STATE_IDLE;
364 }
365 }
366
GetUploadProgress() const367 uint64 HttpNetworkTransaction::GetUploadProgress() const {
368 if (!stream_.get())
369 return 0;
370
371 return stream_->GetUploadProgress();
372 }
373
OnStreamReady(const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,HttpStream * stream)374 void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config,
375 const ProxyInfo& used_proxy_info,
376 HttpStream* stream) {
377 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
378 DCHECK(stream_request_.get());
379
380 stream_.reset(stream);
381 ssl_config_ = used_ssl_config;
382 proxy_info_ = used_proxy_info;
383 response_.was_npn_negotiated = stream_request_->was_npn_negotiated();
384 response_.was_fetched_via_spdy = stream_request_->using_spdy();
385 response_.was_fetched_via_proxy = !proxy_info_.is_direct();
386
387 OnIOComplete(OK);
388 }
389
OnStreamFailed(int result,const SSLConfig & used_ssl_config)390 void HttpNetworkTransaction::OnStreamFailed(int result,
391 const SSLConfig& used_ssl_config) {
392 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
393 DCHECK_NE(OK, result);
394 DCHECK(stream_request_.get());
395 DCHECK(!stream_.get());
396 ssl_config_ = used_ssl_config;
397
398 OnIOComplete(result);
399 }
400
OnCertificateError(int result,const SSLConfig & used_ssl_config,const SSLInfo & ssl_info)401 void HttpNetworkTransaction::OnCertificateError(
402 int result,
403 const SSLConfig& used_ssl_config,
404 const SSLInfo& ssl_info) {
405 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
406 DCHECK_NE(OK, result);
407 DCHECK(stream_request_.get());
408 DCHECK(!stream_.get());
409
410 response_.ssl_info = ssl_info;
411 ssl_config_ = used_ssl_config;
412
413 // TODO(mbelshe): For now, we're going to pass the error through, and that
414 // will close the stream_request in all cases. This means that we're always
415 // going to restart an entire STATE_CREATE_STREAM, even if the connection is
416 // good and the user chooses to ignore the error. This is not ideal, but not
417 // the end of the world either.
418
419 OnIOComplete(result);
420 }
421
OnNeedsProxyAuth(const HttpResponseInfo & proxy_response,const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,HttpAuthController * auth_controller)422 void HttpNetworkTransaction::OnNeedsProxyAuth(
423 const HttpResponseInfo& proxy_response,
424 const SSLConfig& used_ssl_config,
425 const ProxyInfo& used_proxy_info,
426 HttpAuthController* auth_controller) {
427 DCHECK(stream_request_.get());
428 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
429
430 establishing_tunnel_ = true;
431 response_.headers = proxy_response.headers;
432 response_.auth_challenge = proxy_response.auth_challenge;
433 headers_valid_ = true;
434 ssl_config_ = used_ssl_config;
435 proxy_info_ = used_proxy_info;
436
437 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller;
438 pending_auth_target_ = HttpAuth::AUTH_PROXY;
439
440 DoCallback(OK);
441 }
442
OnNeedsClientAuth(const SSLConfig & used_ssl_config,SSLCertRequestInfo * cert_info)443 void HttpNetworkTransaction::OnNeedsClientAuth(
444 const SSLConfig& used_ssl_config,
445 SSLCertRequestInfo* cert_info) {
446 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
447
448 ssl_config_ = used_ssl_config;
449 response_.cert_request_info = cert_info;
450 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
451 }
452
OnHttpsProxyTunnelResponse(const HttpResponseInfo & response_info,const SSLConfig & used_ssl_config,const ProxyInfo & used_proxy_info,HttpStream * stream)453 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse(
454 const HttpResponseInfo& response_info,
455 const SSLConfig& used_ssl_config,
456 const ProxyInfo& used_proxy_info,
457 HttpStream* stream) {
458 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
459
460 headers_valid_ = true;
461 response_ = response_info;
462 ssl_config_ = used_ssl_config;
463 proxy_info_ = used_proxy_info;
464 stream_.reset(stream);
465 stream_request_.reset(); // we're done with the stream request
466 OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
467 }
468
is_https_request() const469 bool HttpNetworkTransaction::is_https_request() const {
470 return request_->url.SchemeIs("https");
471 }
472
DoCallback(int rv)473 void HttpNetworkTransaction::DoCallback(int rv) {
474 DCHECK_NE(rv, ERR_IO_PENDING);
475 DCHECK(user_callback_);
476
477 // Since Run may result in Read being called, clear user_callback_ up front.
478 CompletionCallback* c = user_callback_;
479 user_callback_ = NULL;
480 c->Run(rv);
481 }
482
OnIOComplete(int result)483 void HttpNetworkTransaction::OnIOComplete(int result) {
484 int rv = DoLoop(result);
485 if (rv != ERR_IO_PENDING)
486 DoCallback(rv);
487 }
488
DoLoop(int result)489 int HttpNetworkTransaction::DoLoop(int result) {
490 DCHECK(next_state_ != STATE_NONE);
491
492 int rv = result;
493 do {
494 State state = next_state_;
495 next_state_ = STATE_NONE;
496 switch (state) {
497 case STATE_CREATE_STREAM:
498 DCHECK_EQ(OK, rv);
499 rv = DoCreateStream();
500 break;
501 case STATE_CREATE_STREAM_COMPLETE:
502 rv = DoCreateStreamComplete(rv);
503 break;
504 case STATE_INIT_STREAM:
505 DCHECK_EQ(OK, rv);
506 rv = DoInitStream();
507 break;
508 case STATE_INIT_STREAM_COMPLETE:
509 rv = DoInitStreamComplete(rv);
510 break;
511 case STATE_GENERATE_PROXY_AUTH_TOKEN:
512 DCHECK_EQ(OK, rv);
513 rv = DoGenerateProxyAuthToken();
514 break;
515 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
516 rv = DoGenerateProxyAuthTokenComplete(rv);
517 break;
518 case STATE_GENERATE_SERVER_AUTH_TOKEN:
519 DCHECK_EQ(OK, rv);
520 rv = DoGenerateServerAuthToken();
521 break;
522 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
523 rv = DoGenerateServerAuthTokenComplete(rv);
524 break;
525 case STATE_BUILD_REQUEST:
526 DCHECK_EQ(OK, rv);
527 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, NULL);
528 rv = DoBuildRequest();
529 break;
530 case STATE_BUILD_REQUEST_COMPLETE:
531 rv = DoBuildRequestComplete(rv);
532 break;
533 case STATE_SEND_REQUEST:
534 DCHECK_EQ(OK, rv);
535 rv = DoSendRequest();
536 break;
537 case STATE_SEND_REQUEST_COMPLETE:
538 rv = DoSendRequestComplete(rv);
539 net_log_.EndEventWithNetErrorCode(
540 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, rv);
541 break;
542 case STATE_READ_HEADERS:
543 DCHECK_EQ(OK, rv);
544 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, NULL);
545 rv = DoReadHeaders();
546 break;
547 case STATE_READ_HEADERS_COMPLETE:
548 rv = DoReadHeadersComplete(rv);
549 net_log_.EndEventWithNetErrorCode(
550 NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv);
551 break;
552 case STATE_READ_BODY:
553 DCHECK_EQ(OK, rv);
554 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, NULL);
555 rv = DoReadBody();
556 break;
557 case STATE_READ_BODY_COMPLETE:
558 rv = DoReadBodyComplete(rv);
559 net_log_.EndEventWithNetErrorCode(
560 NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv);
561 break;
562 case STATE_DRAIN_BODY_FOR_AUTH_RESTART:
563 DCHECK_EQ(OK, rv);
564 net_log_.BeginEvent(
565 NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, NULL);
566 rv = DoDrainBodyForAuthRestart();
567 break;
568 case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE:
569 rv = DoDrainBodyForAuthRestartComplete(rv);
570 net_log_.EndEventWithNetErrorCode(
571 NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, rv);
572 break;
573 default:
574 NOTREACHED() << "bad state";
575 rv = ERR_FAILED;
576 break;
577 }
578 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
579
580 return rv;
581 }
582
DoCreateStream()583 int HttpNetworkTransaction::DoCreateStream() {
584 next_state_ = STATE_CREATE_STREAM_COMPLETE;
585
586 stream_request_.reset(
587 session_->http_stream_factory()->RequestStream(
588 *request_,
589 ssl_config_,
590 this,
591 net_log_));
592 DCHECK(stream_request_.get());
593 return ERR_IO_PENDING;
594 }
595
DoCreateStreamComplete(int result)596 int HttpNetworkTransaction::DoCreateStreamComplete(int result) {
597 if (result == OK) {
598 next_state_ = STATE_INIT_STREAM;
599 DCHECK(stream_.get());
600 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
601 result = HandleCertificateRequest(result);
602 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
603 // Return OK and let the caller read the proxy's error page
604 next_state_ = STATE_NONE;
605 return OK;
606 }
607
608 // Handle possible handshake errors that may have occurred if the stream
609 // used SSL for one or more of the layers.
610 result = HandleSSLHandshakeError(result);
611
612 // At this point we are done with the stream_request_.
613 stream_request_.reset();
614 return result;
615 }
616
DoInitStream()617 int HttpNetworkTransaction::DoInitStream() {
618 DCHECK(stream_.get());
619 next_state_ = STATE_INIT_STREAM_COMPLETE;
620 return stream_->InitializeStream(request_, net_log_, &io_callback_);
621 }
622
DoInitStreamComplete(int result)623 int HttpNetworkTransaction::DoInitStreamComplete(int result) {
624 if (result == OK) {
625 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
626 } else {
627 if (result < 0)
628 result = HandleIOError(result);
629
630 // The stream initialization failed, so this stream will never be useful.
631 stream_.reset();
632 }
633
634 return result;
635 }
636
DoGenerateProxyAuthToken()637 int HttpNetworkTransaction::DoGenerateProxyAuthToken() {
638 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
639 if (!ShouldApplyProxyAuth())
640 return OK;
641 HttpAuth::Target target = HttpAuth::AUTH_PROXY;
642 if (!auth_controllers_[target].get())
643 auth_controllers_[target] =
644 new HttpAuthController(target,
645 AuthURL(target),
646 session_->http_auth_cache(),
647 session_->http_auth_handler_factory());
648 return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
649 &io_callback_,
650 net_log_);
651 }
652
DoGenerateProxyAuthTokenComplete(int rv)653 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
654 DCHECK_NE(ERR_IO_PENDING, rv);
655 if (rv == OK)
656 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN;
657 return rv;
658 }
659
DoGenerateServerAuthToken()660 int HttpNetworkTransaction::DoGenerateServerAuthToken() {
661 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE;
662 HttpAuth::Target target = HttpAuth::AUTH_SERVER;
663 if (!auth_controllers_[target].get())
664 auth_controllers_[target] =
665 new HttpAuthController(target,
666 AuthURL(target),
667 session_->http_auth_cache(),
668 session_->http_auth_handler_factory());
669 if (!ShouldApplyServerAuth())
670 return OK;
671 return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
672 &io_callback_,
673 net_log_);
674 }
675
DoGenerateServerAuthTokenComplete(int rv)676 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
677 DCHECK_NE(ERR_IO_PENDING, rv);
678 if (rv == OK)
679 next_state_ = STATE_BUILD_REQUEST;
680 return rv;
681 }
682
BuildRequestHeaders(bool using_proxy)683 void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) {
684 request_headers_.SetHeader(HttpRequestHeaders::kHost,
685 GetHostAndOptionalPort(request_->url));
686
687 // For compat with HTTP/1.0 servers and proxies:
688 if (using_proxy) {
689 request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection,
690 "keep-alive");
691 } else {
692 request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive");
693 }
694
695 // Our consumer should have made sure that this is a safe referrer. See for
696 // instance WebCore::FrameLoader::HideReferrer.
697 if (request_->referrer.is_valid()) {
698 request_headers_.SetHeader(HttpRequestHeaders::kReferer,
699 request_->referrer.spec());
700 }
701
702 // Add a content length header?
703 if (request_body_.get()) {
704 if (request_body_->is_chunked()) {
705 request_headers_.SetHeader(
706 HttpRequestHeaders::kTransferEncoding, "chunked");
707 } else {
708 request_headers_.SetHeader(
709 HttpRequestHeaders::kContentLength,
710 base::Uint64ToString(request_body_->size()));
711 }
712 } else if (request_->method == "POST" || request_->method == "PUT" ||
713 request_->method == "HEAD") {
714 // An empty POST/PUT request still needs a content length. As for HEAD,
715 // IE and Safari also add a content length header. Presumably it is to
716 // support sending a HEAD request to an URL that only expects to be sent a
717 // POST or some other method that normally would have a message body.
718 request_headers_.SetHeader(HttpRequestHeaders::kContentLength, "0");
719 }
720
721 // Honor load flags that impact proxy caches.
722 if (request_->load_flags & LOAD_BYPASS_CACHE) {
723 request_headers_.SetHeader(HttpRequestHeaders::kPragma, "no-cache");
724 request_headers_.SetHeader(HttpRequestHeaders::kCacheControl, "no-cache");
725 } else if (request_->load_flags & LOAD_VALIDATE_CACHE) {
726 request_headers_.SetHeader(HttpRequestHeaders::kCacheControl, "max-age=0");
727 }
728
729 if (ShouldApplyProxyAuth() && HaveAuth(HttpAuth::AUTH_PROXY))
730 auth_controllers_[HttpAuth::AUTH_PROXY]->AddAuthorizationHeader(
731 &request_headers_);
732 if (ShouldApplyServerAuth() && HaveAuth(HttpAuth::AUTH_SERVER))
733 auth_controllers_[HttpAuth::AUTH_SERVER]->AddAuthorizationHeader(
734 &request_headers_);
735
736 // Headers that will be stripped from request_->extra_headers to prevent,
737 // e.g., plugins from overriding headers that are controlled using other
738 // means. Otherwise a plugin could set a referrer although sending the
739 // referrer is inhibited.
740 // TODO(jochen): check whether also other headers should be stripped.
741 static const char* const kExtraHeadersToBeStripped[] = {
742 "Referer"
743 };
744
745 HttpRequestHeaders stripped_extra_headers;
746 stripped_extra_headers.CopyFrom(request_->extra_headers);
747 for (size_t i = 0; i < arraysize(kExtraHeadersToBeStripped); ++i)
748 stripped_extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]);
749 request_headers_.MergeFrom(stripped_extra_headers);
750 }
751
DoBuildRequest()752 int HttpNetworkTransaction::DoBuildRequest() {
753 next_state_ = STATE_BUILD_REQUEST_COMPLETE;
754 delegate_callback_->AddRef(); // balanced in DoSendRequestComplete
755
756 request_body_.reset(NULL);
757 if (request_->upload_data) {
758 int error_code;
759 request_body_.reset(
760 UploadDataStream::Create(request_->upload_data, &error_code));
761 if (!request_body_.get())
762 return error_code;
763 }
764
765 headers_valid_ = false;
766
767 // This is constructed lazily (instead of within our Start method), so that
768 // we have proxy info available.
769 if (request_headers_.IsEmpty()) {
770 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) &&
771 !is_https_request();
772 BuildRequestHeaders(using_proxy);
773 }
774
775 if (session_->network_delegate()) {
776 return session_->network_delegate()->NotifyBeforeSendHeaders(
777 request_->request_id, delegate_callback_, &request_headers_);
778 }
779
780 return OK;
781 }
782
DoBuildRequestComplete(int result)783 int HttpNetworkTransaction::DoBuildRequestComplete(int result) {
784 delegate_callback_->Release(); // balanced in DoBuildRequest
785
786 if (result == OK)
787 next_state_ = STATE_SEND_REQUEST;
788 return result;
789 }
790
DoSendRequest()791 int HttpNetworkTransaction::DoSendRequest() {
792 next_state_ = STATE_SEND_REQUEST_COMPLETE;
793
794 return stream_->SendRequest(
795 request_headers_, request_body_.release(), &response_, &io_callback_);
796 }
797
DoSendRequestComplete(int result)798 int HttpNetworkTransaction::DoSendRequestComplete(int result) {
799 if (result < 0)
800 return HandleIOError(result);
801 next_state_ = STATE_READ_HEADERS;
802 return OK;
803 }
804
DoReadHeaders()805 int HttpNetworkTransaction::DoReadHeaders() {
806 next_state_ = STATE_READ_HEADERS_COMPLETE;
807 return stream_->ReadResponseHeaders(&io_callback_);
808 }
809
HandleConnectionClosedBeforeEndOfHeaders()810 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() {
811 if (!response_.headers && !stream_->IsConnectionReused()) {
812 // The connection was closed before any data was sent. Likely an error
813 // rather than empty HTTP/0.9 response.
814 return ERR_EMPTY_RESPONSE;
815 }
816
817 return OK;
818 }
819
DoReadHeadersComplete(int result)820 int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
821 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here
822 // due to SSL renegotiation.
823 if (IsCertificateError(result)) {
824 // We don't handle a certificate error during SSL renegotiation, so we
825 // have to return an error that's not in the certificate error range
826 // (-2xx).
827 LOG(ERROR) << "Got a server certificate with error " << result
828 << " during SSL renegotiation";
829 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION;
830 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
831 // TODO(wtc): Need a test case for this code path!
832 DCHECK(stream_.get());
833 DCHECK(is_https_request());
834 response_.cert_request_info = new SSLCertRequestInfo;
835 stream_->GetSSLCertRequestInfo(response_.cert_request_info);
836 result = HandleCertificateRequest(result);
837 if (result == OK)
838 return result;
839 }
840
841 if (result < 0 && result != ERR_CONNECTION_CLOSED)
842 return HandleIOError(result);
843
844 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) {
845 ResetConnectionAndRequestForResend();
846 return OK;
847 }
848
849 // After we call RestartWithAuth a new response_time will be recorded, and
850 // we need to be cautious about incorrectly logging the duration across the
851 // authentication activity.
852 if (result == OK)
853 LogTransactionConnectedMetrics();
854
855 if (result == ERR_CONNECTION_CLOSED) {
856 // For now, if we get at least some data, we do the best we can to make
857 // sense of it and send it back up the stack.
858 int rv = HandleConnectionClosedBeforeEndOfHeaders();
859 if (rv != OK)
860 return rv;
861 }
862
863 if (net_log_.IsLoggingAllEvents()) {
864 net_log_.AddEvent(
865 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
866 make_scoped_refptr(new NetLogHttpResponseParameter(response_.headers)));
867 }
868
869 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
870 // HTTP/0.9 doesn't support the PUT method, so lack of response headers
871 // indicates a buggy server. See:
872 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921
873 if (request_->method == "PUT")
874 return ERR_METHOD_NOT_SUPPORTED;
875 }
876
877 // Check for an intermediate 100 Continue response. An origin server is
878 // allowed to send this response even if we didn't ask for it, so we just
879 // need to skip over it.
880 // We treat any other 1xx in this same way (although in practice getting
881 // a 1xx that isn't a 100 is rare).
882 if (response_.headers->response_code() / 100 == 1) {
883 response_.headers = new HttpResponseHeaders("");
884 next_state_ = STATE_READ_HEADERS;
885 return OK;
886 }
887
888 HostPortPair endpoint = HostPortPair(request_->url.HostNoBrackets(),
889 request_->url.EffectiveIntPort());
890 ProcessAlternateProtocol(session_->http_stream_factory(),
891 session_->mutable_alternate_protocols(),
892 *response_.headers,
893 endpoint);
894
895 int rv = HandleAuthChallenge();
896 if (rv != OK)
897 return rv;
898
899 if (is_https_request())
900 stream_->GetSSLInfo(&response_.ssl_info);
901
902 headers_valid_ = true;
903 return OK;
904 }
905
DoReadBody()906 int HttpNetworkTransaction::DoReadBody() {
907 DCHECK(read_buf_);
908 DCHECK_GT(read_buf_len_, 0);
909 DCHECK(stream_ != NULL);
910
911 next_state_ = STATE_READ_BODY_COMPLETE;
912 return stream_->ReadResponseBody(read_buf_, read_buf_len_, &io_callback_);
913 }
914
DoReadBodyComplete(int result)915 int HttpNetworkTransaction::DoReadBodyComplete(int result) {
916 // We are done with the Read call.
917 bool done = false;
918 if (result <= 0) {
919 DCHECK_NE(ERR_IO_PENDING, result);
920 done = true;
921 }
922
923 bool keep_alive = false;
924 if (stream_->IsResponseBodyComplete()) {
925 // Note: Just because IsResponseBodyComplete is true, we're not
926 // necessarily "done". We're only "done" when it is the last
927 // read on this HttpNetworkTransaction, which will be signified
928 // by a zero-length read.
929 // TODO(mbelshe): The keepalive property is really a property of
930 // the stream. No need to compute it here just to pass back
931 // to the stream's Close function.
932 if (stream_->CanFindEndOfResponse())
933 keep_alive = GetResponseHeaders()->IsKeepAlive();
934 }
935
936 // Clean up connection if we are done.
937 if (done) {
938 LogTransactionMetrics();
939 stream_->Close(!keep_alive);
940 // Note: we don't reset the stream here. We've closed it, but we still
941 // need it around so that callers can call methods such as
942 // GetUploadProgress() and have them be meaningful.
943 // TODO(mbelshe): This means we closed the stream here, and we close it
944 // again in ~HttpNetworkTransaction. Clean that up.
945
946 // The next Read call will return 0 (EOF).
947 }
948
949 // Clear these to avoid leaving around old state.
950 read_buf_ = NULL;
951 read_buf_len_ = 0;
952
953 return result;
954 }
955
DoDrainBodyForAuthRestart()956 int HttpNetworkTransaction::DoDrainBodyForAuthRestart() {
957 // This method differs from DoReadBody only in the next_state_. So we just
958 // call DoReadBody and override the next_state_. Perhaps there is a more
959 // elegant way for these two methods to share code.
960 int rv = DoReadBody();
961 DCHECK(next_state_ == STATE_READ_BODY_COMPLETE);
962 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE;
963 return rv;
964 }
965
966 // TODO(wtc): This method and the DoReadBodyComplete method are almost
967 // the same. Figure out a good way for these two methods to share code.
DoDrainBodyForAuthRestartComplete(int result)968 int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) {
969 // keep_alive defaults to true because the very reason we're draining the
970 // response body is to reuse the connection for auth restart.
971 bool done = false, keep_alive = true;
972 if (result < 0) {
973 // Error or closed connection while reading the socket.
974 done = true;
975 keep_alive = false;
976 } else if (stream_->IsResponseBodyComplete()) {
977 done = true;
978 }
979
980 if (done) {
981 DidDrainBodyForAuthRestart(keep_alive);
982 } else {
983 // Keep draining.
984 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
985 }
986
987 return OK;
988 }
989
LogTransactionConnectedMetrics()990 void HttpNetworkTransaction::LogTransactionConnectedMetrics() {
991 if (logged_response_time_)
992 return;
993
994 logged_response_time_ = true;
995
996 base::TimeDelta total_duration = response_.response_time - start_time_;
997
998 UMA_HISTOGRAM_CLIPPED_TIMES(
999 "Net.Transaction_Connected_Under_10",
1000 total_duration,
1001 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1002 100);
1003
1004 bool reused_socket = stream_->IsConnectionReused();
1005 if (!reused_socket) {
1006 UMA_HISTOGRAM_CLIPPED_TIMES(
1007 "Net.Transaction_Connected_New",
1008 total_duration,
1009 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1010 100);
1011
1012 static bool use_conn_impact_histogram(
1013 base::FieldTrialList::Find("ConnCountImpact") &&
1014 !base::FieldTrialList::Find("ConnCountImpact")->group_name().empty());
1015 if (use_conn_impact_histogram) {
1016 UMA_HISTOGRAM_CLIPPED_TIMES(
1017 base::FieldTrial::MakeName("Net.Transaction_Connected_New",
1018 "ConnCountImpact"),
1019 total_duration,
1020 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1021 100);
1022 }
1023 }
1024
1025 static bool use_spdy_histogram(base::FieldTrialList::Find("SpdyImpact") &&
1026 !base::FieldTrialList::Find("SpdyImpact")->group_name().empty());
1027 if (use_spdy_histogram && response_.was_npn_negotiated) {
1028 UMA_HISTOGRAM_CLIPPED_TIMES(
1029 base::FieldTrial::MakeName("Net.Transaction_Connected_Under_10",
1030 "SpdyImpact"),
1031 total_duration, base::TimeDelta::FromMilliseconds(1),
1032 base::TimeDelta::FromMinutes(10), 100);
1033
1034 if (!reused_socket) {
1035 UMA_HISTOGRAM_CLIPPED_TIMES(
1036 base::FieldTrial::MakeName("Net.Transaction_Connected_New",
1037 "SpdyImpact"),
1038 total_duration, base::TimeDelta::FromMilliseconds(1),
1039 base::TimeDelta::FromMinutes(10), 100);
1040 }
1041 }
1042
1043 // Currently, non-zero priority requests are frame or sub-frame resource
1044 // types. This will change when we also prioritize certain subresources like
1045 // css, js, etc.
1046 if (request_->priority) {
1047 UMA_HISTOGRAM_CLIPPED_TIMES(
1048 "Net.Priority_High_Latency",
1049 total_duration,
1050 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1051 100);
1052 } else {
1053 UMA_HISTOGRAM_CLIPPED_TIMES(
1054 "Net.Priority_Low_Latency",
1055 total_duration,
1056 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1057 100);
1058 }
1059 }
1060
LogTransactionMetrics() const1061 void HttpNetworkTransaction::LogTransactionMetrics() const {
1062 base::TimeDelta duration = base::Time::Now() -
1063 response_.request_time;
1064 if (60 < duration.InMinutes())
1065 return;
1066
1067 base::TimeDelta total_duration = base::Time::Now() - start_time_;
1068
1069 UMA_HISTOGRAM_LONG_TIMES("Net.Transaction_Latency", duration);
1070 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Under_10", duration,
1071 base::TimeDelta::FromMilliseconds(1),
1072 base::TimeDelta::FromMinutes(10),
1073 100);
1074 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Total_Under_10",
1075 total_duration,
1076 base::TimeDelta::FromMilliseconds(1),
1077 base::TimeDelta::FromMinutes(10), 100);
1078 if (!stream_->IsConnectionReused()) {
1079 UMA_HISTOGRAM_CLIPPED_TIMES(
1080 "Net.Transaction_Latency_Total_New_Connection_Under_10",
1081 total_duration, base::TimeDelta::FromMilliseconds(1),
1082 base::TimeDelta::FromMinutes(10), 100);
1083 }
1084 }
1085
HandleCertificateRequest(int error)1086 int HttpNetworkTransaction::HandleCertificateRequest(int error) {
1087 // There are two paths through which the server can request a certificate
1088 // from us. The first is during the initial handshake, the second is
1089 // during SSL renegotiation.
1090 //
1091 // In both cases, we want to close the connection before proceeding.
1092 // We do this for two reasons:
1093 // First, we don't want to keep the connection to the server hung for a
1094 // long time while the user selects a certificate.
1095 // Second, even if we did keep the connection open, NSS has a bug where
1096 // restarting the handshake for ClientAuth is currently broken.
1097 DCHECK_EQ(error, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
1098
1099 if (stream_.get()) {
1100 // Since we already have a stream, we're being called as part of SSL
1101 // renegotiation.
1102 DCHECK(!stream_request_.get());
1103 stream_->Close(true);
1104 stream_.reset();
1105 }
1106
1107 // The server is asking for a client certificate during the initial
1108 // handshake.
1109 stream_request_.reset();
1110
1111 // If the user selected one of the certificates in client_certs or declined
1112 // to provide one for this server before, use the past decision
1113 // automatically.
1114 scoped_refptr<X509Certificate> client_cert;
1115 bool found_cached_cert = session_->ssl_client_auth_cache()->Lookup(
1116 response_.cert_request_info->host_and_port, &client_cert);
1117 if (!found_cached_cert)
1118 return error;
1119
1120 // Check that the certificate selected is still a certificate the server
1121 // is likely to accept, based on the criteria supplied in the
1122 // CertificateRequest message.
1123 if (client_cert) {
1124 const std::vector<scoped_refptr<X509Certificate> >& client_certs =
1125 response_.cert_request_info->client_certs;
1126 bool cert_still_valid = false;
1127 for (size_t i = 0; i < client_certs.size(); ++i) {
1128 if (client_cert->Equals(client_certs[i])) {
1129 cert_still_valid = true;
1130 break;
1131 }
1132 }
1133
1134 if (!cert_still_valid)
1135 return error;
1136 }
1137
1138 // TODO(davidben): Add a unit test which covers this path; we need to be
1139 // able to send a legitimate certificate and also bypass/clear the
1140 // SSL session cache.
1141 ssl_config_.client_cert = client_cert;
1142 ssl_config_.send_client_cert = true;
1143 next_state_ = STATE_CREATE_STREAM;
1144 // Reset the other member variables.
1145 // Note: this is necessary only with SSL renegotiation.
1146 ResetStateForRestart();
1147 return OK;
1148 }
1149
1150 // TODO(rch): This does not correctly handle errors when an SSL proxy is
1151 // being used, as all of the errors are handled as if they were generated
1152 // by the endpoint host, request_->url, rather than considering if they were
1153 // generated by the SSL proxy. http://crbug.com/69329
HandleSSLHandshakeError(int error)1154 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
1155 DCHECK(request_);
1156 if (ssl_config_.send_client_cert &&
1157 (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) {
1158 session_->ssl_client_auth_cache()->Remove(
1159 GetHostAndPort(request_->url));
1160 }
1161
1162 switch (error) {
1163 case ERR_SSL_PROTOCOL_ERROR:
1164 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1165 case ERR_SSL_DECOMPRESSION_FAILURE_ALERT:
1166 case ERR_SSL_BAD_RECORD_MAC_ALERT:
1167 if (ssl_config_.tls1_enabled) {
1168 // This could be a TLS-intolerant server, an SSL 3.0 server that
1169 // chose a TLS-only cipher suite or a server with buggy DEFLATE
1170 // support. Turn off TLS 1.0, DEFLATE support and retry.
1171 session_->http_stream_factory()->AddTLSIntolerantServer(
1172 HostPortPair::FromURL(request_->url));
1173 ResetConnectionAndRequestForResend();
1174 error = OK;
1175 }
1176 break;
1177 }
1178 return error;
1179 }
1180
1181 // This method determines whether it is safe to resend the request after an
1182 // IO error. It can only be called in response to request header or body
1183 // write errors or response header read errors. It should not be used in
1184 // other cases, such as a Connect error.
HandleIOError(int error)1185 int HttpNetworkTransaction::HandleIOError(int error) {
1186 // SSL errors may happen at any time during the stream and indicate issues
1187 // with the underlying connection. Because the peer may request
1188 // renegotiation at any time, check and handle any possible SSL handshake
1189 // related errors. In addition to renegotiation, TLS False/Snap Start may
1190 // cause SSL handshake errors to be delayed until the first or second Write
1191 // (Snap Start) or the first Read (False & Snap Start) on the underlying
1192 // connection.
1193 error = HandleSSLHandshakeError(error);
1194
1195 switch (error) {
1196 // If we try to reuse a connection that the server is in the process of
1197 // closing, we may end up successfully writing out our request (or a
1198 // portion of our request) only to find a connection error when we try to
1199 // read from (or finish writing to) the socket.
1200 case ERR_CONNECTION_RESET:
1201 case ERR_CONNECTION_CLOSED:
1202 case ERR_CONNECTION_ABORTED:
1203 if (ShouldResendRequest(error)) {
1204 ResetConnectionAndRequestForResend();
1205 error = OK;
1206 }
1207 break;
1208 case ERR_SPDY_PING_FAILED:
1209 ResetConnectionAndRequestForResend();
1210 error = OK;
1211 break;
1212 }
1213 return error;
1214 }
1215
ResetStateForRestart()1216 void HttpNetworkTransaction::ResetStateForRestart() {
1217 ResetStateForAuthRestart();
1218 stream_.reset();
1219 }
1220
ResetStateForAuthRestart()1221 void HttpNetworkTransaction::ResetStateForAuthRestart() {
1222 pending_auth_target_ = HttpAuth::AUTH_NONE;
1223 read_buf_ = NULL;
1224 read_buf_len_ = 0;
1225 headers_valid_ = false;
1226 request_headers_.Clear();
1227 response_ = HttpResponseInfo();
1228 establishing_tunnel_ = false;
1229 }
1230
GetResponseHeaders() const1231 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const {
1232 return response_.headers;
1233 }
1234
ShouldResendRequest(int error) const1235 bool HttpNetworkTransaction::ShouldResendRequest(int error) const {
1236 bool connection_is_proven = stream_->IsConnectionReused();
1237 bool has_received_headers = GetResponseHeaders() != NULL;
1238
1239 // NOTE: we resend a request only if we reused a keep-alive connection.
1240 // This automatically prevents an infinite resend loop because we'll run
1241 // out of the cached keep-alive connections eventually.
1242 if (connection_is_proven && !has_received_headers)
1243 return true;
1244 return false;
1245 }
1246
ResetConnectionAndRequestForResend()1247 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() {
1248 if (stream_.get()) {
1249 stream_->Close(true);
1250 stream_.reset();
1251 }
1252
1253 // We need to clear request_headers_ because it contains the real request
1254 // headers, but we may need to resend the CONNECT request first to recreate
1255 // the SSL tunnel.
1256 request_headers_.Clear();
1257 next_state_ = STATE_CREATE_STREAM; // Resend the request.
1258 }
1259
ShouldApplyProxyAuth() const1260 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const {
1261 return !is_https_request() &&
1262 (proxy_info_.is_https() || proxy_info_.is_http());
1263 }
1264
ShouldApplyServerAuth() const1265 bool HttpNetworkTransaction::ShouldApplyServerAuth() const {
1266 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA);
1267 }
1268
HandleAuthChallenge()1269 int HttpNetworkTransaction::HandleAuthChallenge() {
1270 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders());
1271 DCHECK(headers);
1272
1273 int status = headers->response_code();
1274 if (status != 401 && status != 407)
1275 return OK;
1276 HttpAuth::Target target = status == 407 ?
1277 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER;
1278 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
1279 return ERR_UNEXPECTED_PROXY_AUTH;
1280
1281 // This case can trigger when an HTTPS server responds with a 407 status
1282 // code through a non-authenticating proxy.
1283 if (!auth_controllers_[target].get())
1284 return ERR_UNEXPECTED_PROXY_AUTH;
1285
1286 int rv = auth_controllers_[target]->HandleAuthChallenge(
1287 headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false,
1288 net_log_);
1289 if (auth_controllers_[target]->HaveAuthHandler())
1290 pending_auth_target_ = target;
1291
1292 scoped_refptr<AuthChallengeInfo> auth_info =
1293 auth_controllers_[target]->auth_info();
1294 if (auth_info.get())
1295 response_.auth_challenge = auth_info;
1296
1297 return rv;
1298 }
1299
HaveAuth(HttpAuth::Target target) const1300 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const {
1301 return auth_controllers_[target].get() &&
1302 auth_controllers_[target]->HaveAuth();
1303 }
1304
AuthURL(HttpAuth::Target target) const1305 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const {
1306 switch (target) {
1307 case HttpAuth::AUTH_PROXY: {
1308 if (!proxy_info_.proxy_server().is_valid() ||
1309 proxy_info_.proxy_server().is_direct()) {
1310 return GURL(); // There is no proxy server.
1311 }
1312 const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
1313 return GURL(scheme +
1314 proxy_info_.proxy_server().host_port_pair().ToString());
1315 }
1316 case HttpAuth::AUTH_SERVER:
1317 return request_->url;
1318 default:
1319 return GURL();
1320 }
1321 }
1322
1323 #define STATE_CASE(s) \
1324 case s: \
1325 description = base::StringPrintf("%s (0x%08X)", #s, s); \
1326 break
1327
DescribeState(State state)1328 std::string HttpNetworkTransaction::DescribeState(State state) {
1329 std::string description;
1330 switch (state) {
1331 STATE_CASE(STATE_CREATE_STREAM);
1332 STATE_CASE(STATE_CREATE_STREAM_COMPLETE);
1333 STATE_CASE(STATE_BUILD_REQUEST);
1334 STATE_CASE(STATE_BUILD_REQUEST_COMPLETE);
1335 STATE_CASE(STATE_SEND_REQUEST);
1336 STATE_CASE(STATE_SEND_REQUEST_COMPLETE);
1337 STATE_CASE(STATE_READ_HEADERS);
1338 STATE_CASE(STATE_READ_HEADERS_COMPLETE);
1339 STATE_CASE(STATE_READ_BODY);
1340 STATE_CASE(STATE_READ_BODY_COMPLETE);
1341 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART);
1342 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE);
1343 STATE_CASE(STATE_NONE);
1344 default:
1345 description = base::StringPrintf("Unknown state 0x%08X (%u)", state,
1346 state);
1347 break;
1348 }
1349 return description;
1350 }
1351
1352 #undef STATE_CASE
1353
1354 } // namespace net
1355