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, buf_len, |
228 buf_len, buf->data()); | 230 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; |
238 } | 240 } |
(...skipping 46 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(NetLogEventType::SOCKET_BYTES_RECEIVED, 0, |
| 463 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 |