OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 const std::string& user_agent, | 26 const std::string& user_agent, |
27 const HostPortPair& endpoint, | 27 const HostPortPair& endpoint, |
28 const GURL& url, | 28 const GURL& url, |
29 const HostPortPair& proxy_server, | 29 const HostPortPair& proxy_server, |
30 HttpAuthCache* auth_cache, | 30 HttpAuthCache* auth_cache, |
31 HttpAuthHandlerFactory* auth_handler_factory) | 31 HttpAuthHandlerFactory* auth_handler_factory) |
32 : ALLOW_THIS_IN_INITIALIZER_LIST( | 32 : ALLOW_THIS_IN_INITIALIZER_LIST( |
33 io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)), | 33 io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)), |
34 next_state_(STATE_DISCONNECTED), | 34 next_state_(STATE_DISCONNECTED), |
35 spdy_stream_(spdy_stream), | 35 spdy_stream_(spdy_stream), |
36 read_callback_(NULL), | 36 old_read_callback_(NULL), |
37 write_callback_(NULL), | 37 write_callback_(NULL), |
38 endpoint_(endpoint), | 38 endpoint_(endpoint), |
39 auth_( | 39 auth_( |
40 new HttpAuthController(HttpAuth::AUTH_PROXY, | 40 new HttpAuthController(HttpAuth::AUTH_PROXY, |
41 GURL("https://" + proxy_server.ToString()), | 41 GURL("https://" + proxy_server.ToString()), |
42 auth_cache, | 42 auth_cache, |
43 auth_handler_factory)), | 43 auth_handler_factory)), |
44 user_buffer_(NULL), | 44 user_buffer_(NULL), |
45 write_buffer_len_(0), | 45 write_buffer_len_(0), |
46 write_bytes_outstanding_(0), | 46 write_bytes_outstanding_(0), |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 // for the specified endpoint. Waits for the server to send back | 85 // for the specified endpoint. Waits for the server to send back |
86 // a SYN_REPLY frame. OK will be returned if the status is 200. | 86 // a SYN_REPLY frame. OK will be returned if the status is 200. |
87 // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. | 87 // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. |
88 // In any of these cases, Read() may be called to retrieve the HTTP | 88 // In any of these cases, Read() may be called to retrieve the HTTP |
89 // response body. Any other return values should be considered fatal. | 89 // response body. Any other return values should be considered fatal. |
90 // TODO(rch): handle 407 proxy auth requested correctly, perhaps | 90 // TODO(rch): handle 407 proxy auth requested correctly, perhaps |
91 // by creating a new stream for the subsequent request. | 91 // by creating a new stream for the subsequent request. |
92 // TODO(rch): create a more appropriate error code to disambiguate | 92 // TODO(rch): create a more appropriate error code to disambiguate |
93 // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. | 93 // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. |
94 int SpdyProxyClientSocket::Connect(OldCompletionCallback* callback) { | 94 int SpdyProxyClientSocket::Connect(OldCompletionCallback* callback) { |
95 DCHECK(!read_callback_); | 95 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
96 if (next_state_ == STATE_OPEN) | 96 if (next_state_ == STATE_OPEN) |
97 return OK; | 97 return OK; |
98 | 98 |
| 99 DCHECK_EQ(STATE_DISCONNECTED, next_state_); |
| 100 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 101 |
| 102 int rv = DoLoop(OK); |
| 103 if (rv == ERR_IO_PENDING) |
| 104 old_read_callback_ = callback; |
| 105 return rv; |
| 106 } |
| 107 int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { |
| 108 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 109 if (next_state_ == STATE_OPEN) |
| 110 return OK; |
| 111 |
99 DCHECK_EQ(STATE_DISCONNECTED, next_state_); | 112 DCHECK_EQ(STATE_DISCONNECTED, next_state_); |
100 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 113 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
101 | 114 |
102 int rv = DoLoop(OK); | 115 int rv = DoLoop(OK); |
103 if (rv == ERR_IO_PENDING) | 116 if (rv == ERR_IO_PENDING) |
104 read_callback_ = callback; | 117 read_callback_ = callback; |
105 return rv; | 118 return rv; |
106 } | 119 } |
107 | 120 |
108 void SpdyProxyClientSocket::Disconnect() { | 121 void SpdyProxyClientSocket::Disconnect() { |
109 read_buffer_.clear(); | 122 read_buffer_.clear(); |
110 user_buffer_ = NULL; | 123 user_buffer_ = NULL; |
111 read_callback_ = NULL; | 124 old_read_callback_ = NULL; |
| 125 read_callback_.Reset(); |
112 | 126 |
113 write_buffer_len_ = 0; | 127 write_buffer_len_ = 0; |
114 write_bytes_outstanding_ = 0; | 128 write_bytes_outstanding_ = 0; |
115 write_callback_ = NULL; | 129 write_callback_ = NULL; |
116 | 130 |
117 next_state_ = STATE_DISCONNECTED; | 131 next_state_ = STATE_DISCONNECTED; |
118 | 132 |
119 if (spdy_stream_) | 133 if (spdy_stream_) |
120 // This will cause OnClose to be invoked, which takes care of | 134 // This will cause OnClose to be invoked, which takes care of |
121 // cleaning up all the internal state. | 135 // cleaning up all the internal state. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 int64 SpdyProxyClientSocket::NumBytesRead() const { | 167 int64 SpdyProxyClientSocket::NumBytesRead() const { |
154 return -1; | 168 return -1; |
155 } | 169 } |
156 | 170 |
157 base::TimeDelta SpdyProxyClientSocket::GetConnectTimeMicros() const { | 171 base::TimeDelta SpdyProxyClientSocket::GetConnectTimeMicros() const { |
158 return base::TimeDelta::FromMicroseconds(-1); | 172 return base::TimeDelta::FromMicroseconds(-1); |
159 } | 173 } |
160 | 174 |
161 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, | 175 int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, |
162 OldCompletionCallback* callback) { | 176 OldCompletionCallback* callback) { |
163 DCHECK(!read_callback_); | 177 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
164 DCHECK(!user_buffer_); | 178 DCHECK(!user_buffer_); |
165 | 179 |
166 if (next_state_ == STATE_DISCONNECTED) | 180 if (next_state_ == STATE_DISCONNECTED) |
167 return ERR_SOCKET_NOT_CONNECTED; | 181 return ERR_SOCKET_NOT_CONNECTED; |
168 | 182 |
169 if (next_state_ == STATE_CLOSED && read_buffer_.empty()) { | 183 if (next_state_ == STATE_CLOSED && read_buffer_.empty()) { |
170 return 0; | 184 return 0; |
171 } | 185 } |
172 | 186 |
173 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); | 187 DCHECK(next_state_ == STATE_OPEN || next_state_ == STATE_CLOSED); |
174 DCHECK(buf); | 188 DCHECK(buf); |
175 user_buffer_ = new DrainableIOBuffer(buf, buf_len); | 189 user_buffer_ = new DrainableIOBuffer(buf, buf_len); |
176 int result = PopulateUserReadBuffer(); | 190 int result = PopulateUserReadBuffer(); |
177 if (result == 0) { | 191 if (result == 0) { |
178 DCHECK(callback); | 192 DCHECK(callback); |
179 read_callback_ = callback; | 193 old_read_callback_ = callback; |
180 return ERR_IO_PENDING; | 194 return ERR_IO_PENDING; |
181 } | 195 } |
182 user_buffer_ = NULL; | 196 user_buffer_ = NULL; |
183 return result; | 197 return result; |
184 } | 198 } |
185 | 199 |
186 int SpdyProxyClientSocket::PopulateUserReadBuffer() { | 200 int SpdyProxyClientSocket::PopulateUserReadBuffer() { |
187 if (!user_buffer_) | 201 if (!user_buffer_) |
188 return ERR_IO_PENDING; | 202 return ERR_IO_PENDING; |
189 | 203 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const { | 278 int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const { |
265 if (!IsConnected()) | 279 if (!IsConnected()) |
266 return ERR_SOCKET_NOT_CONNECTED; | 280 return ERR_SOCKET_NOT_CONNECTED; |
267 return spdy_stream_->GetLocalAddress(address); | 281 return spdy_stream_->GetLocalAddress(address); |
268 } | 282 } |
269 | 283 |
270 void SpdyProxyClientSocket::OnIOComplete(int result) { | 284 void SpdyProxyClientSocket::OnIOComplete(int result) { |
271 DCHECK_NE(STATE_DISCONNECTED, next_state_); | 285 DCHECK_NE(STATE_DISCONNECTED, next_state_); |
272 int rv = DoLoop(result); | 286 int rv = DoLoop(result); |
273 if (rv != ERR_IO_PENDING) { | 287 if (rv != ERR_IO_PENDING) { |
274 OldCompletionCallback* c = read_callback_; | 288 if (old_read_callback_) { |
275 read_callback_ = NULL; | 289 OldCompletionCallback* c = old_read_callback_; |
276 c->Run(rv); | 290 old_read_callback_ = NULL; |
| 291 c->Run(rv); |
| 292 } else { |
| 293 CompletionCallback c = read_callback_; |
| 294 read_callback_.Reset(); |
| 295 c.Run(rv); |
| 296 } |
277 } | 297 } |
278 } | 298 } |
279 | 299 |
280 int SpdyProxyClientSocket::DoLoop(int last_io_result) { | 300 int SpdyProxyClientSocket::DoLoop(int last_io_result) { |
281 DCHECK_NE(next_state_, STATE_DISCONNECTED); | 301 DCHECK_NE(next_state_, STATE_DISCONNECTED); |
282 int rv = last_io_result; | 302 int rv = last_io_result; |
283 do { | 303 do { |
284 State state = next_state_; | 304 State state = next_state_; |
285 next_state_ = STATE_DISCONNECTED; | 305 next_state_ = STATE_DISCONNECTED; |
286 switch (state) { | 306 switch (state) { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 // Called when data is received. | 485 // Called when data is received. |
466 void SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { | 486 void SpdyProxyClientSocket::OnDataReceived(const char* data, int length) { |
467 if (length > 0) { | 487 if (length > 0) { |
468 // Save the received data. | 488 // Save the received data. |
469 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length)); | 489 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(length)); |
470 memcpy(io_buffer->data(), data, length); | 490 memcpy(io_buffer->data(), data, length); |
471 read_buffer_.push_back( | 491 read_buffer_.push_back( |
472 make_scoped_refptr(new DrainableIOBuffer(io_buffer, length))); | 492 make_scoped_refptr(new DrainableIOBuffer(io_buffer, length))); |
473 } | 493 } |
474 | 494 |
475 if (read_callback_) { | 495 if (old_read_callback_) { |
476 int rv = PopulateUserReadBuffer(); | 496 int rv = PopulateUserReadBuffer(); |
477 OldCompletionCallback* c = read_callback_; | 497 OldCompletionCallback* c = old_read_callback_; |
478 read_callback_ = NULL; | 498 old_read_callback_ = NULL; |
479 user_buffer_ = NULL; | 499 user_buffer_ = NULL; |
480 c->Run(rv); | 500 c->Run(rv); |
| 501 } else if (!read_callback_.is_null()) { |
| 502 int rv = PopulateUserReadBuffer(); |
| 503 CompletionCallback c = read_callback_; |
| 504 read_callback_.Reset(); |
| 505 user_buffer_ = NULL; |
| 506 c.Run(rv); |
481 } | 507 } |
482 } | 508 } |
483 | 509 |
484 void SpdyProxyClientSocket::OnDataSent(int length) { | 510 void SpdyProxyClientSocket::OnDataSent(int length) { |
485 DCHECK(write_callback_); | 511 DCHECK(write_callback_); |
486 | 512 |
487 write_bytes_outstanding_ -= length; | 513 write_bytes_outstanding_ -= length; |
488 | 514 |
489 DCHECK_GE(write_bytes_outstanding_, 0); | 515 DCHECK_GE(write_bytes_outstanding_, 0); |
490 | 516 |
(...skipping 21 matching lines...) Expand all Loading... |
512 | 538 |
513 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); | 539 base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); |
514 OldCompletionCallback* write_callback = write_callback_; | 540 OldCompletionCallback* write_callback = write_callback_; |
515 write_callback_ = NULL; | 541 write_callback_ = NULL; |
516 write_buffer_len_ = 0; | 542 write_buffer_len_ = 0; |
517 write_bytes_outstanding_ = 0; | 543 write_bytes_outstanding_ = 0; |
518 | 544 |
519 // If we're in the middle of connecting, we need to make sure | 545 // If we're in the middle of connecting, we need to make sure |
520 // we invoke the connect callback. | 546 // we invoke the connect callback. |
521 if (connecting) { | 547 if (connecting) { |
522 DCHECK(read_callback_); | 548 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
523 OldCompletionCallback* read_callback = read_callback_; | 549 if (old_read_callback_) { |
524 read_callback_ = NULL; | 550 OldCompletionCallback* read_callback = old_read_callback_; |
525 read_callback->Run(status); | 551 old_read_callback_ = NULL; |
526 } else if (read_callback_) { | 552 read_callback->Run(status); |
| 553 } else { |
| 554 CompletionCallback read_callback = read_callback_; |
| 555 read_callback_.Reset(); |
| 556 read_callback.Run(status); |
| 557 } |
| 558 } else if (old_read_callback_ || !read_callback_.is_null()) { |
527 // If we have a read_callback_, the we need to make sure we call it back. | 559 // If we have a read_callback_, the we need to make sure we call it back. |
528 OnDataReceived(NULL, 0); | 560 OnDataReceived(NULL, 0); |
529 } | 561 } |
530 // This may have been deleted by read_callback_, so check first. | 562 // This may have been deleted by read_callback_, so check first. |
531 if (weak_ptr && write_callback) | 563 if (weak_ptr && write_callback) |
532 write_callback->Run(ERR_CONNECTION_CLOSED); | 564 write_callback->Run(ERR_CONNECTION_CLOSED); |
533 } | 565 } |
534 | 566 |
535 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { | 567 void SpdyProxyClientSocket::set_chunk_callback(ChunkCallback* /*callback*/) { |
536 } | 568 } |
537 | 569 |
538 } // namespace net | 570 } // namespace net |
OLD | NEW |