| 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/spdy/spdy_proxy_client_socket.h" | 5 #include "net/spdy/spdy_proxy_client_socket.h" |
| 6 | 6 |
| 7 #include <algorithm> // min | 7 #include <algorithm> // min |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "base/values.h" | 18 #include "base/values.h" |
| 19 #include "net/base/auth.h" | 19 #include "net/base/auth.h" |
| 20 #include "net/base/io_buffer.h" | 20 #include "net/base/io_buffer.h" |
| 21 #include "net/http/http_auth_cache.h" | 21 #include "net/http/http_auth_cache.h" |
| 22 #include "net/http/http_auth_handler_factory.h" | 22 #include "net/http/http_auth_handler_factory.h" |
| 23 #include "net/http/http_request_info.h" | 23 #include "net/http/http_request_info.h" |
| 24 #include "net/http/http_response_headers.h" | 24 #include "net/http/http_response_headers.h" |
| 25 #include "net/http/proxy_connect_redirect_http_stream.h" | 25 #include "net/http/proxy_connect_redirect_http_stream.h" |
| 26 #include "net/log/net_log_event_type.h" |
| 27 #include "net/log/net_log_source_type.h" |
| 26 #include "net/spdy/spdy_http_utils.h" | 28 #include "net/spdy/spdy_http_utils.h" |
| 27 #include "url/gurl.h" | 29 #include "url/gurl.h" |
| 28 | 30 |
| 29 namespace net { | 31 namespace net { |
| 30 | 32 |
| 31 SpdyProxyClientSocket::SpdyProxyClientSocket( | 33 SpdyProxyClientSocket::SpdyProxyClientSocket( |
| 32 const base::WeakPtr<SpdyStream>& spdy_stream, | 34 const base::WeakPtr<SpdyStream>& spdy_stream, |
| 33 const std::string& user_agent, | 35 const std::string& user_agent, |
| 34 const HostPortPair& endpoint, | 36 const HostPortPair& endpoint, |
| 35 const HostPortPair& proxy_server, | 37 const HostPortPair& proxy_server, |
| 36 const BoundNetLog& source_net_log, | 38 const BoundNetLog& source_net_log, |
| 37 HttpAuthController* auth_controller) | 39 HttpAuthController* auth_controller) |
| 38 : next_state_(STATE_DISCONNECTED), | 40 : next_state_(STATE_DISCONNECTED), |
| 39 spdy_stream_(spdy_stream), | 41 spdy_stream_(spdy_stream), |
| 40 endpoint_(endpoint), | 42 endpoint_(endpoint), |
| 41 auth_(auth_controller), | 43 auth_(auth_controller), |
| 42 user_agent_(user_agent), | 44 user_agent_(user_agent), |
| 43 user_buffer_len_(0), | 45 user_buffer_len_(0), |
| 44 write_buffer_len_(0), | 46 write_buffer_len_(0), |
| 45 was_ever_used_(false), | 47 was_ever_used_(false), |
| 46 redirect_has_load_timing_info_(false), | 48 redirect_has_load_timing_info_(false), |
| 47 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), | 49 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), |
| 48 NetLog::SOURCE_PROXY_CLIENT_SOCKET)), | 50 NetLogSourceType::PROXY_CLIENT_SOCKET)), |
| 49 weak_factory_(this), | 51 weak_factory_(this), |
| 50 write_callback_weak_factory_(this) { | 52 write_callback_weak_factory_(this) { |
| 51 request_.method = "CONNECT"; | 53 request_.method = "CONNECT"; |
| 52 request_.url = GURL("https://" + endpoint.ToString()); | 54 request_.url = GURL("https://" + endpoint.ToString()); |
| 53 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 55 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, |
| 54 source_net_log.source().ToEventParametersCallback()); | 56 source_net_log.source().ToEventParametersCallback()); |
| 55 net_log_.AddEvent( | 57 net_log_.AddEvent( |
| 56 NetLog::TYPE_HTTP2_PROXY_CLIENT_SESSION, | 58 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION, |
| 57 spdy_stream->net_log().source().ToEventParametersCallback()); | 59 spdy_stream->net_log().source().ToEventParametersCallback()); |
| 58 | 60 |
| 59 spdy_stream_->SetDelegate(this); | 61 spdy_stream_->SetDelegate(this); |
| 60 was_ever_used_ = spdy_stream_->WasEverUsed(); | 62 was_ever_used_ = spdy_stream_->WasEverUsed(); |
| 61 } | 63 } |
| 62 | 64 |
| 63 SpdyProxyClientSocket::~SpdyProxyClientSocket() { | 65 SpdyProxyClientSocket::~SpdyProxyClientSocket() { |
| 64 Disconnect(); | 66 Disconnect(); |
| 65 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); | 67 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
| 66 } | 68 } |
| 67 | 69 |
| 68 const HttpResponseInfo* SpdyProxyClientSocket::GetConnectResponseInfo() const { | 70 const HttpResponseInfo* SpdyProxyClientSocket::GetConnectResponseInfo() const { |
| 69 return response_.headers.get() ? &response_ : NULL; | 71 return response_.headers.get() ? &response_ : NULL; |
| 70 } | 72 } |
| 71 | 73 |
| 72 const scoped_refptr<HttpAuthController>& | 74 const scoped_refptr<HttpAuthController>& |
| 73 SpdyProxyClientSocket::GetAuthController() const { | 75 SpdyProxyClientSocket::GetAuthController() const { |
| 74 return auth_; | 76 return auth_; |
| 75 } | 77 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 219 } |
| 218 | 220 |
| 219 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 221 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, |
| 220 const CompletionCallback& callback) { | 222 const CompletionCallback& callback) { |
| 221 DCHECK(write_callback_.is_null()); | 223 DCHECK(write_callback_.is_null()); |
| 222 if (next_state_ != STATE_OPEN) | 224 if (next_state_ != STATE_OPEN) |
| 223 return ERR_SOCKET_NOT_CONNECTED; | 225 return ERR_SOCKET_NOT_CONNECTED; |
| 224 | 226 |
| 225 DCHECK(spdy_stream_.get()); | 227 DCHECK(spdy_stream_.get()); |
| 226 spdy_stream_->SendData(buf, buf_len, MORE_DATA_TO_SEND); | 228 spdy_stream_->SendData(buf, buf_len, MORE_DATA_TO_SEND); |
| 227 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | 229 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_SENT, |
| 228 buf_len, buf->data()); | 230 buf_len, buf->data()); |
| 229 write_callback_ = callback; | 231 write_callback_ = callback; |
| 230 write_buffer_len_ = buf_len; | 232 write_buffer_len_ = buf_len; |
| 231 return ERR_IO_PENDING; | 233 return ERR_IO_PENDING; |
| 232 } | 234 } |
| 233 | 235 |
| 234 int SpdyProxyClientSocket::SetReceiveBufferSize(int32_t size) { | 236 int SpdyProxyClientSocket::SetReceiveBufferSize(int32_t size) { |
| 235 // Since this StreamSocket sits on top of a shared SpdySession, it | 237 // Since this StreamSocket sits on top of a shared SpdySession, it |
| 236 // is not safe for callers to change this underlying socket. | 238 // is not safe for callers to change this underlying socket. |
| 237 return ERR_NOT_IMPLEMENTED; | 239 return ERR_NOT_IMPLEMENTED; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 switch (state) { | 287 switch (state) { |
| 286 case STATE_GENERATE_AUTH_TOKEN: | 288 case STATE_GENERATE_AUTH_TOKEN: |
| 287 DCHECK_EQ(OK, rv); | 289 DCHECK_EQ(OK, rv); |
| 288 rv = DoGenerateAuthToken(); | 290 rv = DoGenerateAuthToken(); |
| 289 break; | 291 break; |
| 290 case STATE_GENERATE_AUTH_TOKEN_COMPLETE: | 292 case STATE_GENERATE_AUTH_TOKEN_COMPLETE: |
| 291 rv = DoGenerateAuthTokenComplete(rv); | 293 rv = DoGenerateAuthTokenComplete(rv); |
| 292 break; | 294 break; |
| 293 case STATE_SEND_REQUEST: | 295 case STATE_SEND_REQUEST: |
| 294 DCHECK_EQ(OK, rv); | 296 DCHECK_EQ(OK, rv); |
| 295 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST); | 297 net_log_.BeginEvent( |
| 298 NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST); |
| 296 rv = DoSendRequest(); | 299 rv = DoSendRequest(); |
| 297 break; | 300 break; |
| 298 case STATE_SEND_REQUEST_COMPLETE: | 301 case STATE_SEND_REQUEST_COMPLETE: |
| 299 net_log_.EndEventWithNetErrorCode( | 302 net_log_.EndEventWithNetErrorCode( |
| 300 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv); | 303 NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST, rv); |
| 301 rv = DoSendRequestComplete(rv); | 304 rv = DoSendRequestComplete(rv); |
| 302 if (rv >= 0 || rv == ERR_IO_PENDING) { | 305 if (rv >= 0 || rv == ERR_IO_PENDING) { |
| 303 // Emit extra event so can use the same events as | 306 // Emit extra event so can use the same events as |
| 304 // HttpProxyClientSocket. | 307 // HttpProxyClientSocket. |
| 305 net_log_.BeginEvent( | 308 net_log_.BeginEvent( |
| 306 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS); | 309 NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS); |
| 307 } | 310 } |
| 308 break; | 311 break; |
| 309 case STATE_READ_REPLY_COMPLETE: | 312 case STATE_READ_REPLY_COMPLETE: |
| 310 rv = DoReadReplyComplete(rv); | 313 rv = DoReadReplyComplete(rv); |
| 311 net_log_.EndEventWithNetErrorCode( | 314 net_log_.EndEventWithNetErrorCode( |
| 312 NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); | 315 NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); |
| 313 break; | 316 break; |
| 314 default: | 317 default: |
| 315 NOTREACHED() << "bad state"; | 318 NOTREACHED() << "bad state"; |
| 316 rv = ERR_UNEXPECTED; | 319 rv = ERR_UNEXPECTED; |
| 317 break; | 320 break; |
| 318 } | 321 } |
| 319 } while (rv != ERR_IO_PENDING && next_state_ != STATE_DISCONNECTED && | 322 } while (rv != ERR_IO_PENDING && next_state_ != STATE_DISCONNECTED && |
| 320 next_state_ != STATE_OPEN); | 323 next_state_ != STATE_OPEN); |
| 321 return rv; | 324 return rv; |
| 322 } | 325 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 344 HttpRequestHeaders authorization_headers; | 347 HttpRequestHeaders authorization_headers; |
| 345 if (auth_->HaveAuth()) { | 348 if (auth_->HaveAuth()) { |
| 346 auth_->AddAuthorizationHeader(&authorization_headers); | 349 auth_->AddAuthorizationHeader(&authorization_headers); |
| 347 } | 350 } |
| 348 | 351 |
| 349 std::string request_line; | 352 std::string request_line; |
| 350 BuildTunnelRequest(endpoint_, authorization_headers, user_agent_, | 353 BuildTunnelRequest(endpoint_, authorization_headers, user_agent_, |
| 351 &request_line, &request_.extra_headers); | 354 &request_line, &request_.extra_headers); |
| 352 | 355 |
| 353 net_log_.AddEvent( | 356 net_log_.AddEvent( |
| 354 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, | 357 NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, |
| 355 base::Bind(&HttpRequestHeaders::NetLogCallback, | 358 base::Bind(&HttpRequestHeaders::NetLogCallback, |
| 356 base::Unretained(&request_.extra_headers), &request_line)); | 359 base::Unretained(&request_.extra_headers), &request_line)); |
| 357 | 360 |
| 358 SpdyHeaderBlock headers; | 361 SpdyHeaderBlock headers; |
| 359 CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, true, | 362 CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, true, |
| 360 &headers); | 363 &headers); |
| 361 | 364 |
| 362 return spdy_stream_->SendRequestHeaders(std::move(headers), | 365 return spdy_stream_->SendRequestHeaders(std::move(headers), |
| 363 MORE_DATA_TO_SEND); | 366 MORE_DATA_TO_SEND); |
| 364 } | 367 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 377 // we are notified by a callback when the HEADERS frame arrives. | 380 // we are notified by a callback when the HEADERS frame arrives. |
| 378 | 381 |
| 379 if (result < 0) | 382 if (result < 0) |
| 380 return result; | 383 return result; |
| 381 | 384 |
| 382 // Require the "HTTP/1.x" status line for SSL CONNECT. | 385 // Require the "HTTP/1.x" status line for SSL CONNECT. |
| 383 if (response_.headers->GetHttpVersion() < HttpVersion(1, 0)) | 386 if (response_.headers->GetHttpVersion() < HttpVersion(1, 0)) |
| 384 return ERR_TUNNEL_CONNECTION_FAILED; | 387 return ERR_TUNNEL_CONNECTION_FAILED; |
| 385 | 388 |
| 386 net_log_.AddEvent( | 389 net_log_.AddEvent( |
| 387 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, | 390 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, |
| 388 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); | 391 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); |
| 389 | 392 |
| 390 switch (response_.headers->response_code()) { | 393 switch (response_.headers->response_code()) { |
| 391 case 200: // OK | 394 case 200: // OK |
| 392 next_state_ = STATE_OPEN; | 395 next_state_ = STATE_OPEN; |
| 393 return OK; | 396 return OK; |
| 394 | 397 |
| 395 case 302: // Found / Moved Temporarily | 398 case 302: // Found / Moved Temporarily |
| 396 // Try to return a sanitized response so we can follow auth redirects. | 399 // Try to return a sanitized response so we can follow auth redirects. |
| 397 // If we can't, fail the tunnel connection. | 400 // If we can't, fail the tunnel connection. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 if (!SpdyHeadersToHttpResponse(response_headers, &response_)) | 447 if (!SpdyHeadersToHttpResponse(response_headers, &response_)) |
| 445 return RESPONSE_HEADERS_ARE_INCOMPLETE; | 448 return RESPONSE_HEADERS_ARE_INCOMPLETE; |
| 446 | 449 |
| 447 OnIOComplete(OK); | 450 OnIOComplete(OK); |
| 448 return RESPONSE_HEADERS_ARE_COMPLETE; | 451 return RESPONSE_HEADERS_ARE_COMPLETE; |
| 449 } | 452 } |
| 450 | 453 |
| 451 // Called when data is received or on EOF (if |buffer| is NULL). | 454 // Called when data is received or on EOF (if |buffer| is NULL). |
| 452 void SpdyProxyClientSocket::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { | 455 void SpdyProxyClientSocket::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { |
| 453 if (buffer) { | 456 if (buffer) { |
| 454 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 457 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, |
| 455 buffer->GetRemainingSize(), | 458 buffer->GetRemainingSize(), |
| 456 buffer->GetRemainingData()); | 459 buffer->GetRemainingData()); |
| 457 read_buffer_queue_.Enqueue(std::move(buffer)); | 460 read_buffer_queue_.Enqueue(std::move(buffer)); |
| 458 } else { | 461 } else { |
| 459 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, 0, NULL); | 462 net_log_.AddByteTransferEvent( |
| 463 NetLogEventType::SOCKET_BYTES_RECEIVED, 0, NULL); |
| 460 } | 464 } |
| 461 | 465 |
| 462 if (!read_callback_.is_null()) { | 466 if (!read_callback_.is_null()) { |
| 463 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); | 467 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); |
| 464 CompletionCallback c = read_callback_; | 468 CompletionCallback c = read_callback_; |
| 465 read_callback_.Reset(); | 469 read_callback_.Reset(); |
| 466 user_buffer_ = NULL; | 470 user_buffer_ = NULL; |
| 467 user_buffer_len_ = 0; | 471 user_buffer_len_ = 0; |
| 468 c.Run(rv); | 472 c.Run(rv); |
| 469 } | 473 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 } else if (!read_callback_.is_null()) { | 519 } else if (!read_callback_.is_null()) { |
| 516 // If we have a read_callback_, the we need to make sure we call it back. | 520 // If we have a read_callback_, the we need to make sure we call it back. |
| 517 OnDataReceived(std::unique_ptr<SpdyBuffer>()); | 521 OnDataReceived(std::unique_ptr<SpdyBuffer>()); |
| 518 } | 522 } |
| 519 // This may have been deleted by read_callback_, so check first. | 523 // This may have been deleted by read_callback_, so check first. |
| 520 if (weak_ptr.get() && !write_callback.is_null()) | 524 if (weak_ptr.get() && !write_callback.is_null()) |
| 521 write_callback.Run(ERR_CONNECTION_CLOSED); | 525 write_callback.Run(ERR_CONNECTION_CLOSED); |
| 522 } | 526 } |
| 523 | 527 |
| 524 } // namespace net | 528 } // namespace net |
| OLD | NEW |