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 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 const std::string& user_agent, | 29 const std::string& user_agent, |
30 const HostPortPair& endpoint, | 30 const HostPortPair& endpoint, |
31 const GURL& url, | 31 const GURL& url, |
32 const HostPortPair& proxy_server, | 32 const HostPortPair& proxy_server, |
33 const BoundNetLog& source_net_log, | 33 const BoundNetLog& source_net_log, |
34 HttpAuthCache* auth_cache, | 34 HttpAuthCache* auth_cache, |
35 HttpAuthHandlerFactory* auth_handler_factory) | 35 HttpAuthHandlerFactory* auth_handler_factory) |
36 : next_state_(STATE_DISCONNECTED), | 36 : next_state_(STATE_DISCONNECTED), |
37 spdy_stream_(spdy_stream), | 37 spdy_stream_(spdy_stream), |
38 endpoint_(endpoint), | 38 endpoint_(endpoint), |
39 auth_( | 39 auth_(new HttpAuthController(HttpAuth::AUTH_PROXY, |
40 new HttpAuthController(HttpAuth::AUTH_PROXY, | 40 GURL("https://" + proxy_server.ToString()), |
41 GURL("https://" + proxy_server.ToString()), | 41 auth_cache, |
42 auth_cache, | 42 auth_handler_factory)), |
43 auth_handler_factory)), | |
44 user_buffer_len_(0), | 43 user_buffer_len_(0), |
45 write_buffer_len_(0), | 44 write_buffer_len_(0), |
46 was_ever_used_(false), | 45 was_ever_used_(false), |
47 redirect_has_load_timing_info_(false), | 46 redirect_has_load_timing_info_(false), |
48 weak_factory_(this), | 47 weak_factory_(this), |
49 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), | 48 net_log_(BoundNetLog::Make(spdy_stream->net_log().net_log(), |
50 NetLog::SOURCE_PROXY_CLIENT_SOCKET)) { | 49 NetLog::SOURCE_PROXY_CLIENT_SOCKET)) { |
51 request_.method = "CONNECT"; | 50 request_.method = "CONNECT"; |
52 request_.url = url; | 51 request_.url = url; |
53 if (!user_agent.empty()) | 52 if (!user_agent.empty()) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 | 87 |
89 bool SpdyProxyClientSocket::IsUsingSpdy() const { | 88 bool SpdyProxyClientSocket::IsUsingSpdy() const { |
90 return true; | 89 return true; |
91 } | 90 } |
92 | 91 |
93 NextProto SpdyProxyClientSocket::GetProtocolNegotiated() const { | 92 NextProto SpdyProxyClientSocket::GetProtocolNegotiated() const { |
94 // Save the negotiated protocol | 93 // Save the negotiated protocol |
95 SSLInfo ssl_info; | 94 SSLInfo ssl_info; |
96 bool was_npn_negotiated; | 95 bool was_npn_negotiated; |
97 NextProto protocol_negotiated; | 96 NextProto protocol_negotiated; |
98 spdy_stream_->GetSSLInfo(&ssl_info, &was_npn_negotiated, | 97 spdy_stream_->GetSSLInfo( |
99 &protocol_negotiated); | 98 &ssl_info, &was_npn_negotiated, &protocol_negotiated); |
100 return protocol_negotiated; | 99 return protocol_negotiated; |
101 } | 100 } |
102 | 101 |
103 HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { | 102 HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { |
104 return new ProxyConnectRedirectHttpStream( | 103 return new ProxyConnectRedirectHttpStream( |
105 redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : NULL); | 104 redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : NULL); |
106 } | 105 } |
107 | 106 |
108 // Sends a SYN_STREAM frame to the proxy with a CONNECT request | 107 // Sends a SYN_STREAM frame to the proxy with a CONNECT request |
109 // for the specified endpoint. Waits for the server to send back | 108 // for the specified endpoint. Waits for the server to send back |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 DCHECK(!spdy_stream_.get()); | 146 DCHECK(!spdy_stream_.get()); |
148 } | 147 } |
149 } | 148 } |
150 | 149 |
151 bool SpdyProxyClientSocket::IsConnected() const { | 150 bool SpdyProxyClientSocket::IsConnected() const { |
152 return next_state_ == STATE_OPEN; | 151 return next_state_ == STATE_OPEN; |
153 } | 152 } |
154 | 153 |
155 bool SpdyProxyClientSocket::IsConnectedAndIdle() const { | 154 bool SpdyProxyClientSocket::IsConnectedAndIdle() const { |
156 return IsConnected() && read_buffer_queue_.IsEmpty() && | 155 return IsConnected() && read_buffer_queue_.IsEmpty() && |
157 spdy_stream_->IsOpen(); | 156 spdy_stream_->IsOpen(); |
158 } | 157 } |
159 | 158 |
160 const BoundNetLog& SpdyProxyClientSocket::NetLog() const { | 159 const BoundNetLog& SpdyProxyClientSocket::NetLog() const { |
161 return net_log_; | 160 return net_log_; |
162 } | 161 } |
163 | 162 |
164 void SpdyProxyClientSocket::SetSubresourceSpeculation() { | 163 void SpdyProxyClientSocket::SetSubresourceSpeculation() { |
165 // TODO(rch): what should this implementation be? | 164 // TODO(rch): what should this implementation be? |
166 } | 165 } |
167 | 166 |
(...skipping 13 matching lines...) Expand all Loading... |
181 return false; | 180 return false; |
182 } | 181 } |
183 | 182 |
184 NextProto SpdyProxyClientSocket::GetNegotiatedProtocol() const { | 183 NextProto SpdyProxyClientSocket::GetNegotiatedProtocol() const { |
185 return kProtoUnknown; | 184 return kProtoUnknown; |
186 } | 185 } |
187 | 186 |
188 bool SpdyProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | 187 bool SpdyProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { |
189 bool was_npn_negotiated; | 188 bool was_npn_negotiated; |
190 NextProto protocol_negotiated; | 189 NextProto protocol_negotiated; |
191 return spdy_stream_->GetSSLInfo(ssl_info, &was_npn_negotiated, | 190 return spdy_stream_->GetSSLInfo( |
192 &protocol_negotiated); | 191 ssl_info, &was_npn_negotiated, &protocol_negotiated); |
193 } | 192 } |
194 | 193 |
195 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, | 194 int SpdyProxyClientSocket::Read(IOBuffer* buf, |
| 195 int buf_len, |
196 const CompletionCallback& callback) { | 196 const CompletionCallback& callback) { |
197 DCHECK(read_callback_.is_null()); | 197 DCHECK(read_callback_.is_null()); |
198 DCHECK(!user_buffer_.get()); | 198 DCHECK(!user_buffer_.get()); |
199 | 199 |
200 if (next_state_ == STATE_DISCONNECTED) | 200 if (next_state_ == STATE_DISCONNECTED) |
201 return ERR_SOCKET_NOT_CONNECTED; | 201 return ERR_SOCKET_NOT_CONNECTED; |
202 | 202 |
203 if (next_state_ == STATE_CLOSED && read_buffer_queue_.IsEmpty()) { | 203 if (next_state_ == STATE_CLOSED && read_buffer_queue_.IsEmpty()) { |
204 return 0; | 204 return 0; |
205 } | 205 } |
206 | 206 |
207 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); | 207 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); |
208 DCHECK(buf); | 208 DCHECK(buf); |
209 size_t result = PopulateUserReadBuffer(buf->data(), buf_len); | 209 size_t result = PopulateUserReadBuffer(buf->data(), buf_len); |
210 if (result == 0) { | 210 if (result == 0) { |
211 user_buffer_ = buf; | 211 user_buffer_ = buf; |
212 user_buffer_len_ = static_cast<size_t>(buf_len); | 212 user_buffer_len_ = static_cast<size_t>(buf_len); |
213 DCHECK(!callback.is_null()); | 213 DCHECK(!callback.is_null()); |
214 read_callback_ = callback; | 214 read_callback_ = callback; |
215 return ERR_IO_PENDING; | 215 return ERR_IO_PENDING; |
216 } | 216 } |
217 user_buffer_ = NULL; | 217 user_buffer_ = NULL; |
218 return result; | 218 return result; |
219 } | 219 } |
220 | 220 |
221 size_t SpdyProxyClientSocket::PopulateUserReadBuffer(char* data, size_t len) { | 221 size_t SpdyProxyClientSocket::PopulateUserReadBuffer(char* data, size_t len) { |
222 return read_buffer_queue_.Dequeue(data, len); | 222 return read_buffer_queue_.Dequeue(data, len); |
223 } | 223 } |
224 | 224 |
225 int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len, | 225 int SpdyProxyClientSocket::Write(IOBuffer* buf, |
| 226 int buf_len, |
226 const CompletionCallback& callback) { | 227 const CompletionCallback& callback) { |
227 DCHECK(write_callback_.is_null()); | 228 DCHECK(write_callback_.is_null()); |
228 if (next_state_ != STATE_OPEN) | 229 if (next_state_ != STATE_OPEN) |
229 return ERR_SOCKET_NOT_CONNECTED; | 230 return ERR_SOCKET_NOT_CONNECTED; |
230 | 231 |
231 DCHECK(spdy_stream_.get()); | 232 DCHECK(spdy_stream_.get()); |
232 spdy_stream_->SendData(buf, buf_len, MORE_DATA_TO_SEND); | 233 spdy_stream_->SendData(buf, buf_len, MORE_DATA_TO_SEND); |
233 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, | 234 net_log_.AddByteTransferEvent( |
234 buf_len, buf->data()); | 235 NetLog::TYPE_SOCKET_BYTES_SENT, buf_len, buf->data()); |
235 write_callback_ = callback; | 236 write_callback_ = callback; |
236 write_buffer_len_ = buf_len; | 237 write_buffer_len_ = buf_len; |
237 return ERR_IO_PENDING; | 238 return ERR_IO_PENDING; |
238 } | 239 } |
239 | 240 |
240 int SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) { | 241 int SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) { |
241 // Since this StreamSocket sits on top of a shared SpdySession, it | 242 // Since this StreamSocket sits on top of a shared SpdySession, it |
242 // is not safe for callers to change this underlying socket. | 243 // is not safe for callers to change this underlying socket. |
243 return ERR_NOT_IMPLEMENTED; | 244 return ERR_NOT_IMPLEMENTED; |
244 } | 245 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 344 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
344 | 345 |
345 // Add Proxy-Authentication header if necessary. | 346 // Add Proxy-Authentication header if necessary. |
346 HttpRequestHeaders authorization_headers; | 347 HttpRequestHeaders authorization_headers; |
347 if (auth_->HaveAuth()) { | 348 if (auth_->HaveAuth()) { |
348 auth_->AddAuthorizationHeader(&authorization_headers); | 349 auth_->AddAuthorizationHeader(&authorization_headers); |
349 } | 350 } |
350 | 351 |
351 std::string request_line; | 352 std::string request_line; |
352 HttpRequestHeaders request_headers; | 353 HttpRequestHeaders request_headers; |
353 BuildTunnelRequest(request_, authorization_headers, endpoint_, &request_line, | 354 BuildTunnelRequest(request_, |
| 355 authorization_headers, |
| 356 endpoint_, |
| 357 &request_line, |
354 &request_headers); | 358 &request_headers); |
355 | 359 |
356 net_log_.AddEvent( | 360 net_log_.AddEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, |
357 NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, | 361 base::Bind(&HttpRequestHeaders::NetLogCallback, |
358 base::Bind(&HttpRequestHeaders::NetLogCallback, | 362 base::Unretained(&request_headers), |
359 base::Unretained(&request_headers), | 363 &request_line)); |
360 &request_line)); | |
361 | 364 |
362 request_.extra_headers.MergeFrom(request_headers); | 365 request_.extra_headers.MergeFrom(request_headers); |
363 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); | 366 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); |
364 CreateSpdyHeadersFromHttpRequest(request_, request_headers, headers.get(), | 367 CreateSpdyHeadersFromHttpRequest(request_, |
365 spdy_stream_->GetProtocolVersion(), true); | 368 request_headers, |
| 369 headers.get(), |
| 370 spdy_stream_->GetProtocolVersion(), |
| 371 true); |
366 // Reset the URL to be the endpoint of the connection | 372 // Reset the URL to be the endpoint of the connection |
367 if (spdy_stream_->GetProtocolVersion() > 2) { | 373 if (spdy_stream_->GetProtocolVersion() > 2) { |
368 (*headers)[":path"] = endpoint_.ToString(); | 374 (*headers)[":path"] = endpoint_.ToString(); |
369 headers->erase(":scheme"); | 375 headers->erase(":scheme"); |
370 } else { | 376 } else { |
371 (*headers)["url"] = endpoint_.ToString(); | 377 (*headers)["url"] = endpoint_.ToString(); |
372 headers->erase("scheme"); | 378 headers->erase("scheme"); |
373 } | 379 } |
374 | 380 |
375 return spdy_stream_->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND); | 381 return spdy_stream_->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 if (!read_callback_.is_null()) { | 476 if (!read_callback_.is_null()) { |
471 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); | 477 int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); |
472 CompletionCallback c = read_callback_; | 478 CompletionCallback c = read_callback_; |
473 read_callback_.Reset(); | 479 read_callback_.Reset(); |
474 user_buffer_ = NULL; | 480 user_buffer_ = NULL; |
475 user_buffer_len_ = 0; | 481 user_buffer_len_ = 0; |
476 c.Run(rv); | 482 c.Run(rv); |
477 } | 483 } |
478 } | 484 } |
479 | 485 |
480 void SpdyProxyClientSocket::OnDataSent() { | 486 void SpdyProxyClientSocket::OnDataSent() { |
481 DCHECK(!write_callback_.is_null()); | 487 DCHECK(!write_callback_.is_null()); |
482 | 488 |
483 int rv = write_buffer_len_; | 489 int rv = write_buffer_len_; |
484 write_buffer_len_ = 0; | 490 write_buffer_len_ = 0; |
485 | 491 |
486 // Proxy write callbacks result in deep callback chains. Post to allow the | 492 // Proxy write callbacks result in deep callback chains. Post to allow the |
487 // stream's write callback chain to unwind (see crbug.com/355511). | 493 // stream's write callback chain to unwind (see crbug.com/355511). |
488 base::MessageLoop::current()->PostTask( | 494 base::MessageLoop::current()->PostTask( |
489 FROM_HERE, | 495 FROM_HERE, base::Bind(ResetAndReturn(&write_callback_), rv)); |
490 base::Bind(ResetAndReturn(&write_callback_), rv)); | |
491 } | 496 } |
492 | 497 |
493 void SpdyProxyClientSocket::OnClose(int status) { | 498 void SpdyProxyClientSocket::OnClose(int status) { |
494 was_ever_used_ = spdy_stream_->WasEverUsed(); | 499 was_ever_used_ = spdy_stream_->WasEverUsed(); |
495 spdy_stream_.reset(); | 500 spdy_stream_.reset(); |
496 | 501 |
497 bool connecting = next_state_ != STATE_DISCONNECTED && | 502 bool connecting = |
498 next_state_ < STATE_OPEN; | 503 next_state_ != STATE_DISCONNECTED && next_state_ < STATE_OPEN; |
499 if (next_state_ == STATE_OPEN) | 504 if (next_state_ == STATE_OPEN) |
500 next_state_ = STATE_CLOSED; | 505 next_state_ = STATE_CLOSED; |
501 else | 506 else |
502 next_state_ = STATE_DISCONNECTED; | 507 next_state_ = STATE_DISCONNECTED; |
503 | 508 |
504 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 509 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
505 CompletionCallback write_callback = write_callback_; | 510 CompletionCallback write_callback = write_callback_; |
506 write_callback_.Reset(); | 511 write_callback_.Reset(); |
507 write_buffer_len_ = 0; | 512 write_buffer_len_ = 0; |
508 | 513 |
509 // If we're in the middle of connecting, we need to make sure | 514 // If we're in the middle of connecting, we need to make sure |
510 // we invoke the connect callback. | 515 // we invoke the connect callback. |
511 if (connecting) { | 516 if (connecting) { |
512 DCHECK(!read_callback_.is_null()); | 517 DCHECK(!read_callback_.is_null()); |
513 CompletionCallback read_callback = read_callback_; | 518 CompletionCallback read_callback = read_callback_; |
514 read_callback_.Reset(); | 519 read_callback_.Reset(); |
515 read_callback.Run(status); | 520 read_callback.Run(status); |
516 } else if (!read_callback_.is_null()) { | 521 } else if (!read_callback_.is_null()) { |
517 // If we have a read_callback_, the we need to make sure we call it back. | 522 // If we have a read_callback_, the we need to make sure we call it back. |
518 OnDataReceived(scoped_ptr<SpdyBuffer>()); | 523 OnDataReceived(scoped_ptr<SpdyBuffer>()); |
519 } | 524 } |
520 // This may have been deleted by read_callback_, so check first. | 525 // This may have been deleted by read_callback_, so check first. |
521 if (weak_ptr.get() && !write_callback.is_null()) | 526 if (weak_ptr.get() && !write_callback.is_null()) |
522 write_callback.Run(ERR_CONNECTION_CLOSED); | 527 write_callback.Run(ERR_CONNECTION_CLOSED); |
523 } | 528 } |
524 | 529 |
525 } // namespace net | 530 } // namespace net |
OLD | NEW |