| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_proxy_client_socket.h" | 5 #include "net/http/http_proxy_client_socket.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 HttpAuthHandlerFactory* http_auth_handler_factory, | 34 HttpAuthHandlerFactory* http_auth_handler_factory, |
| 35 bool tunnel, | 35 bool tunnel, |
| 36 bool using_spdy, | 36 bool using_spdy, |
| 37 NextProto protocol_negotiated, | 37 NextProto protocol_negotiated, |
| 38 bool is_https_proxy) | 38 bool is_https_proxy) |
| 39 : io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete, | 39 : io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete, |
| 40 base::Unretained(this))), | 40 base::Unretained(this))), |
| 41 next_state_(STATE_NONE), | 41 next_state_(STATE_NONE), |
| 42 transport_(transport_socket), | 42 transport_(transport_socket), |
| 43 endpoint_(endpoint), | 43 endpoint_(endpoint), |
| 44 auth_(tunnel ? | 44 auth_(tunnel ? new HttpAuthController( |
| 45 new HttpAuthController(HttpAuth::AUTH_PROXY, | 45 HttpAuth::AUTH_PROXY, |
| 46 GURL((is_https_proxy ? "https://" : "http://") | 46 GURL((is_https_proxy ? "https://" : "http://") + |
| 47 + proxy_server.ToString()), | 47 proxy_server.ToString()), |
| 48 http_auth_cache, | 48 http_auth_cache, |
| 49 http_auth_handler_factory) | 49 http_auth_handler_factory) |
| 50 : NULL), | 50 : NULL), |
| 51 tunnel_(tunnel), | 51 tunnel_(tunnel), |
| 52 using_spdy_(using_spdy), | 52 using_spdy_(using_spdy), |
| 53 protocol_negotiated_(protocol_negotiated), | 53 protocol_negotiated_(protocol_negotiated), |
| 54 is_https_proxy_(is_https_proxy), | 54 is_https_proxy_(is_https_proxy), |
| 55 redirect_has_load_timing_info_(false), | 55 redirect_has_load_timing_info_(false), |
| 56 net_log_(transport_socket->socket()->NetLog()) { | 56 net_log_(transport_socket->socket()->NetLog()) { |
| 57 // Synthesize the bits of a request that we actually use. | 57 // Synthesize the bits of a request that we actually use. |
| 58 request_.url = request_url; | 58 request_.url = request_url; |
| 59 request_.method = "GET"; | 59 request_.method = "GET"; |
| 60 if (!user_agent.empty()) | 60 if (!user_agent.empty()) |
| 61 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, | 61 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, |
| 62 user_agent); | 62 user_agent); |
| 63 } | 63 } |
| 64 | 64 |
| 65 HttpProxyClientSocket::~HttpProxyClientSocket() { | 65 HttpProxyClientSocket::~HttpProxyClientSocket() { |
| 66 Disconnect(); | 66 Disconnect(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { | 69 int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { |
| 70 DCHECK_EQ(STATE_NONE, next_state_); | 70 DCHECK_EQ(STATE_NONE, next_state_); |
| 71 DCHECK(user_callback_.is_null()); | 71 DCHECK(user_callback_.is_null()); |
| 72 | 72 |
| 73 int rv = PrepareForAuthRestart(); | 73 int rv = PrepareForAuthRestart(); |
| 74 if (rv != OK) | 74 if (rv != OK) |
| 75 return rv; | 75 return rv; |
| 76 | 76 |
| 77 rv = DoLoop(OK); | 77 rv = DoLoop(OK); |
| 78 if (rv == ERR_IO_PENDING) { | 78 if (rv == ERR_IO_PENDING) { |
| 79 if (!callback.is_null()) | 79 if (!callback.is_null()) |
| 80 user_callback_ = callback; | 80 user_callback_ = callback; |
| 81 } | 81 } |
| 82 | 82 |
| 83 return rv; | 83 return rv; |
| 84 } | 84 } |
| 85 | 85 |
| 86 const scoped_refptr<HttpAuthController>& | 86 const scoped_refptr<HttpAuthController>& |
| 87 HttpProxyClientSocket::GetAuthController() const { | 87 HttpProxyClientSocket::GetAuthController() const { |
| 88 return auth_; | 88 return auth_; |
| 89 } | 89 } |
| 90 | 90 |
| 91 bool HttpProxyClientSocket::IsUsingSpdy() const { | 91 bool HttpProxyClientSocket::IsUsingSpdy() const { |
| 92 return using_spdy_; | 92 return using_spdy_; |
| 93 } | 93 } |
| 94 | 94 |
| 95 NextProto HttpProxyClientSocket::GetProtocolNegotiated() const { | 95 NextProto HttpProxyClientSocket::GetProtocolNegotiated() const { |
| 96 return protocol_negotiated_; | 96 return protocol_negotiated_; |
| 97 } | 97 } |
| 98 | 98 |
| 99 const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const { | 99 const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const { |
| 100 return response_.headers.get() ? &response_ : NULL; | 100 return response_.headers.get() ? &response_ : NULL; |
| 101 } | 101 } |
| 102 | 102 |
| 103 HttpStream* HttpProxyClientSocket::CreateConnectResponseStream() { | 103 HttpStream* HttpProxyClientSocket::CreateConnectResponseStream() { |
| 104 return new ProxyConnectRedirectHttpStream( | 104 return new ProxyConnectRedirectHttpStream( |
| 105 redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : NULL); | 105 redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : NULL); |
| 106 } | 106 } |
| 107 | 107 |
| 108 | |
| 109 int HttpProxyClientSocket::Connect(const CompletionCallback& callback) { | 108 int HttpProxyClientSocket::Connect(const CompletionCallback& callback) { |
| 110 DCHECK(transport_.get()); | 109 DCHECK(transport_.get()); |
| 111 DCHECK(transport_->socket()); | 110 DCHECK(transport_->socket()); |
| 112 DCHECK(user_callback_.is_null()); | 111 DCHECK(user_callback_.is_null()); |
| 113 | 112 |
| 114 // TODO(rch): figure out the right way to set up a tunnel with SPDY. | 113 // TODO(rch): figure out the right way to set up a tunnel with SPDY. |
| 115 // This approach sends the complete HTTPS request to the proxy | 114 // This approach sends the complete HTTPS request to the proxy |
| 116 // which allows the proxy to see "private" data. Instead, we should | 115 // which allows the proxy to see "private" data. Instead, we should |
| 117 // create an SSL tunnel to the origin server using the CONNECT method | 116 // create an SSL tunnel to the origin server using the CONNECT method |
| 118 // inside a single SPDY stream. | 117 // inside a single SPDY stream. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 139 next_state_ = STATE_NONE; | 138 next_state_ = STATE_NONE; |
| 140 user_callback_.Reset(); | 139 user_callback_.Reset(); |
| 141 } | 140 } |
| 142 | 141 |
| 143 bool HttpProxyClientSocket::IsConnected() const { | 142 bool HttpProxyClientSocket::IsConnected() const { |
| 144 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); | 143 return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); |
| 145 } | 144 } |
| 146 | 145 |
| 147 bool HttpProxyClientSocket::IsConnectedAndIdle() const { | 146 bool HttpProxyClientSocket::IsConnectedAndIdle() const { |
| 148 return next_state_ == STATE_DONE && | 147 return next_state_ == STATE_DONE && |
| 149 transport_->socket()->IsConnectedAndIdle(); | 148 transport_->socket()->IsConnectedAndIdle(); |
| 150 } | 149 } |
| 151 | 150 |
| 152 const BoundNetLog& HttpProxyClientSocket::NetLog() const { | 151 const BoundNetLog& HttpProxyClientSocket::NetLog() const { |
| 153 return net_log_; | 152 return net_log_; |
| 154 } | 153 } |
| 155 | 154 |
| 156 void HttpProxyClientSocket::SetSubresourceSpeculation() { | 155 void HttpProxyClientSocket::SetSubresourceSpeculation() { |
| 157 if (transport_.get() && transport_->socket()) { | 156 if (transport_.get() && transport_->socket()) { |
| 158 transport_->socket()->SetSubresourceSpeculation(); | 157 transport_->socket()->SetSubresourceSpeculation(); |
| 159 } else { | 158 } else { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } | 201 } |
| 203 | 202 |
| 204 bool HttpProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | 203 bool HttpProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { |
| 205 if (transport_.get() && transport_->socket()) { | 204 if (transport_.get() && transport_->socket()) { |
| 206 return transport_->socket()->GetSSLInfo(ssl_info); | 205 return transport_->socket()->GetSSLInfo(ssl_info); |
| 207 } | 206 } |
| 208 NOTREACHED(); | 207 NOTREACHED(); |
| 209 return false; | 208 return false; |
| 210 } | 209 } |
| 211 | 210 |
| 212 int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len, | 211 int HttpProxyClientSocket::Read(IOBuffer* buf, |
| 212 int buf_len, |
| 213 const CompletionCallback& callback) { | 213 const CompletionCallback& callback) { |
| 214 DCHECK(user_callback_.is_null()); | 214 DCHECK(user_callback_.is_null()); |
| 215 if (next_state_ != STATE_DONE) { | 215 if (next_state_ != STATE_DONE) { |
| 216 // We're trying to read the body of the response but we're still trying | 216 // We're trying to read the body of the response but we're still trying |
| 217 // to establish an SSL tunnel through the proxy. We can't read these | 217 // to establish an SSL tunnel through the proxy. We can't read these |
| 218 // bytes when establishing a tunnel because they might be controlled by | 218 // bytes when establishing a tunnel because they might be controlled by |
| 219 // an active network attacker. We don't worry about this for HTTP | 219 // an active network attacker. We don't worry about this for HTTP |
| 220 // because an active network attacker can already control HTTP sessions. | 220 // because an active network attacker can already control HTTP sessions. |
| 221 // We reach this case when the user cancels a 407 proxy auth prompt. | 221 // We reach this case when the user cancels a 407 proxy auth prompt. |
| 222 // See http://crbug.com/8473. | 222 // See http://crbug.com/8473. |
| 223 DCHECK_EQ(407, response_.headers->response_code()); | 223 DCHECK_EQ(407, response_.headers->response_code()); |
| 224 LogBlockedTunnelResponse(); | 224 LogBlockedTunnelResponse(); |
| 225 | 225 |
| 226 return ERR_TUNNEL_CONNECTION_FAILED; | 226 return ERR_TUNNEL_CONNECTION_FAILED; |
| 227 } | 227 } |
| 228 | 228 |
| 229 return transport_->socket()->Read(buf, buf_len, callback); | 229 return transport_->socket()->Read(buf, buf_len, callback); |
| 230 } | 230 } |
| 231 | 231 |
| 232 int HttpProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 232 int HttpProxyClientSocket::Write(IOBuffer* buf, |
| 233 int buf_len, |
| 233 const CompletionCallback& callback) { | 234 const CompletionCallback& callback) { |
| 234 DCHECK_EQ(STATE_DONE, next_state_); | 235 DCHECK_EQ(STATE_DONE, next_state_); |
| 235 DCHECK(user_callback_.is_null()); | 236 DCHECK(user_callback_.is_null()); |
| 236 | 237 |
| 237 return transport_->socket()->Write(buf, buf_len, callback); | 238 return transport_->socket()->Write(buf, buf_len, callback); |
| 238 } | 239 } |
| 239 | 240 |
| 240 int HttpProxyClientSocket::SetReceiveBufferSize(int32 size) { | 241 int HttpProxyClientSocket::SetReceiveBufferSize(int32 size) { |
| 241 return transport_->socket()->SetReceiveBufferSize(size); | 242 return transport_->socket()->SetReceiveBufferSize(size); |
| 242 } | 243 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 parser_buf_ = NULL; | 290 parser_buf_ = NULL; |
| 290 http_stream_parser_.reset(); | 291 http_stream_parser_.reset(); |
| 291 request_line_.clear(); | 292 request_line_.clear(); |
| 292 request_headers_.Clear(); | 293 request_headers_.Clear(); |
| 293 response_ = HttpResponseInfo(); | 294 response_ = HttpResponseInfo(); |
| 294 return OK; | 295 return OK; |
| 295 } | 296 } |
| 296 | 297 |
| 297 void HttpProxyClientSocket::LogBlockedTunnelResponse() const { | 298 void HttpProxyClientSocket::LogBlockedTunnelResponse() const { |
| 298 ProxyClientSocket::LogBlockedTunnelResponse( | 299 ProxyClientSocket::LogBlockedTunnelResponse( |
| 299 response_.headers->response_code(), | 300 response_.headers->response_code(), request_.url, is_https_proxy_); |
| 300 request_.url, | |
| 301 is_https_proxy_); | |
| 302 } | 301 } |
| 303 | 302 |
| 304 void HttpProxyClientSocket::DoCallback(int result) { | 303 void HttpProxyClientSocket::DoCallback(int result) { |
| 305 DCHECK_NE(ERR_IO_PENDING, result); | 304 DCHECK_NE(ERR_IO_PENDING, result); |
| 306 DCHECK(!user_callback_.is_null()); | 305 DCHECK(!user_callback_.is_null()); |
| 307 | 306 |
| 308 // Since Run() may result in Read being called, | 307 // Since Run() may result in Read being called, |
| 309 // clear user_callback_ up front. | 308 // clear user_callback_ up front. |
| 310 CompletionCallback c = user_callback_; | 309 CompletionCallback c = user_callback_; |
| 311 user_callback_.Reset(); | 310 user_callback_.Reset(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 330 switch (state) { | 329 switch (state) { |
| 331 case STATE_GENERATE_AUTH_TOKEN: | 330 case STATE_GENERATE_AUTH_TOKEN: |
| 332 DCHECK_EQ(OK, rv); | 331 DCHECK_EQ(OK, rv); |
| 333 rv = DoGenerateAuthToken(); | 332 rv = DoGenerateAuthToken(); |
| 334 break; | 333 break; |
| 335 case STATE_GENERATE_AUTH_TOKEN_COMPLETE: | 334 case STATE_GENERATE_AUTH_TOKEN_COMPLETE: |
| 336 rv = DoGenerateAuthTokenComplete(rv); | 335 rv = DoGenerateAuthTokenComplete(rv); |
| 337 break; | 336 break; |
| 338 case STATE_SEND_REQUEST: | 337 case STATE_SEND_REQUEST: |
| 339 DCHECK_EQ(OK, rv); | 338 DCHECK_EQ(OK, rv); |
| 340 net_log_.BeginEvent( | 339 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST); |
| 341 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST); | |
| 342 rv = DoSendRequest(); | 340 rv = DoSendRequest(); |
| 343 break; | 341 break; |
| 344 case STATE_SEND_REQUEST_COMPLETE: | 342 case STATE_SEND_REQUEST_COMPLETE: |
| 345 rv = DoSendRequestComplete(rv); | 343 rv = DoSendRequestComplete(rv); |
| 346 net_log_.EndEventWithNetErrorCode( | 344 net_log_.EndEventWithNetErrorCode( |
| 347 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv); | 345 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv); |
| 348 break; | 346 break; |
| 349 case STATE_READ_HEADERS: | 347 case STATE_READ_HEADERS: |
| 350 DCHECK_EQ(OK, rv); | 348 DCHECK_EQ(OK, rv); |
| 351 net_log_.BeginEvent( | 349 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS); |
| 352 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS); | |
| 353 rv = DoReadHeaders(); | 350 rv = DoReadHeaders(); |
| 354 break; | 351 break; |
| 355 case STATE_READ_HEADERS_COMPLETE: | 352 case STATE_READ_HEADERS_COMPLETE: |
| 356 rv = DoReadHeadersComplete(rv); | 353 rv = DoReadHeadersComplete(rv); |
| 357 net_log_.EndEventWithNetErrorCode( | 354 net_log_.EndEventWithNetErrorCode( |
| 358 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); | 355 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); |
| 359 break; | 356 break; |
| 360 case STATE_DRAIN_BODY: | 357 case STATE_DRAIN_BODY: |
| 361 DCHECK_EQ(OK, rv); | 358 DCHECK_EQ(OK, rv); |
| 362 rv = DoDrainBody(); | 359 rv = DoDrainBody(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 int HttpProxyClientSocket::DoSendRequest() { | 395 int HttpProxyClientSocket::DoSendRequest() { |
| 399 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 396 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
| 400 | 397 |
| 401 // This is constructed lazily (instead of within our Start method), so that | 398 // This is constructed lazily (instead of within our Start method), so that |
| 402 // we have proxy info available. | 399 // we have proxy info available. |
| 403 if (request_line_.empty()) { | 400 if (request_line_.empty()) { |
| 404 DCHECK(request_headers_.IsEmpty()); | 401 DCHECK(request_headers_.IsEmpty()); |
| 405 HttpRequestHeaders authorization_headers; | 402 HttpRequestHeaders authorization_headers; |
| 406 if (auth_->HaveAuth()) | 403 if (auth_->HaveAuth()) |
| 407 auth_->AddAuthorizationHeader(&authorization_headers); | 404 auth_->AddAuthorizationHeader(&authorization_headers); |
| 408 BuildTunnelRequest(request_, authorization_headers, endpoint_, | 405 BuildTunnelRequest(request_, |
| 409 &request_line_, &request_headers_); | 406 authorization_headers, |
| 407 endpoint_, |
| 408 &request_line_, |
| 409 &request_headers_); |
| 410 | 410 |
| 411 net_log_.AddEvent( | 411 net_log_.AddEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, |
| 412 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, | 412 base::Bind(&HttpRequestHeaders::NetLogCallback, |
| 413 base::Bind(&HttpRequestHeaders::NetLogCallback, | 413 base::Unretained(&request_headers_), |
| 414 base::Unretained(&request_headers_), | 414 &request_line_)); |
| 415 &request_line_)); | |
| 416 } | 415 } |
| 417 | 416 |
| 418 parser_buf_ = new GrowableIOBuffer(); | 417 parser_buf_ = new GrowableIOBuffer(); |
| 419 http_stream_parser_.reset(new HttpStreamParser( | 418 http_stream_parser_.reset(new HttpStreamParser( |
| 420 transport_.get(), &request_, parser_buf_.get(), net_log_)); | 419 transport_.get(), &request_, parser_buf_.get(), net_log_)); |
| 421 return http_stream_parser_->SendRequest( | 420 return http_stream_parser_->SendRequest( |
| 422 request_line_, request_headers_, &response_, io_callback_); | 421 request_line_, request_headers_, &response_, io_callback_); |
| 423 } | 422 } |
| 424 | 423 |
| 425 int HttpProxyClientSocket::DoSendRequestComplete(int result) { | 424 int HttpProxyClientSocket::DoSendRequestComplete(int result) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 449 | 448 |
| 450 switch (response_.headers->response_code()) { | 449 switch (response_.headers->response_code()) { |
| 451 case 200: // OK | 450 case 200: // OK |
| 452 if (http_stream_parser_->IsMoreDataBuffered()) | 451 if (http_stream_parser_->IsMoreDataBuffered()) |
| 453 // The proxy sent extraneous data after the headers. | 452 // The proxy sent extraneous data after the headers. |
| 454 return ERR_TUNNEL_CONNECTION_FAILED; | 453 return ERR_TUNNEL_CONNECTION_FAILED; |
| 455 | 454 |
| 456 next_state_ = STATE_DONE; | 455 next_state_ = STATE_DONE; |
| 457 return OK; | 456 return OK; |
| 458 | 457 |
| 459 // We aren't able to CONNECT to the remote host through the proxy. We | 458 // We aren't able to CONNECT to the remote host through the proxy. We |
| 460 // need to be very suspicious about the response because an active network | 459 // need to be very suspicious about the response because an active network |
| 461 // attacker can force us into this state by masquerading as the proxy. | 460 // attacker can force us into this state by masquerading as the proxy. |
| 462 // The only safe thing to do here is to fail the connection because our | 461 // The only safe thing to do here is to fail the connection because our |
| 463 // client is expecting an SSL protected response. | 462 // client is expecting an SSL protected response. |
| 464 // See http://crbug.com/7338. | 463 // See http://crbug.com/7338. |
| 465 | 464 |
| 466 case 302: // Found / Moved Temporarily | 465 case 302: // Found / Moved Temporarily |
| 467 // Attempt to follow redirects from HTTPS proxies, but only if we can | 466 // Attempt to follow redirects from HTTPS proxies, but only if we can |
| 468 // sanitize the response. This still allows a rogue HTTPS proxy to | 467 // sanitize the response. This still allows a rogue HTTPS proxy to |
| 469 // redirect an HTTPS site load to a similar-looking site, but no longer | 468 // redirect an HTTPS site load to a similar-looking site, but no longer |
| 470 // allows it to impersonate the site the user requested. | 469 // allows it to impersonate the site the user requested. |
| 471 if (is_https_proxy_ && SanitizeProxyRedirect(&response_, request_.url)) { | 470 if (is_https_proxy_ && SanitizeProxyRedirect(&response_, request_.url)) { |
| 472 bool is_connection_reused = http_stream_parser_->IsConnectionReused(); | 471 bool is_connection_reused = http_stream_parser_->IsConnectionReused(); |
| 473 redirect_has_load_timing_info_ = | 472 redirect_has_load_timing_info_ = transport_->GetLoadTimingInfo( |
| 474 transport_->GetLoadTimingInfo( | 473 is_connection_reused, &redirect_load_timing_info_); |
| 475 is_connection_reused, &redirect_load_timing_info_); | |
| 476 transport_.reset(); | 474 transport_.reset(); |
| 477 http_stream_parser_.reset(); | 475 http_stream_parser_.reset(); |
| 478 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; | 476 return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; |
| 479 } | 477 } |
| 480 | 478 |
| 481 // We're not using an HTTPS proxy, or we couldn't sanitize the redirect. | 479 // We're not using an HTTPS proxy, or we couldn't sanitize the redirect. |
| 482 LogBlockedTunnelResponse(); | 480 LogBlockedTunnelResponse(); |
| 483 return ERR_TUNNEL_CONNECTION_FAILED; | 481 return ERR_TUNNEL_CONNECTION_FAILED; |
| 484 | 482 |
| 485 case 407: // Proxy Authentication Required | 483 case 407: // Proxy Authentication Required |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 527 |
| 530 int HttpProxyClientSocket::DoTCPRestartComplete(int result) { | 528 int HttpProxyClientSocket::DoTCPRestartComplete(int result) { |
| 531 if (result != OK) | 529 if (result != OK) |
| 532 return result; | 530 return result; |
| 533 | 531 |
| 534 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 532 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 535 return result; | 533 return result; |
| 536 } | 534 } |
| 537 | 535 |
| 538 } // namespace net | 536 } // namespace net |
| OLD | NEW |