OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |