Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: net/http/http_network_transaction.cc

Issue 249031: Refactor HttpNetworkTransaction: Parse stream in HttpStream (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include "base/scoped_ptr.h" 7 #include "base/scoped_ptr.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/field_trial.h" 9 #include "base/field_trial.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/trace_event.h" 12 #include "base/trace_event.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "net/base/connection_type_histograms.h" 14 #include "net/base/connection_type_histograms.h"
15 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
16 #include "net/base/load_flags.h" 16 #include "net/base/load_flags.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/base/net_util.h" 18 #include "net/base/net_util.h"
19 #include "net/base/ssl_cert_request_info.h" 19 #include "net/base/ssl_cert_request_info.h"
20 #include "net/base/upload_data_stream.h" 20 #include "net/base/upload_data_stream.h"
21 #include "net/http/http_auth.h" 21 #include "net/http/http_auth.h"
22 #include "net/http/http_auth_handler.h" 22 #include "net/http/http_auth_handler.h"
23 #include "net/http/http_basic_stream.h" 23 #include "net/http/http_basic_stream.h"
24 #include "net/http/http_chunked_decoder.h" 24 #include "net/http/http_chunked_decoder.h"
25 #include "net/http/http_network_session.h" 25 #include "net/http/http_network_session.h"
26 #include "net/http/http_request_info.h" 26 #include "net/http/http_request_info.h"
27 #include "net/http/http_response_headers.h" 27 #include "net/http/http_response_headers.h"
28 #include "net/http/http_response_info.h"
28 #include "net/http/http_util.h" 29 #include "net/http/http_util.h"
29 #include "net/socket/client_socket_factory.h" 30 #include "net/socket/client_socket_factory.h"
30 #include "net/socket/socks5_client_socket.h" 31 #include "net/socket/socks5_client_socket.h"
31 #include "net/socket/socks_client_socket.h" 32 #include "net/socket/socks_client_socket.h"
32 #include "net/socket/ssl_client_socket.h" 33 #include "net/socket/ssl_client_socket.h"
33 34
34 using base::Time; 35 using base::Time;
35 36
36 namespace net { 37 namespace net {
37 38
38 void HttpNetworkTransaction::ResponseHeaders::Realloc(size_t new_size) {
39 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size)));
40 }
41
42 namespace { 39 namespace {
43 40
44 void BuildRequestHeaders(const HttpRequestInfo* request_info, 41 void BuildRequestHeaders(const HttpRequestInfo* request_info,
45 const std::string& authorization_headers, 42 const std::string& authorization_headers,
46 const UploadDataStream* upload_data_stream, 43 const UploadDataStream* upload_data_stream,
47 bool using_proxy, 44 bool using_proxy,
48 std::string* request_headers) { 45 std::string* request_headers) {
49 const std::string path = using_proxy ? 46 const std::string path = using_proxy ?
50 HttpUtil::SpecForRequest(request_info->url) : 47 HttpUtil::SpecForRequest(request_info->url) :
51 HttpUtil::PathForRequest(request_info->url); 48 HttpUtil::PathForRequest(request_info->url);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 128
132 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session) 129 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session)
133 : pending_auth_target_(HttpAuth::AUTH_NONE), 130 : pending_auth_target_(HttpAuth::AUTH_NONE),
134 ALLOW_THIS_IN_INITIALIZER_LIST( 131 ALLOW_THIS_IN_INITIALIZER_LIST(
135 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), 132 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)),
136 user_callback_(NULL), 133 user_callback_(NULL),
137 session_(session), 134 session_(session),
138 request_(NULL), 135 request_(NULL),
139 pac_request_(NULL), 136 pac_request_(NULL),
140 reused_socket_(false), 137 reused_socket_(false),
138 headers_valid_(false),
139 logged_response_time(false),
141 using_ssl_(false), 140 using_ssl_(false),
142 proxy_mode_(kDirectConnection), 141 proxy_mode_(kDirectConnection),
143 establishing_tunnel_(false), 142 establishing_tunnel_(false),
144 reading_body_from_socket_(false),
145 embedded_identity_used_(false), 143 embedded_identity_used_(false),
146 request_headers_(new RequestHeaders()),
147 request_headers_bytes_sent_(0),
148 header_buf_(new ResponseHeaders()),
149 header_buf_capacity_(0),
150 header_buf_len_(0),
151 header_buf_body_offset_(-1),
152 header_buf_http_offset_(-1),
153 response_body_length_(-1), // -1 means unspecified.
154 response_body_read_(0),
155 read_buf_len_(0), 144 read_buf_len_(0),
156 next_state_(STATE_NONE) { 145 next_state_(STATE_NONE) {
157 session->ssl_config_service()->GetSSLConfig(&ssl_config_); 146 session->ssl_config_service()->GetSSLConfig(&ssl_config_);
158 } 147 }
159 148
160 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, 149 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
161 CompletionCallback* callback, 150 CompletionCallback* callback,
162 LoadLog* load_log) { 151 LoadLog* load_log) {
163 UpdateConnectionTypeHistograms(CONNECTION_ANY); 152 UpdateConnectionTypeHistograms(CONNECTION_ANY);
164 153
165 load_log_ = load_log; 154 load_log_ = load_log;
166 request_ = request_info; 155 request_ = request_info;
167 start_time_ = base::Time::Now(); 156 start_time_ = base::Time::Now();
168 157
169 next_state_ = STATE_RESOLVE_PROXY; 158 next_state_ = STATE_RESOLVE_PROXY;
170 int rv = DoLoop(OK); 159 int rv = DoLoop(OK);
171 if (rv == ERR_IO_PENDING) 160 if (rv == ERR_IO_PENDING)
172 user_callback_ = callback; 161 user_callback_ = callback;
173 return rv; 162 return rv;
174 } 163 }
175 164
176 int HttpNetworkTransaction::RestartIgnoringLastError( 165 int HttpNetworkTransaction::RestartIgnoringLastError(
177 CompletionCallback* callback) { 166 CompletionCallback* callback) {
178 if (connection_.socket()->IsConnected()) { 167 if (connection_.socket()->IsConnected()) {
179 next_state_ = STATE_WRITE_HEADERS; 168 next_state_ = STATE_SEND_REQUEST;
180 } else { 169 } else {
181 connection_.socket()->Disconnect(); 170 connection_.socket()->Disconnect();
182 connection_.Reset(); 171 connection_.Reset();
183 next_state_ = STATE_INIT_CONNECTION; 172 next_state_ = STATE_INIT_CONNECTION;
184 } 173 }
185 int rv = DoLoop(OK); 174 int rv = DoLoop(OK);
186 if (rv == ERR_IO_PENDING) 175 if (rv == ERR_IO_PENDING)
187 user_callback_ = callback; 176 user_callback_ = callback;
188 return rv; 177 return rv;
189 } 178 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // See http://crbug.com/21015. 248 // See http://crbug.com/21015.
260 bool has_auth_identity = 249 bool has_auth_identity =
261 auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE; 250 auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE;
262 if (has_auth_identity) { 251 if (has_auth_identity) {
263 session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target], 252 session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target],
264 auth_identity_[target].username, auth_identity_[target].password, 253 auth_identity_[target].username, auth_identity_[target].password,
265 AuthPath(target)); 254 AuthPath(target));
266 } 255 }
267 256
268 bool keep_alive = false; 257 bool keep_alive = false;
269 if (response_.headers->IsKeepAlive()) { 258 // Even if the server says the connection is keep-alive, we have to be
270 // If there is a response body of known length, we need to drain it first. 259 // able to find the end of each response in order to reuse the connection.
271 if (response_body_length_ > 0 || chunked_decoder_.get()) { 260 if (GetResponseHeaders()->IsKeepAlive() &&
261 http_stream_->CanFindEndOfResponse()) {
262 // If the response body hasn't been completely read, we need to drain
263 // it first.
264 if (!http_stream_->IsResponseBodyComplete()) {
272 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; 265 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
273 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket 266 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket.
274 read_buf_len_ = kDrainBodyBufferSize; 267 read_buf_len_ = kDrainBodyBufferSize;
275 return; 268 return;
276 } 269 }
277 if (response_body_length_ == 0) // No response body to drain. 270 keep_alive = true;
278 keep_alive = true;
279 // response_body_length_ is -1 and we're not using chunked encoding. We
280 // don't know the length of the response body, so we can't reuse this
281 // connection even though the server says it's keep-alive.
282 } 271 }
283 272
284 // We don't need to drain the response body, so we act as if we had drained 273 // We don't need to drain the response body, so we act as if we had drained
285 // the response body. 274 // the response body.
286 DidDrainBodyForAuthRestart(keep_alive); 275 DidDrainBodyForAuthRestart(keep_alive);
287 } 276 }
288 277
289 void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { 278 void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
290 if (keep_alive) { 279 if (keep_alive) {
291 next_state_ = STATE_WRITE_HEADERS; 280 next_state_ = STATE_SEND_REQUEST;
292 reused_socket_ = true; 281 reused_socket_ = true;
293 } else { 282 } else {
294 next_state_ = STATE_INIT_CONNECTION; 283 next_state_ = STATE_INIT_CONNECTION;
295 connection_.socket()->Disconnect(); 284 connection_.socket()->Disconnect();
296 connection_.Reset(); 285 connection_.Reset();
297 } 286 }
298 287
299 // Reset the other member variables. 288 // Reset the other member variables.
300 ResetStateForRestart(); 289 ResetStateForRestart();
301 } 290 }
302 291
303 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, 292 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len,
304 CompletionCallback* callback) { 293 CompletionCallback* callback) {
305 DCHECK(response_.headers); 294 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
295 DCHECK(headers.get());
306 DCHECK(buf); 296 DCHECK(buf);
307 DCHECK_LT(0, buf_len); 297 DCHECK_LT(0, buf_len);
308 298
309 if (!connection_.is_initialized()) 299 if (!connection_.is_initialized())
310 return 0; // connection_ has been reset. Treat like EOF. 300 return 0; // connection_ has been reset. Treat like EOF.
311 301
312 if (establishing_tunnel_) { 302 if (establishing_tunnel_) {
313 // We're trying to read the body of the response but we're still trying to 303 // We're trying to read the body of the response but we're still trying to
314 // establish an SSL tunnel through the proxy. We can't read these bytes 304 // establish an SSL tunnel through the proxy. We can't read these bytes
315 // when establishing a tunnel because they might be controlled by an active 305 // when establishing a tunnel because they might be controlled by an active
316 // network attacker. We don't worry about this for HTTP because an active 306 // network attacker. We don't worry about this for HTTP because an active
317 // network attacker can already control HTTP sessions. 307 // network attacker can already control HTTP sessions.
318 // We reach this case when the user cancels a 407 proxy auth prompt. 308 // We reach this case when the user cancels a 407 proxy auth prompt.
319 // See http://crbug.com/8473 309 // See http://crbug.com/8473
320 DCHECK_EQ(407, response_.headers->response_code()); 310 DCHECK_EQ(407, headers->response_code());
321 LogBlockedTunnelResponse(response_.headers->response_code()); 311 LogBlockedTunnelResponse(headers->response_code());
322 return ERR_TUNNEL_CONNECTION_FAILED; 312 return ERR_TUNNEL_CONNECTION_FAILED;
323 } 313 }
324 314
325 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. 315 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
326 // See if the user is passing in an IOBuffer with a NULL |data_|. 316 // See if the user is passing in an IOBuffer with a NULL |data_|.
327 CHECK(buf); 317 CHECK(buf);
328 CHECK(buf->data()); 318 CHECK(buf->data());
329 319
330 read_buf_ = buf; 320 read_buf_ = buf;
331 read_buf_len_ = buf_len; 321 read_buf_len_ = buf_len;
332 322
333 next_state_ = STATE_READ_BODY; 323 next_state_ = STATE_READ_BODY;
334 int rv = DoLoop(OK); 324 int rv = DoLoop(OK);
335 if (rv == ERR_IO_PENDING) 325 if (rv == ERR_IO_PENDING)
336 user_callback_ = callback; 326 user_callback_ = callback;
337 return rv; 327 return rv;
338 } 328 }
339 329
340 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { 330 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const {
341 return (response_.headers || response_.ssl_info.cert || 331 const HttpResponseInfo* response = http_stream_->GetResponseInfo();
342 response_.cert_request_info) ? &response_ : NULL; 332 return ((headers_valid_ && response->headers) || response->ssl_info.cert ||
333 response->cert_request_info) ? response : NULL;
343 } 334 }
344 335
345 LoadState HttpNetworkTransaction::GetLoadState() const { 336 LoadState HttpNetworkTransaction::GetLoadState() const {
346 // TODO(wtc): Define a new LoadState value for the 337 // TODO(wtc): Define a new LoadState value for the
347 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. 338 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request.
348 switch (next_state_) { 339 switch (next_state_) {
349 case STATE_RESOLVE_PROXY_COMPLETE: 340 case STATE_RESOLVE_PROXY_COMPLETE:
350 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 341 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
351 case STATE_INIT_CONNECTION_COMPLETE: 342 case STATE_INIT_CONNECTION_COMPLETE:
352 return connection_.GetLoadState(); 343 return connection_.GetLoadState();
353 case STATE_WRITE_HEADERS_COMPLETE: 344 case STATE_SEND_REQUEST_COMPLETE:
354 case STATE_WRITE_BODY_COMPLETE:
355 return LOAD_STATE_SENDING_REQUEST; 345 return LOAD_STATE_SENDING_REQUEST;
356 case STATE_READ_HEADERS_COMPLETE: 346 case STATE_READ_HEADERS_COMPLETE:
357 return LOAD_STATE_WAITING_FOR_RESPONSE; 347 return LOAD_STATE_WAITING_FOR_RESPONSE;
358 case STATE_READ_BODY_COMPLETE: 348 case STATE_READ_BODY_COMPLETE:
359 return LOAD_STATE_READING_RESPONSE; 349 return LOAD_STATE_READING_RESPONSE;
360 default: 350 default:
361 return LOAD_STATE_IDLE; 351 return LOAD_STATE_IDLE;
362 } 352 }
363 } 353 }
364 354
365 uint64 HttpNetworkTransaction::GetUploadProgress() const { 355 uint64 HttpNetworkTransaction::GetUploadProgress() const {
366 if (!request_body_stream_.get()) 356 if (!http_stream_.get())
367 return 0; 357 return 0;
368 358
369 return request_body_stream_->position(); 359 return http_stream_->GetUploadProgress();
370 } 360 }
371 361
372 HttpNetworkTransaction::~HttpNetworkTransaction() { 362 HttpNetworkTransaction::~HttpNetworkTransaction() {
373 // If we still have an open socket, then make sure to disconnect it so it 363 // If we still have an open socket, then make sure to disconnect it so it
374 // won't call us back and we don't try to reuse it later on. 364 // won't call us back and we don't try to reuse it later on.
375 if (connection_.is_initialized()) 365 if (connection_.is_initialized())
376 connection_.socket()->Disconnect(); 366 connection_.socket()->Disconnect();
377 367
378 if (pac_request_) 368 if (pac_request_)
379 session_->proxy_service()->CancelPacRequest(pac_request_); 369 session_->proxy_service()->CancelPacRequest(pac_request_);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 break; 422 break;
433 case STATE_SSL_CONNECT: 423 case STATE_SSL_CONNECT:
434 DCHECK_EQ(OK, rv); 424 DCHECK_EQ(OK, rv);
435 TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec()); 425 TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec());
436 rv = DoSSLConnect(); 426 rv = DoSSLConnect();
437 break; 427 break;
438 case STATE_SSL_CONNECT_COMPLETE: 428 case STATE_SSL_CONNECT_COMPLETE:
439 rv = DoSSLConnectComplete(rv); 429 rv = DoSSLConnectComplete(rv);
440 TRACE_EVENT_END("http.ssl_connect", request_, request_->url.spec()); 430 TRACE_EVENT_END("http.ssl_connect", request_, request_->url.spec());
441 break; 431 break;
442 case STATE_WRITE_HEADERS: 432 case STATE_SEND_REQUEST:
443 DCHECK_EQ(OK, rv); 433 DCHECK_EQ(OK, rv);
444 TRACE_EVENT_BEGIN("http.write_headers", request_, request_->url.spec()); 434 TRACE_EVENT_BEGIN("http.send_request", request_, request_->url.spec());
445 rv = DoWriteHeaders(); 435 rv = DoSendRequest();
446 break; 436 break;
447 case STATE_WRITE_HEADERS_COMPLETE: 437 case STATE_SEND_REQUEST_COMPLETE:
448 rv = DoWriteHeadersComplete(rv); 438 rv = DoSendRequestComplete(rv);
449 TRACE_EVENT_END("http.write_headers", request_, request_->url.spec()); 439 TRACE_EVENT_END("http.send_request", request_, request_->url.spec());
450 break;
451 case STATE_WRITE_BODY:
452 DCHECK_EQ(OK, rv);
453 TRACE_EVENT_BEGIN("http.write_body", request_, request_->url.spec());
454 rv = DoWriteBody();
455 break;
456 case STATE_WRITE_BODY_COMPLETE:
457 rv = DoWriteBodyComplete(rv);
458 TRACE_EVENT_END("http.write_body", request_, request_->url.spec());
459 break; 440 break;
460 case STATE_READ_HEADERS: 441 case STATE_READ_HEADERS:
461 DCHECK_EQ(OK, rv); 442 DCHECK_EQ(OK, rv);
462 TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec()); 443 TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec());
463 rv = DoReadHeaders(); 444 rv = DoReadHeaders();
464 break; 445 break;
465 case STATE_READ_HEADERS_COMPLETE: 446 case STATE_READ_HEADERS_COMPLETE:
466 rv = DoReadHeadersComplete(rv); 447 rv = DoReadHeadersComplete(rv);
467 TRACE_EVENT_END("http.read_headers", request_, request_->url.spec()); 448 TRACE_EVENT_END("http.read_headers", request_, request_->url.spec());
468 break; 449 break;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 585
605 DCHECK(connection_.is_initialized()); 586 DCHECK(connection_.is_initialized());
606 587
607 LogTCPConnectedMetrics(connection_); 588 LogTCPConnectedMetrics(connection_);
608 589
609 // Set the reused_socket_ flag to indicate that we are using a keep-alive 590 // Set the reused_socket_ flag to indicate that we are using a keep-alive
610 // connection. This flag is used to handle errors that occur while we are 591 // connection. This flag is used to handle errors that occur while we are
611 // trying to reuse a keep-alive connection. 592 // trying to reuse a keep-alive connection.
612 reused_socket_ = connection_.is_reused(); 593 reused_socket_ = connection_.is_reused();
613 if (reused_socket_) { 594 if (reused_socket_) {
614 next_state_ = STATE_WRITE_HEADERS; 595 next_state_ = STATE_SEND_REQUEST;
615 } else { 596 } else {
616 // Now we have a TCP connected socket. Perform other connection setup as 597 // Now we have a TCP connected socket. Perform other connection setup as
617 // needed. 598 // needed.
618 if (proxy_mode_ == kSOCKSProxy) 599 if (proxy_mode_ == kSOCKSProxy)
619 next_state_ = STATE_SOCKS_CONNECT; 600 next_state_ = STATE_SOCKS_CONNECT;
620 else if (using_ssl_ && proxy_mode_ == kDirectConnection) { 601 else if (using_ssl_ && proxy_mode_ == kDirectConnection) {
621 next_state_ = STATE_SSL_CONNECT; 602 next_state_ = STATE_SSL_CONNECT;
622 } else { 603 } else {
623 next_state_ = STATE_WRITE_HEADERS; 604 next_state_ = STATE_SEND_REQUEST;
624 if (proxy_mode_ == kHTTPProxyUsingTunnel) 605 if (proxy_mode_ == kHTTPProxyUsingTunnel)
625 establishing_tunnel_ = true; 606 establishing_tunnel_ = true;
626 } 607 }
627 } 608 }
609 headers_valid_ = false;
628 http_stream_.reset(new HttpBasicStream(&connection_)); 610 http_stream_.reset(new HttpBasicStream(&connection_));
629 return OK; 611 return OK;
630 } 612 }
631 613
632 int HttpNetworkTransaction::DoSOCKSConnect() { 614 int HttpNetworkTransaction::DoSOCKSConnect() {
633 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 615 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
634 616
635 next_state_ = STATE_SOCKS_CONNECT_COMPLETE; 617 next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
636 618
637 // Add a SOCKS connection on top of our existing transport socket. 619 // Add a SOCKS connection on top of our existing transport socket.
(...skipping 10 matching lines...) Expand all
648 return connection_.socket()->Connect(&io_callback_); 630 return connection_.socket()->Connect(&io_callback_);
649 } 631 }
650 632
651 int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) { 633 int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) {
652 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 634 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
653 635
654 if (result == OK) { 636 if (result == OK) {
655 if (using_ssl_) { 637 if (using_ssl_) {
656 next_state_ = STATE_SSL_CONNECT; 638 next_state_ = STATE_SSL_CONNECT;
657 } else { 639 } else {
658 next_state_ = STATE_WRITE_HEADERS; 640 next_state_ = STATE_SEND_REQUEST;
659 } 641 }
660 } else { 642 } else {
661 result = ReconsiderProxyAfterError(result); 643 result = ReconsiderProxyAfterError(result);
662 } 644 }
663 return result; 645 return result;
664 } 646 }
665 647
666 int HttpNetworkTransaction::DoSSLConnect() { 648 int HttpNetworkTransaction::DoSSLConnect() {
667 next_state_ = STATE_SSL_CONNECT_COMPLETE; 649 next_state_ = STATE_SSL_CONNECT_COMPLETE;
668 650
(...skipping 18 matching lines...) Expand all
687 DCHECK(ssl_connect_start_time_ != base::TimeTicks()); 669 DCHECK(ssl_connect_start_time_ != base::TimeTicks());
688 base::TimeDelta connect_duration = 670 base::TimeDelta connect_duration =
689 base::TimeTicks::Now() - ssl_connect_start_time_; 671 base::TimeTicks::Now() - ssl_connect_start_time_;
690 672
691 UMA_HISTOGRAM_CLIPPED_TIMES("Net.SSL_Connection_Latency", 673 UMA_HISTOGRAM_CLIPPED_TIMES("Net.SSL_Connection_Latency",
692 connect_duration, 674 connect_duration,
693 base::TimeDelta::FromMilliseconds(1), 675 base::TimeDelta::FromMilliseconds(1),
694 base::TimeDelta::FromMinutes(10), 676 base::TimeDelta::FromMinutes(10),
695 100); 677 100);
696 678
697 next_state_ = STATE_WRITE_HEADERS; 679 next_state_ = STATE_SEND_REQUEST;
698 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 680 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
699 result = HandleCertificateRequest(result); 681 result = HandleCertificateRequest(result);
700 } else { 682 } else {
701 result = HandleSSLHandshakeError(result); 683 result = HandleSSLHandshakeError(result);
702 } 684 }
703 return result; 685 return result;
704 } 686 }
705 687
706 int HttpNetworkTransaction::DoWriteHeaders() { 688 int HttpNetworkTransaction::DoSendRequest() {
707 next_state_ = STATE_WRITE_HEADERS_COMPLETE; 689 next_state_ = STATE_SEND_REQUEST_COMPLETE;
690
691 UploadDataStream* request_body = NULL;
692 if (!establishing_tunnel_ && request_->upload_data)
693 request_body = new UploadDataStream(request_->upload_data);
708 694
709 // This is constructed lazily (instead of within our Start method), so that 695 // This is constructed lazily (instead of within our Start method), so that
710 // we have proxy info available. 696 // we have proxy info available.
711 if (request_headers_->headers_.empty()) { 697 if (request_headers_.empty()) {
712 // Figure out if we can/should add Proxy-Authentication & Authentication 698 // Figure out if we can/should add Proxy-Authentication & Authentication
713 // headers. 699 // headers.
714 bool have_proxy_auth = 700 bool have_proxy_auth =
715 ShouldApplyProxyAuth() && 701 ShouldApplyProxyAuth() &&
716 (HaveAuth(HttpAuth::AUTH_PROXY) || 702 (HaveAuth(HttpAuth::AUTH_PROXY) ||
717 SelectPreemptiveAuth(HttpAuth::AUTH_PROXY)); 703 SelectPreemptiveAuth(HttpAuth::AUTH_PROXY));
718 bool have_server_auth = 704 bool have_server_auth =
719 ShouldApplyServerAuth() && 705 ShouldApplyServerAuth() &&
720 (HaveAuth(HttpAuth::AUTH_SERVER) || 706 (HaveAuth(HttpAuth::AUTH_SERVER) ||
721 SelectPreemptiveAuth(HttpAuth::AUTH_SERVER)); 707 SelectPreemptiveAuth(HttpAuth::AUTH_SERVER));
722 708
723 std::string authorization_headers; 709 std::string authorization_headers;
724 710
725 // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization 711 // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization
726 // header with no credentials), we should return an error to prevent 712 // header with no credentials), we should return an error to prevent
727 // entering an infinite auth restart loop. See http://crbug.com/21050. 713 // entering an infinite auth restart loop. See http://crbug.com/21050.
728 if (have_proxy_auth) 714 if (have_proxy_auth)
729 authorization_headers.append( 715 authorization_headers.append(
730 BuildAuthorizationHeader(HttpAuth::AUTH_PROXY)); 716 BuildAuthorizationHeader(HttpAuth::AUTH_PROXY));
731 if (have_server_auth) 717 if (have_server_auth)
732 authorization_headers.append( 718 authorization_headers.append(
733 BuildAuthorizationHeader(HttpAuth::AUTH_SERVER)); 719 BuildAuthorizationHeader(HttpAuth::AUTH_SERVER));
734 720
735 if (establishing_tunnel_) { 721 if (establishing_tunnel_) {
736 BuildTunnelRequest(request_, authorization_headers, 722 BuildTunnelRequest(request_, authorization_headers, &request_headers_);
737 &request_headers_->headers_);
738 } else { 723 } else {
739 if (request_->upload_data) 724 BuildRequestHeaders(request_, authorization_headers, request_body,
740 request_body_stream_.reset(new UploadDataStream(request_->upload_data)); 725 proxy_mode_ == kHTTPProxy, &request_headers_);
741 BuildRequestHeaders(request_, authorization_headers,
742 request_body_stream_.get(),
743 proxy_mode_ == kHTTPProxy,
744 &request_headers_->headers_);
745 } 726 }
746 } 727 }
747 728
748 // Record our best estimate of the 'request time' as the time when we send 729 return http_stream_->SendRequest(request_, request_headers_, request_body,
749 // out the first bytes of the request headers. 730 &io_callback_);
750 if (request_headers_bytes_sent_ == 0) {
751 response_.request_time = Time::Now();
752 }
753
754 request_headers_->SetDataOffset(request_headers_bytes_sent_);
755 int buf_len = static_cast<int>(request_headers_->headers_.size() -
756 request_headers_bytes_sent_);
757 DCHECK_GT(buf_len, 0);
758
759 return http_stream_->Write(request_headers_, buf_len, &io_callback_);
760 } 731 }
761 732
762 int HttpNetworkTransaction::DoWriteHeadersComplete(int result) { 733 int HttpNetworkTransaction::DoSendRequestComplete(int result) {
763 if (result < 0) 734 if (result < 0)
764 return HandleIOError(result); 735 return HandleIOError(result);
765 736
766 request_headers_bytes_sent_ += result; 737 next_state_ = STATE_READ_HEADERS;
767 if (request_headers_bytes_sent_ < request_headers_->headers_.size()) {
768 next_state_ = STATE_WRITE_HEADERS;
769 } else if (!establishing_tunnel_ && request_body_stream_.get() &&
770 request_body_stream_->size()) {
771 next_state_ = STATE_WRITE_BODY;
772 } else {
773 next_state_ = STATE_READ_HEADERS;
774 }
775 return OK;
776 }
777 738
778 int HttpNetworkTransaction::DoWriteBody() {
779 next_state_ = STATE_WRITE_BODY_COMPLETE;
780
781 DCHECK(request_body_stream_.get());
782 DCHECK(request_body_stream_->size());
783
784 int buf_len = static_cast<int>(request_body_stream_->buf_len());
785
786 return http_stream_->Write(request_body_stream_->buf(), buf_len,
787 &io_callback_);
788 }
789
790 int HttpNetworkTransaction::DoWriteBodyComplete(int result) {
791 if (result < 0)
792 return HandleIOError(result);
793
794 request_body_stream_->DidConsume(result);
795
796 if (request_body_stream_->position() < request_body_stream_->size()) {
797 next_state_ = STATE_WRITE_BODY;
798 } else {
799 next_state_ = STATE_READ_HEADERS;
800 }
801 return OK; 739 return OK;
802 } 740 }
803 741
804 int HttpNetworkTransaction::DoReadHeaders() { 742 int HttpNetworkTransaction::DoReadHeaders() {
805 next_state_ = STATE_READ_HEADERS_COMPLETE; 743 next_state_ = STATE_READ_HEADERS_COMPLETE;
806 744
807 // Grow the read buffer if necessary. 745 return http_stream_->ReadResponseHeaders(&io_callback_);
808 if (header_buf_len_ == header_buf_capacity_) {
809 header_buf_capacity_ += kHeaderBufInitialSize;
810 header_buf_->Realloc(header_buf_capacity_);
811 }
812
813 int buf_len = header_buf_capacity_ - header_buf_len_;
814 header_buf_->set_data(header_buf_len_);
815
816 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
817 // See if the user is passing in an IOBuffer with a NULL |data_|.
818 CHECK(header_buf_->data());
819
820 return http_stream_->Read(header_buf_, buf_len, &io_callback_);
821 } 746 }
822 747
823 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { 748 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() {
824 if (establishing_tunnel_) { 749 if (establishing_tunnel_) {
825 // The connection was closed before the tunnel could be established. 750 // The connection was closed before the tunnel could be established.
826 return ERR_TUNNEL_CONNECTION_FAILED; 751 return ERR_TUNNEL_CONNECTION_FAILED;
827 } 752 }
828 753
829 if (has_found_status_line_start()) { 754 if (!http_stream_->GetResponseInfo()->headers) {
830 // Assume EOF is end-of-headers.
831 header_buf_body_offset_ = header_buf_len_;
832 return OK;
833 }
834
835 // No status line was matched yet. Could have been a HTTP/0.9 response, or
836 // a partial HTTP/1.x response.
837
838 if (header_buf_len_ == 0) {
839 // The connection was closed before any data was sent. Likely an error 755 // The connection was closed before any data was sent. Likely an error
840 // rather than empty HTTP/0.9 response. 756 // rather than empty HTTP/0.9 response.
841 return ERR_EMPTY_RESPONSE; 757 return ERR_EMPTY_RESPONSE;
842 } 758 }
843 759
844 // Assume everything else is a HTTP/0.9 response (including responses
845 // of 'h', 'ht', 'htt').
846 header_buf_body_offset_ = 0;
847 return OK; 760 return OK;
848 } 761 }
849 762
850 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { 763 int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
851 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here 764 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here
852 // due to SSL renegotiation. 765 // due to SSL renegotiation.
853 if (using_ssl_) { 766 if (using_ssl_) {
854 if (IsCertificateError(result)) { 767 if (IsCertificateError(result)) {
855 // We don't handle a certificate error during SSL renegotiation, so we 768 // We don't handle a certificate error during SSL renegotiation, so we
856 // have to return an error that's not in the certificate error range 769 // have to return an error that's not in the certificate error range
857 // (-2xx). 770 // (-2xx).
858 LOG(ERROR) << "Got a server certificate with error " << result 771 LOG(ERROR) << "Got a server certificate with error " << result
859 << " during SSL renegotiation"; 772 << " during SSL renegotiation";
860 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; 773 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION;
861 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 774 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
862 result = HandleCertificateRequest(result); 775 result = HandleCertificateRequest(result);
863 if (result == OK) 776 if (result == OK)
864 return result; 777 return result;
865 } 778 }
866 } 779 }
867 780
868 if (result < 0) 781 if (result < 0 && result != ERR_CONNECTION_CLOSED)
869 return HandleIOError(result); 782 return HandleIOError(result);
870 783
871 if (result == 0 && ShouldResendRequest(result)) { 784 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) {
872 ResetConnectionAndRequestForResend(); 785 ResetConnectionAndRequestForResend();
873 return result; 786 return OK;
874 } 787 }
875 788
876 // Record our best estimate of the 'response time' as the time when we read 789 // After we call RestartWithAuth a new response_time will be recorded, and
877 // the first bytes of the response headers. 790 // we need to be cautious about incorrectly logging the duration across the
878 if (header_buf_len_ == 0) { 791 // authentication activity.
879 // After we call RestartWithAuth header_buf_len will be zero again, and 792 HttpResponseInfo* response = http_stream_->GetResponseInfo();
880 // we need to be cautious about incorrectly logging the duration across the 793 if (!logged_response_time) {
881 // authentication activitiy. 794 LogTransactionConnectedMetrics();
882 bool first_response = response_.response_time == Time(); 795 logged_response_time = true;
883 response_.response_time = Time::Now();
884 if (first_response)
885 LogTransactionConnectedMetrics();
886 } 796 }
887 797
888 // The socket was closed before we found end-of-headers. 798 if (result == ERR_CONNECTION_CLOSED) {
889 if (result == 0) {
890 int rv = HandleConnectionClosedBeforeEndOfHeaders(); 799 int rv = HandleConnectionClosedBeforeEndOfHeaders();
891 if (rv != OK) 800 if (rv != OK)
892 return rv; 801 return rv;
893 } else { 802 // TODO(wtc): Traditionally this code has returned 0 when reading a closed
894 header_buf_len_ += result; 803 // socket. That is partially corrected in classes that we call, but
895 DCHECK(header_buf_len_ <= header_buf_capacity_); 804 // callers need to be updated.
805 result = 0;
806 }
896 807
897 // Look for the start of the status line, if it hasn't been found yet. 808 if (response->headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
898 if (!has_found_status_line_start()) { 809 // Require the "HTTP/1.x" status line for SSL CONNECT.
899 header_buf_http_offset_ = HttpUtil::LocateStartOfStatusLine( 810 if (establishing_tunnel_)
900 header_buf_->headers(), header_buf_len_); 811 return ERR_TUNNEL_CONNECTION_FAILED;
901 }
902 812
903 if (has_found_status_line_start()) { 813 // HTTP/0.9 doesn't support the PUT method, so lack of response headers
904 int eoh = HttpUtil::LocateEndOfHeaders( 814 // indicates a buggy server. See:
905 header_buf_->headers(), header_buf_len_, header_buf_http_offset_); 815 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921
906 if (eoh == -1) { 816 if (request_->method == "PUT")
907 // Prevent growing the headers buffer indefinitely. 817 return ERR_METHOD_NOT_SUPPORTED;
908 if (header_buf_len_ >= kMaxHeaderBufSize) 818 }
909 return ERR_RESPONSE_HEADERS_TOO_BIG;
910 819
911 // Haven't found the end of headers yet, keep reading. 820 if (establishing_tunnel_) {
912 next_state_ = STATE_READ_HEADERS; 821 switch (response->headers->response_code()) {
822 case 200: // OK
823 if (http_stream_->IsMoreDataBuffered()) {
824 // The proxy sent extraneous data after the headers.
825 return ERR_TUNNEL_CONNECTION_FAILED;
826 }
827 next_state_ = STATE_SSL_CONNECT;
828 // Reset for the real request and response headers.
829 request_headers_.clear();
830 http_stream_.reset(new HttpBasicStream(&connection_));
831 headers_valid_ = false;
832 establishing_tunnel_ = false;
913 return OK; 833 return OK;
914 } 834
915 header_buf_body_offset_ = eoh; 835 // We aren't able to CONNECT to the remote host through the proxy. We
916 } else if (header_buf_len_ < 8) { 836 // need to be very suspicious about the response because an active network
917 // Not enough data to decide whether this is HTTP/0.9 yet. 837 // attacker can force us into this state by masquerading as the proxy.
918 // 8 bytes = (4 bytes of junk) + "http".length() 838 // The only safe thing to do here is to fail the connection because our
919 next_state_ = STATE_READ_HEADERS; 839 // client is expecting an SSL protected response.
920 return OK; 840 // See http://crbug.com/7338.
921 } else { 841 case 407: // Proxy Authentication Required
922 // Enough data was read -- there is no status line. 842 // We need this status code to allow proxy authentication. Our
923 header_buf_body_offset_ = 0; 843 // authentication code is smart enough to avoid being tricked by an
844 // active network attacker.
845 break;
846 default:
847 // For all other status codes, we conservatively fail the CONNECT
848 // request.
849 // We lose something by doing this. We have seen proxy 403, 404, and
850 // 501 response bodies that contain a useful error message. For
851 // example, Squid uses a 404 response to report the DNS error: "The
852 // domain name does not exist."
853 LogBlockedTunnelResponse(response->headers->response_code());
854 return ERR_TUNNEL_CONNECTION_FAILED;
924 } 855 }
925 } 856 }
926 857
927 // And, we are done with the Start or the SSL tunnel CONNECT sequence. 858 // Check for an intermediate 100 Continue response. An origin server is
928 return DidReadResponseHeaders(); 859 // allowed to send this response even if we didn't ask for it, so we just
860 // need to skip over it.
861 // We treat any other 1xx in this same way (although in practice getting
862 // a 1xx that isn't a 100 is rare).
863 if (response->headers->response_code() / 100 == 1) {
864 next_state_ = STATE_READ_HEADERS;
865 return OK;
866 }
867
868 int rv = HandleAuthChallenge();
869 if (rv != OK)
870 return rv;
871
872 if (using_ssl_ && !establishing_tunnel_) {
873 SSLClientSocket* ssl_socket =
874 reinterpret_cast<SSLClientSocket*>(connection_.socket());
875 ssl_socket->GetSSLInfo(&response->ssl_info);
876 }
877
878 headers_valid_ = true;
879 return OK;
929 } 880 }
930 881
931 int HttpNetworkTransaction::DoReadBody() { 882 int HttpNetworkTransaction::DoReadBody() {
932 DCHECK(read_buf_); 883 DCHECK(read_buf_);
933 DCHECK_GT(read_buf_len_, 0); 884 DCHECK_GT(read_buf_len_, 0);
934 DCHECK(connection_.is_initialized()); 885 DCHECK(connection_.is_initialized());
935 DCHECK(!header_buf_->headers() || header_buf_body_offset_ >= 0);
936 886
937 next_state_ = STATE_READ_BODY_COMPLETE; 887 next_state_ = STATE_READ_BODY_COMPLETE;
938 888 return http_stream_->ReadResponseBody(read_buf_, read_buf_len_,
939 // We may have already consumed the indicated content length. 889 &io_callback_);
940 if (response_body_length_ != -1 &&
941 response_body_read_ >= response_body_length_)
942 return 0;
943
944 // We may have some data remaining in the header buffer.
945 if (header_buf_->headers() && header_buf_body_offset_ < header_buf_len_) {
946 int n = std::min(read_buf_len_, header_buf_len_ - header_buf_body_offset_);
947 memcpy(read_buf_->data(), header_buf_->headers() + header_buf_body_offset_,
948 n);
949 header_buf_body_offset_ += n;
950 if (header_buf_body_offset_ == header_buf_len_) {
951 header_buf_->Reset();
952 header_buf_capacity_ = 0;
953 header_buf_len_ = 0;
954 header_buf_body_offset_ = -1;
955 }
956 return n;
957 }
958
959 reading_body_from_socket_ = true;
960 return http_stream_->Read(read_buf_, read_buf_len_, &io_callback_);
961 } 890 }
962 891
963 int HttpNetworkTransaction::DoReadBodyComplete(int result) { 892 int HttpNetworkTransaction::DoReadBodyComplete(int result) {
964 // We are done with the Read call. 893 // We are done with the Read call.
965 DCHECK(!establishing_tunnel_) << 894 DCHECK(!establishing_tunnel_) <<
966 "We should never read a response body of a tunnel."; 895 "We should never read a response body of a tunnel.";
967 896
968 bool unfiltered_eof = (result == 0 && reading_body_from_socket_);
969 reading_body_from_socket_ = false;
970
971 // Filter incoming data if appropriate. FilterBuf may return an error.
972 if (result > 0 && chunked_decoder_.get()) {
973 result = chunked_decoder_->FilterBuf(read_buf_->data(), result);
974 if (result == 0 && !chunked_decoder_->reached_eof()) {
975 // Don't signal completion of the Read call yet or else it'll look like
976 // we received end-of-file. Wait for more data.
977 next_state_ = STATE_READ_BODY;
978 return OK;
979 }
980 }
981
982 bool done = false, keep_alive = false; 897 bool done = false, keep_alive = false;
983 if (result < 0) { 898 if (result < 0) {
984 // Error while reading the socket. 899 // Error or closed connection while reading the socket.
985 done = true; 900 done = true;
986 } else { 901 // TODO(wtc): Traditionally this code has returned 0 when reading a closed
987 response_body_read_ += result; 902 // socket. That is partially corrected in classes that we call, but
988 if (unfiltered_eof || 903 // callers need to be updated.
989 (response_body_length_ != -1 && 904 if (result == ERR_CONNECTION_CLOSED)
990 response_body_read_ >= response_body_length_) || 905 result = 0;
991 (chunked_decoder_.get() && chunked_decoder_->reached_eof())) { 906 } else if (http_stream_->IsResponseBodyComplete()) {
992 done = true; 907 done = true;
993 keep_alive = response_.headers->IsKeepAlive(); 908 keep_alive = GetResponseHeaders()->IsKeepAlive();
994 // We can't reuse the connection if we read more than the advertised
995 // content length.
996 if (unfiltered_eof ||
997 (response_body_length_ != -1 &&
998 response_body_read_ > response_body_length_))
999 keep_alive = false;
1000 }
1001 } 909 }
1002 910
1003 // Clean up connection_ if we are done. 911 // Clean up connection_ if we are done.
1004 if (done) { 912 if (done) {
1005 LogTransactionMetrics(); 913 LogTransactionMetrics();
1006 if (!keep_alive) 914 if (!keep_alive)
1007 connection_.socket()->Disconnect(); 915 connection_.socket()->Disconnect();
1008 connection_.Reset(); 916 connection_.Reset();
1009 // The next Read call will return 0 (EOF). 917 // The next Read call will return 0 (EOF).
1010 } 918 }
1011 919
1012 // Clear these to avoid leaving around old state. 920 // Clear these to avoid leaving around old state.
1013 read_buf_ = NULL; 921 read_buf_ = NULL;
1014 read_buf_len_ = 0; 922 read_buf_len_ = 0;
1015 923
1016 return result; 924 return result;
1017 } 925 }
1018 926
1019 int HttpNetworkTransaction::DoDrainBodyForAuthRestart() { 927 int HttpNetworkTransaction::DoDrainBodyForAuthRestart() {
1020 // This method differs from DoReadBody only in the next_state_. So we just 928 // This method differs from DoReadBody only in the next_state_. So we just
1021 // call DoReadBody and override the next_state_. Perhaps there is a more 929 // call DoReadBody and override the next_state_. Perhaps there is a more
1022 // elegant way for these two methods to share code. 930 // elegant way for these two methods to share code.
1023 int rv = DoReadBody(); 931 int rv = DoReadBody();
1024 DCHECK(next_state_ == STATE_READ_BODY_COMPLETE); 932 DCHECK(next_state_ == STATE_READ_BODY_COMPLETE);
1025 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE; 933 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE;
1026 return rv; 934 return rv;
1027 } 935 }
1028 936
1029 // TODO(wtc): The first two thirds of this method and the DoReadBodyComplete 937 // TODO(wtc): This method and the DoReadBodyComplete method are almost
1030 // method are almost the same. Figure out a good way for these two methods 938 // the same. Figure out a good way for these two methods to share code.
1031 // to share code.
1032 int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) { 939 int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) {
1033 bool unfiltered_eof = (result == 0 && reading_body_from_socket_);
1034 reading_body_from_socket_ = false;
1035
1036 // Filter incoming data if appropriate. FilterBuf may return an error.
1037 if (result > 0 && chunked_decoder_.get()) {
1038 result = chunked_decoder_->FilterBuf(read_buf_->data(), result);
1039 if (result == 0 && !chunked_decoder_->reached_eof()) {
1040 // Don't signal completion of the Read call yet or else it'll look like
1041 // we received end-of-file. Wait for more data.
1042 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
1043 return OK;
1044 }
1045 }
1046
1047 // keep_alive defaults to true because the very reason we're draining the 940 // keep_alive defaults to true because the very reason we're draining the
1048 // response body is to reuse the connection for auth restart. 941 // response body is to reuse the connection for auth restart.
1049 bool done = false, keep_alive = true; 942 bool done = false, keep_alive = true;
1050 if (result < 0) { 943 if (result < 0) {
1051 // Error while reading the socket. 944 // Error or closed connection while reading the socket.
1052 done = true; 945 done = true;
1053 keep_alive = false; 946 keep_alive = false;
1054 } else { 947 } else if (http_stream_->IsResponseBodyComplete()) {
1055 response_body_read_ += result; 948 done = true;
1056 if (unfiltered_eof ||
1057 (response_body_length_ != -1 &&
1058 response_body_read_ >= response_body_length_) ||
1059 (chunked_decoder_.get() && chunked_decoder_->reached_eof())) {
1060 done = true;
1061 // We can't reuse the connection if we read more than the advertised
1062 // content length.
1063 if (unfiltered_eof ||
1064 (response_body_length_ != -1 &&
1065 response_body_read_ > response_body_length_))
1066 keep_alive = false;
1067 }
1068 } 949 }
1069 950
1070 if (done) { 951 if (done) {
1071 DidDrainBodyForAuthRestart(keep_alive); 952 DidDrainBodyForAuthRestart(keep_alive);
1072 } else { 953 } else {
1073 // Keep draining. 954 // Keep draining.
1074 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; 955 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
1075 } 956 }
1076 957
1077 return OK; 958 return OK;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 base::TimeDelta::FromMinutes(6), 100); 1087 base::TimeDelta::FromMinutes(6), 100);
1207 } 1088 }
1208 break; 1089 break;
1209 default: 1090 default:
1210 NOTREACHED(); 1091 NOTREACHED();
1211 break; 1092 break;
1212 } 1093 }
1213 } 1094 }
1214 1095
1215 void HttpNetworkTransaction::LogTransactionConnectedMetrics() const { 1096 void HttpNetworkTransaction::LogTransactionConnectedMetrics() const {
1216 base::TimeDelta total_duration = response_.response_time - start_time_; 1097 base::TimeDelta total_duration =
1098 http_stream_->GetResponseInfo()->response_time - start_time_;
1217 1099
1218 UMA_HISTOGRAM_CLIPPED_TIMES( 1100 UMA_HISTOGRAM_CLIPPED_TIMES(
1219 "Net.Transaction_Connected_Under_10", 1101 "Net.Transaction_Connected_Under_10",
1220 total_duration, 1102 total_duration,
1221 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1103 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1222 100); 1104 100);
1223 1105
1224 static const bool use_late_binding_histogram = 1106 static const bool use_late_binding_histogram =
1225 !FieldTrial::MakeName("", "SocketLateBinding").empty(); 1107 !FieldTrial::MakeName("", "SocketLateBinding").empty();
1226 1108
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 } else { 1147 } else {
1266 UMA_HISTOGRAM_CLIPPED_TIMES( 1148 UMA_HISTOGRAM_CLIPPED_TIMES(
1267 "Net.Priority_Low_Latency", 1149 "Net.Priority_Low_Latency",
1268 total_duration, 1150 total_duration,
1269 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1151 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1270 100); 1152 100);
1271 } 1153 }
1272 } 1154 }
1273 1155
1274 void HttpNetworkTransaction::LogTransactionMetrics() const { 1156 void HttpNetworkTransaction::LogTransactionMetrics() const {
1275 base::TimeDelta duration = base::Time::Now() - response_.request_time; 1157 base::TimeDelta duration = base::Time::Now() -
1158 http_stream_->GetResponseInfo()->request_time;
1276 if (60 < duration.InMinutes()) 1159 if (60 < duration.InMinutes())
1277 return; 1160 return;
1278 1161
1279 base::TimeDelta total_duration = base::Time::Now() - start_time_; 1162 base::TimeDelta total_duration = base::Time::Now() - start_time_;
1280 1163
1281 UMA_HISTOGRAM_LONG_TIMES("Net.Transaction_Latency", duration); 1164 UMA_HISTOGRAM_LONG_TIMES("Net.Transaction_Latency", duration);
1282 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Under_10", duration, 1165 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Under_10", duration,
1283 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1166 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
1284 100); 1167 100);
1285 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Total_Under_10", 1168 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Total_Under_10",
1286 total_duration, base::TimeDelta::FromMilliseconds(1), 1169 total_duration, base::TimeDelta::FromMilliseconds(1),
1287 base::TimeDelta::FromMinutes(10), 100); 1170 base::TimeDelta::FromMinutes(10), 100);
1288 if (!reused_socket_) { 1171 if (!reused_socket_) {
1289 UMA_HISTOGRAM_CLIPPED_TIMES( 1172 UMA_HISTOGRAM_CLIPPED_TIMES(
1290 "Net.Transaction_Latency_Total_New_Connection_Under_10", 1173 "Net.Transaction_Latency_Total_New_Connection_Under_10",
1291 total_duration, base::TimeDelta::FromMilliseconds(1), 1174 total_duration, base::TimeDelta::FromMilliseconds(1),
1292 base::TimeDelta::FromMinutes(10), 100); 1175 base::TimeDelta::FromMinutes(10), 100);
1293 } 1176 }
1294 } 1177 }
1295 1178
1296 void HttpNetworkTransaction::LogBlockedTunnelResponse( 1179 void HttpNetworkTransaction::LogBlockedTunnelResponse(
1297 int response_code) const { 1180 int response_code) const {
1298 LOG(WARNING) << "Blocked proxy response with status " << response_code 1181 LOG(WARNING) << "Blocked proxy response with status " << response_code
1299 << " to CONNECT request for " 1182 << " to CONNECT request for "
1300 << GetHostAndPort(request_->url) << "."; 1183 << GetHostAndPort(request_->url) << ".";
1301 } 1184 }
1302 1185
1303 int HttpNetworkTransaction::DidReadResponseHeaders() {
1304 DCHECK_GE(header_buf_body_offset_, 0);
1305
1306 scoped_refptr<HttpResponseHeaders> headers;
1307 if (has_found_status_line_start()) {
1308 headers = new HttpResponseHeaders(
1309 HttpUtil::AssembleRawHeaders(
1310 header_buf_->headers(), header_buf_body_offset_));
1311 } else {
1312 // Fabricate a status line to to preserve the HTTP/0.9 version.
1313 // (otherwise HttpResponseHeaders will default it to HTTP/1.0).
1314 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
1315 }
1316
1317 if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
1318 // Require the "HTTP/1.x" status line for SSL CONNECT.
1319 if (establishing_tunnel_)
1320 return ERR_TUNNEL_CONNECTION_FAILED;
1321
1322 // HTTP/0.9 doesn't support the PUT method, so lack of response headers
1323 // indicates a buggy server. See:
1324 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921
1325 if (request_->method == "PUT")
1326 return ERR_METHOD_NOT_SUPPORTED;
1327 }
1328
1329 if (establishing_tunnel_) {
1330 switch (headers->response_code()) {
1331 case 200: // OK
1332 if (header_buf_body_offset_ != header_buf_len_) {
1333 // The proxy sent extraneous data after the headers.
1334 return ERR_TUNNEL_CONNECTION_FAILED;
1335 }
1336 next_state_ = STATE_SSL_CONNECT;
1337 // Reset for the real request and response headers.
1338 request_headers_->headers_.clear();
1339 request_headers_bytes_sent_ = 0;
1340 header_buf_len_ = 0;
1341 header_buf_body_offset_ = -1;
1342 establishing_tunnel_ = false;
1343 return OK;
1344
1345 // We aren't able to CONNECT to the remote host through the proxy. We
1346 // need to be very suspicious about the response because an active network
1347 // attacker can force us into this state by masquerading as the proxy.
1348 // The only safe thing to do here is to fail the connection because our
1349 // client is expecting an SSL protected response.
1350 // See http://crbug.com/7338.
1351 case 407: // Proxy Authentication Required
1352 // We need this status code to allow proxy authentication. Our
1353 // authentication code is smart enough to avoid being tricked by an
1354 // active network attacker.
1355 break;
1356 default:
1357 // For all other status codes, we conservatively fail the CONNECT
1358 // request.
1359 // We lose something by doing this. We have seen proxy 403, 404, and
1360 // 501 response bodies that contain a useful error message. For
1361 // example, Squid uses a 404 response to report the DNS error: "The
1362 // domain name does not exist."
1363 LogBlockedTunnelResponse(headers->response_code());
1364 return ERR_TUNNEL_CONNECTION_FAILED;
1365 }
1366 }
1367
1368 // Check for an intermediate 100 Continue response. An origin server is
1369 // allowed to send this response even if we didn't ask for it, so we just
1370 // need to skip over it.
1371 // We treat any other 1xx in this same way (although in practice getting
1372 // a 1xx that isn't a 100 is rare).
1373 if (headers->response_code() / 100 == 1) {
1374 header_buf_len_ -= header_buf_body_offset_;
1375 // If we've already received some bytes after the 1xx response,
1376 // move them to the beginning of header_buf_.
1377 if (header_buf_len_) {
1378 memmove(header_buf_->headers(),
1379 header_buf_->headers() + header_buf_body_offset_,
1380 header_buf_len_);
1381 }
1382 header_buf_body_offset_ = -1;
1383 next_state_ = STATE_READ_HEADERS;
1384 return OK;
1385 }
1386
1387 response_.headers = headers;
1388 response_.vary_data.Init(*request_, *response_.headers);
1389
1390 // Figure how to determine EOF:
1391
1392 // For certain responses, we know the content length is always 0. From
1393 // RFC 2616 Section 4.3 Message Body:
1394 //
1395 // For response messages, whether or not a message-body is included with
1396 // a message is dependent on both the request method and the response
1397 // status code (section 6.1.1). All responses to the HEAD request method
1398 // MUST NOT include a message-body, even though the presence of entity-
1399 // header fields might lead one to believe they do. All 1xx
1400 // (informational), 204 (no content), and 304 (not modified) responses
1401 // MUST NOT include a message-body. All other responses do include a
1402 // message-body, although it MAY be of zero length.
1403 switch (response_.headers->response_code()) {
1404 // Note that 1xx was already handled earlier.
1405 case 204: // No Content
1406 case 205: // Reset Content
1407 case 304: // Not Modified
1408 response_body_length_ = 0;
1409 break;
1410 }
1411 if (request_->method == "HEAD")
1412 response_body_length_ = 0;
1413
1414 if (response_body_length_ == -1) {
1415 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies.
1416 // Otherwise "Transfer-Encoding: chunked" trumps "Content-Length: N"
1417 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1) &&
1418 response_.headers->HasHeaderValue("Transfer-Encoding", "chunked")) {
1419 chunked_decoder_.reset(new HttpChunkedDecoder());
1420 } else {
1421 response_body_length_ = response_.headers->GetContentLength();
1422 // If response_body_length_ is still -1, then we have to wait for the
1423 // server to close the connection.
1424 }
1425 }
1426
1427 int rv = HandleAuthChallenge();
1428 if (rv != OK)
1429 return rv;
1430
1431 if (using_ssl_ && !establishing_tunnel_) {
1432 SSLClientSocket* ssl_socket =
1433 reinterpret_cast<SSLClientSocket*>(connection_.socket());
1434 ssl_socket->GetSSLInfo(&response_.ssl_info);
1435 }
1436
1437 return OK;
1438 }
1439
1440 int HttpNetworkTransaction::HandleCertificateError(int error) { 1186 int HttpNetworkTransaction::HandleCertificateError(int error) {
1441 DCHECK(using_ssl_); 1187 DCHECK(using_ssl_);
1442 1188
1443 const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID | 1189 const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID |
1444 LOAD_IGNORE_CERT_DATE_INVALID | 1190 LOAD_IGNORE_CERT_DATE_INVALID |
1445 LOAD_IGNORE_CERT_AUTHORITY_INVALID | 1191 LOAD_IGNORE_CERT_AUTHORITY_INVALID |
1446 LOAD_IGNORE_CERT_WRONG_USAGE; 1192 LOAD_IGNORE_CERT_WRONG_USAGE;
1447 if (request_->load_flags & kCertFlags) { 1193 if (request_->load_flags & kCertFlags) {
1448 switch (error) { 1194 switch (error) {
1449 case ERR_CERT_COMMON_NAME_INVALID: 1195 case ERR_CERT_COMMON_NAME_INVALID:
1450 if (request_->load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID) 1196 if (request_->load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID)
1451 error = OK; 1197 error = OK;
1452 break; 1198 break;
1453 case ERR_CERT_DATE_INVALID: 1199 case ERR_CERT_DATE_INVALID:
1454 if (request_->load_flags & LOAD_IGNORE_CERT_DATE_INVALID) 1200 if (request_->load_flags & LOAD_IGNORE_CERT_DATE_INVALID)
1455 error = OK; 1201 error = OK;
1456 break; 1202 break;
1457 case ERR_CERT_AUTHORITY_INVALID: 1203 case ERR_CERT_AUTHORITY_INVALID:
1458 if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID) 1204 if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID)
1459 error = OK; 1205 error = OK;
1460 break; 1206 break;
1461 } 1207 }
1462 } 1208 }
1463 1209
1464 if (error != OK) { 1210 if (error != OK) {
1211 HttpResponseInfo* response = http_stream_->GetResponseInfo();
1465 SSLClientSocket* ssl_socket = 1212 SSLClientSocket* ssl_socket =
1466 reinterpret_cast<SSLClientSocket*>(connection_.socket()); 1213 reinterpret_cast<SSLClientSocket*>(connection_.socket());
1467 ssl_socket->GetSSLInfo(&response_.ssl_info); 1214 ssl_socket->GetSSLInfo(&response->ssl_info);
1468 1215
1469 // Add the bad certificate to the set of allowed certificates in the 1216 // Add the bad certificate to the set of allowed certificates in the
1470 // SSL info object. This data structure will be consulted after calling 1217 // SSL info object. This data structure will be consulted after calling
1471 // RestartIgnoringLastError(). And the user will be asked interactively 1218 // RestartIgnoringLastError(). And the user will be asked interactively
1472 // before RestartIgnoringLastError() is ever called. 1219 // before RestartIgnoringLastError() is ever called.
1473 SSLConfig::CertAndStatus bad_cert; 1220 SSLConfig::CertAndStatus bad_cert;
1474 bad_cert.cert = response_.ssl_info.cert; 1221 bad_cert.cert = response->ssl_info.cert;
1475 bad_cert.cert_status = response_.ssl_info.cert_status; 1222 bad_cert.cert_status = response->ssl_info.cert_status;
1476 ssl_config_.allowed_bad_certs.push_back(bad_cert); 1223 ssl_config_.allowed_bad_certs.push_back(bad_cert);
1477 } 1224 }
1478 return error; 1225 return error;
1479 } 1226 }
1480 1227
1481 int HttpNetworkTransaction::HandleCertificateRequest(int error) { 1228 int HttpNetworkTransaction::HandleCertificateRequest(int error) {
1482 // Assert that the socket did not send a client certificate. 1229 // Assert that the socket did not send a client certificate.
1483 // Note: If we got a reused socket, it was created with some other 1230 // Note: If we got a reused socket, it was created with some other
1484 // transaction's ssl_config_, so we need to disable this assertion. We can 1231 // transaction's ssl_config_, so we need to disable this assertion. We can
1485 // get a certificate request on a reused socket when the server requested 1232 // get a certificate request on a reused socket when the server requested
1486 // renegotiation (rehandshake). 1233 // renegotiation (rehandshake).
1487 // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query 1234 // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query
1488 // the SSL parameters it was created with and get rid of the reused_socket_ 1235 // the SSL parameters it was created with and get rid of the reused_socket_
1489 // test. 1236 // test.
1490 DCHECK(reused_socket_ || !ssl_config_.send_client_cert); 1237 DCHECK(reused_socket_ || !ssl_config_.send_client_cert);
1491 1238
1492 response_.cert_request_info = new SSLCertRequestInfo; 1239 HttpResponseInfo* response = http_stream_->GetResponseInfo();
1240 response->cert_request_info = new SSLCertRequestInfo;
1493 SSLClientSocket* ssl_socket = 1241 SSLClientSocket* ssl_socket =
1494 reinterpret_cast<SSLClientSocket*>(connection_.socket()); 1242 reinterpret_cast<SSLClientSocket*>(connection_.socket());
1495 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); 1243 ssl_socket->GetSSLCertRequestInfo(response->cert_request_info);
1496 1244
1497 // Close the connection while the user is selecting a certificate to send 1245 // Close the connection while the user is selecting a certificate to send
1498 // to the server. 1246 // to the server.
1499 connection_.socket()->Disconnect(); 1247 connection_.socket()->Disconnect();
1500 connection_.Reset(); 1248 connection_.Reset();
1501 1249
1502 // If the user selected one of the certificate in client_certs for this 1250 // If the user selected one of the certificate in client_certs for this
1503 // server before, use it automatically. 1251 // server before, use it automatically.
1504 X509Certificate* client_cert = session_->ssl_client_auth_cache()-> 1252 X509Certificate* client_cert = session_->ssl_client_auth_cache()->
1505 Lookup(GetHostAndPort(request_->url)); 1253 Lookup(GetHostAndPort(request_->url));
1506 if (client_cert) { 1254 if (client_cert) {
1507 const std::vector<scoped_refptr<X509Certificate> >& client_certs = 1255 const std::vector<scoped_refptr<X509Certificate> >& client_certs =
1508 response_.cert_request_info->client_certs; 1256 response->cert_request_info->client_certs;
1509 for (size_t i = 0; i < client_certs.size(); ++i) { 1257 for (size_t i = 0; i < client_certs.size(); ++i) {
1510 if (client_cert->fingerprint().Equals(client_certs[i]->fingerprint())) { 1258 if (client_cert->fingerprint().Equals(client_certs[i]->fingerprint())) {
1511 ssl_config_.client_cert = client_cert; 1259 ssl_config_.client_cert = client_cert;
1512 ssl_config_.send_client_cert = true; 1260 ssl_config_.send_client_cert = true;
1513 next_state_ = STATE_INIT_CONNECTION; 1261 next_state_ = STATE_INIT_CONNECTION;
1514 // Reset the other member variables. 1262 // Reset the other member variables.
1515 // Note: this is necessary only with SSL renegotiation. 1263 // Note: this is necessary only with SSL renegotiation.
1516 ResetStateForRestart(); 1264 ResetStateForRestart();
1517 return OK; 1265 return OK;
1518 } 1266 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 ResetConnectionAndRequestForResend(); 1311 ResetConnectionAndRequestForResend();
1564 error = OK; 1312 error = OK;
1565 } 1313 }
1566 break; 1314 break;
1567 } 1315 }
1568 return error; 1316 return error;
1569 } 1317 }
1570 1318
1571 void HttpNetworkTransaction::ResetStateForRestart() { 1319 void HttpNetworkTransaction::ResetStateForRestart() {
1572 pending_auth_target_ = HttpAuth::AUTH_NONE; 1320 pending_auth_target_ = HttpAuth::AUTH_NONE;
1573 header_buf_->Reset();
1574 header_buf_capacity_ = 0;
1575 header_buf_len_ = 0;
1576 header_buf_body_offset_ = -1;
1577 header_buf_http_offset_ = -1;
1578 response_body_length_ = -1;
1579 response_body_read_ = 0;
1580 read_buf_ = NULL; 1321 read_buf_ = NULL;
1581 read_buf_len_ = 0; 1322 read_buf_len_ = 0;
1582 request_headers_->headers_.clear(); 1323 http_stream_.reset(new HttpBasicStream(&connection_));
1583 request_headers_bytes_sent_ = 0; 1324 headers_valid_ = false;
1584 chunked_decoder_.reset(); 1325 request_headers_.clear();
1585 // Reset all the members of response_. 1326 }
1586 response_ = HttpResponseInfo(); 1327
1328 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const {
1329 CHECK(http_stream_.get());
1330 return http_stream_->GetResponseInfo()->headers;
1587 } 1331 }
1588 1332
1589 bool HttpNetworkTransaction::ShouldResendRequest(int error) const { 1333 bool HttpNetworkTransaction::ShouldResendRequest(int error) const {
1590 // NOTE: we resend a request only if we reused a keep-alive connection. 1334 // NOTE: we resend a request only if we reused a keep-alive connection.
1591 // This automatically prevents an infinite resend loop because we'll run 1335 // This automatically prevents an infinite resend loop because we'll run
1592 // out of the cached keep-alive connections eventually. 1336 // out of the cached keep-alive connections eventually.
1593 if (establishing_tunnel_ || 1337 if (establishing_tunnel_ ||
1594 // We used a socket that was never idle. 1338 !connection_.ShouldResendFailedRequest(error) ||
1595 connection_.reuse_type() == ClientSocketHandle::UNUSED || 1339 GetResponseHeaders()) { // We have received some response headers.
1596 // We used an unused, idle socket and got a error that wasn't a TCP RST.
1597 (connection_.reuse_type() == ClientSocketHandle::UNUSED_IDLE &&
1598 (error != OK && error != ERR_CONNECTION_RESET)) ||
1599 header_buf_len_) { // We have received some response headers.
1600 return false; 1340 return false;
1601 } 1341 }
1602 return true; 1342 return true;
1603 } 1343 }
1604 1344
1605 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { 1345 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() {
1606 connection_.socket()->Disconnect(); 1346 connection_.socket()->Disconnect();
1607 connection_.Reset(); 1347 connection_.Reset();
1608 // There are two reasons we need to clear request_headers_. 1) It contains 1348 // We need to clear request_headers_ because it contains the real request
1609 // the real request headers, but we may need to resend the CONNECT request 1349 // headers, but we may need to resend the CONNECT request first to recreate
1610 // first to recreate the SSL tunnel. 2) An empty request_headers_ causes 1350 // the SSL tunnel.
1611 // BuildRequestHeaders to be called, which rewinds request_body_stream_ to 1351 request_headers_.clear();
1612 // the beginning of request_->upload_data.
1613 request_headers_->headers_.clear();
1614 request_headers_bytes_sent_ = 0;
1615 next_state_ = STATE_INIT_CONNECTION; // Resend the request. 1352 next_state_ = STATE_INIT_CONNECTION; // Resend the request.
1616 } 1353 }
1617 1354
1618 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { 1355 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) {
1619 DCHECK(!pac_request_); 1356 DCHECK(!pac_request_);
1620 1357
1621 // A failure to resolve the hostname or any error related to establishing a 1358 // A failure to resolve the hostname or any error related to establishing a
1622 // TCP connection could be grounds for trying a new proxy configuration. 1359 // TCP connection could be grounds for trying a new proxy configuration.
1623 // 1360 //
1624 // Why do this when a hostname cannot be resolved? Some URLs only make sense 1361 // Why do this when a hostname cannot be resolved? Some URLs only make sense
(...skipping 21 matching lines...) Expand all
1646 } 1383 }
1647 1384
1648 int rv = session_->proxy_service()->ReconsiderProxyAfterError( 1385 int rv = session_->proxy_service()->ReconsiderProxyAfterError(
1649 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); 1386 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_);
1650 if (rv == OK || rv == ERR_IO_PENDING) { 1387 if (rv == OK || rv == ERR_IO_PENDING) {
1651 // If the error was during connection setup, there is no socket to 1388 // If the error was during connection setup, there is no socket to
1652 // disconnect. 1389 // disconnect.
1653 if (connection_.socket()) 1390 if (connection_.socket())
1654 connection_.socket()->Disconnect(); 1391 connection_.socket()->Disconnect();
1655 connection_.Reset(); 1392 connection_.Reset();
1656 DCHECK(!request_headers_bytes_sent_);
1657 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 1393 next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
1658 } else { 1394 } else {
1659 rv = error; 1395 rv = error;
1660 } 1396 }
1661 1397
1662 return rv; 1398 return rv;
1663 } 1399 }
1664 1400
1665 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { 1401 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const {
1666 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; 1402 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 auth_identity_[target].password = entry->password(); 1542 auth_identity_[target].password = entry->password();
1807 return true; 1543 return true;
1808 } 1544 }
1809 return false; 1545 return false;
1810 } 1546 }
1811 1547
1812 std::string HttpNetworkTransaction::AuthChallengeLogMessage() const { 1548 std::string HttpNetworkTransaction::AuthChallengeLogMessage() const {
1813 std::string msg; 1549 std::string msg;
1814 std::string header_val; 1550 std::string header_val;
1815 void* iter = NULL; 1551 void* iter = NULL;
1816 while (response_.headers->EnumerateHeader(&iter, "proxy-authenticate", 1552 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
1817 &header_val)) { 1553 while (headers->EnumerateHeader(&iter, "proxy-authenticate", &header_val)) {
1818 msg.append("\n Has header Proxy-Authenticate: "); 1554 msg.append("\n Has header Proxy-Authenticate: ");
1819 msg.append(header_val); 1555 msg.append(header_val);
1820 } 1556 }
1821 1557
1822 iter = NULL; 1558 iter = NULL;
1823 while (response_.headers->EnumerateHeader(&iter, "www-authenticate", 1559 while (headers->EnumerateHeader(&iter, "www-authenticate", &header_val)) {
1824 &header_val)) {
1825 msg.append("\n Has header WWW-Authenticate: "); 1560 msg.append("\n Has header WWW-Authenticate: ");
1826 msg.append(header_val); 1561 msg.append(header_val);
1827 } 1562 }
1828 1563
1829 // RFC 4559 requires that a proxy indicate its support of NTLM/Negotiate 1564 // RFC 4559 requires that a proxy indicate its support of NTLM/Negotiate
1830 // authentication with a "Proxy-Support: Session-Based-Authentication" 1565 // authentication with a "Proxy-Support: Session-Based-Authentication"
1831 // response header. 1566 // response header.
1832 iter = NULL; 1567 iter = NULL;
1833 while (response_.headers->EnumerateHeader(&iter, "proxy-support", 1568 while (headers->EnumerateHeader(&iter, "proxy-support", &header_val)) {
1834 &header_val)) {
1835 msg.append("\n Has header Proxy-Support: "); 1569 msg.append("\n Has header Proxy-Support: ");
1836 msg.append(header_val); 1570 msg.append(header_val);
1837 } 1571 }
1838 1572
1839 return msg; 1573 return msg;
1840 } 1574 }
1841 1575
1842 int HttpNetworkTransaction::HandleAuthChallenge() { 1576 int HttpNetworkTransaction::HandleAuthChallenge() {
1843 DCHECK(response_.headers); 1577 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders();
1578 DCHECK(headers);
1844 1579
1845 int status = response_.headers->response_code(); 1580 int status = headers->response_code();
1846 if (status != 401 && status != 407) 1581 if (status != 401 && status != 407)
1847 return OK; 1582 return OK;
1848 HttpAuth::Target target = status == 407 ? 1583 HttpAuth::Target target = status == 407 ?
1849 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; 1584 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER;
1850 GURL auth_origin = AuthOrigin(target); 1585 GURL auth_origin = AuthOrigin(target);
1851 1586
1852 LOG(INFO) << "The " << AuthTargetString(target) << " " 1587 LOG(INFO) << "The " << AuthTargetString(target) << " "
1853 << auth_origin << " requested auth" 1588 << auth_origin << " requested auth"
1854 << AuthChallengeLogMessage(); 1589 << AuthChallengeLogMessage();
1855 1590
(...skipping 11 matching lines...) Expand all
1867 InvalidateRejectedAuthFromCache(target, auth_origin); 1602 InvalidateRejectedAuthFromCache(target, auth_origin);
1868 auth_handler_[target] = NULL; 1603 auth_handler_[target] = NULL;
1869 auth_identity_[target] = HttpAuth::Identity(); 1604 auth_identity_[target] = HttpAuth::Identity();
1870 } 1605 }
1871 1606
1872 auth_identity_[target].invalid = true; 1607 auth_identity_[target].invalid = true;
1873 1608
1874 if (target != HttpAuth::AUTH_SERVER || 1609 if (target != HttpAuth::AUTH_SERVER ||
1875 !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA)) { 1610 !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA)) {
1876 // Find the best authentication challenge that we support. 1611 // Find the best authentication challenge that we support.
1877 HttpAuth::ChooseBestChallenge(response_.headers.get(), 1612 HttpAuth::ChooseBestChallenge(headers, target, auth_origin,
1878 target,
1879 auth_origin,
1880 &auth_handler_[target]); 1613 &auth_handler_[target]);
1881 } 1614 }
1882 1615
1883 if (!auth_handler_[target]) { 1616 if (!auth_handler_[target]) {
1884 if (establishing_tunnel_) { 1617 if (establishing_tunnel_) {
1885 LOG(ERROR) << "Can't perform auth to the " << AuthTargetString(target) 1618 LOG(ERROR) << "Can't perform auth to the " << AuthTargetString(target)
1886 << " " << auth_origin << " when establishing a tunnel" 1619 << " " << auth_origin << " when establishing a tunnel"
1887 << AuthChallengeLogMessage(); 1620 << AuthChallengeLogMessage();
1888 1621
1889 // We are establishing a tunnel, we can't show the error page because an 1622 // We are establishing a tunnel, we can't show the error page because an
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 const GURL& auth_origin) { 1658 const GURL& auth_origin) {
1926 // Populates response_.auth_challenge with the authentication challenge info. 1659 // Populates response_.auth_challenge with the authentication challenge info.
1927 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo(). 1660 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo().
1928 1661
1929 AuthChallengeInfo* auth_info = new AuthChallengeInfo; 1662 AuthChallengeInfo* auth_info = new AuthChallengeInfo;
1930 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; 1663 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY;
1931 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin)); 1664 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin));
1932 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); 1665 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme());
1933 // TODO(eroman): decode realm according to RFC 2047. 1666 // TODO(eroman): decode realm according to RFC 2047.
1934 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); 1667 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm());
1935 response_.auth_challenge = auth_info; 1668 http_stream_->GetResponseInfo()->auth_challenge = auth_info;
1936 } 1669 }
1937 1670
1938 } // namespace net 1671 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698