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/url_request/url_request_ftp_job.h" | 5 #include "net/url_request/url_request_ftp_job.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "net/base/auth.h" | 10 #include "net/base/auth.h" |
11 #include "net/base/host_port_pair.h" | 11 #include "net/base/host_port_pair.h" |
12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
13 #include "net/base/net_util.h" | 13 #include "net/base/net_util.h" |
14 #include "net/ftp/ftp_response_info.h" | 14 #include "net/ftp/ftp_response_info.h" |
15 #include "net/ftp/ftp_transaction_factory.h" | 15 #include "net/ftp/ftp_transaction_factory.h" |
16 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
17 #include "net/url_request/url_request_context.h" | 17 #include "net/url_request/url_request_context.h" |
18 #include "net/url_request/url_request_error_job.h" | 18 #include "net/url_request/url_request_error_job.h" |
19 | 19 |
20 namespace net { | 20 namespace net { |
21 | 21 |
22 URLRequestFtpJob::URLRequestFtpJob(URLRequest* request) | 22 URLRequestFtpJob::URLRequestFtpJob(URLRequest* request) |
23 : URLRequestJob(request), | 23 : URLRequestJob(request), |
24 ALLOW_THIS_IN_INITIALIZER_LIST( | |
25 start_callback_(this, &URLRequestFtpJob::OnStartCompleted)), | |
26 ALLOW_THIS_IN_INITIALIZER_LIST( | |
27 read_callback_(this, &URLRequestFtpJob::OnReadCompleted)), | |
28 read_in_progress_(false), | 24 read_in_progress_(false), |
29 context_(request->context()), | 25 context_(request->context()), |
30 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 26 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
31 } | 27 } |
32 | 28 |
33 // static | 29 // static |
34 URLRequestJob* URLRequestFtpJob::Factory(URLRequest* request, | 30 URLRequestJob* URLRequestFtpJob::Factory(URLRequest* request, |
35 const std::string& scheme) { | 31 const std::string& scheme) { |
36 DCHECK_EQ(scheme, "ftp"); | 32 DCHECK_EQ(scheme, "ftp"); |
37 | 33 |
38 int port = request->url().IntPort(); | 34 int port = request->url().IntPort(); |
39 if (request->url().has_port() && | 35 if (request->url().has_port() && |
40 !IsPortAllowedByFtp(port) && !IsPortAllowedByOverride(port)) | 36 !IsPortAllowedByFtp(port) && !IsPortAllowedByOverride(port)) |
(...skipping 30 matching lines...) Expand all Loading... |
71 | 67 |
72 transaction_.reset( | 68 transaction_.reset( |
73 request_->context()->ftp_transaction_factory()->CreateTransaction()); | 69 request_->context()->ftp_transaction_factory()->CreateTransaction()); |
74 | 70 |
75 // No matter what, we want to report our status as IO pending since we will | 71 // No matter what, we want to report our status as IO pending since we will |
76 // be notifying our consumer asynchronously via OnStartCompleted. | 72 // be notifying our consumer asynchronously via OnStartCompleted. |
77 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 73 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
78 int rv; | 74 int rv; |
79 if (transaction_.get()) { | 75 if (transaction_.get()) { |
80 rv = transaction_->Start( | 76 rv = transaction_->Start( |
81 &request_info_, &start_callback_, request_->net_log()); | 77 &request_info_, |
| 78 base::Bind(&URLRequestFtpJob::OnStartCompleted, |
| 79 base::Unretained(this)), |
| 80 request_->net_log()); |
82 if (rv == ERR_IO_PENDING) | 81 if (rv == ERR_IO_PENDING) |
83 return; | 82 return; |
84 } else { | 83 } else { |
85 rv = ERR_FAILED; | 84 rv = ERR_FAILED; |
86 } | 85 } |
87 // The transaction started synchronously, but we need to notify the | 86 // The transaction started synchronously, but we need to notify the |
88 // URLRequest delegate via the message loop. | 87 // URLRequest delegate via the message loop. |
89 MessageLoop::current()->PostTask( | 88 MessageLoop::current()->PostTask( |
90 FROM_HERE, | 89 FROM_HERE, |
91 method_factory_.NewRunnableMethod( | 90 base::Bind(&URLRequestFtpJob::OnStartCompleted, |
92 &URLRequestFtpJob::OnStartCompleted, rv)); | 91 weak_factory_.GetWeakPtr(), rv)); |
93 } | 92 } |
94 | 93 |
95 void URLRequestFtpJob::OnStartCompleted(int result) { | 94 void URLRequestFtpJob::OnStartCompleted(int result) { |
96 // Clear the IO_PENDING status | 95 // Clear the IO_PENDING status |
97 SetStatus(URLRequestStatus()); | 96 SetStatus(URLRequestStatus()); |
98 | 97 |
99 // FTP obviously doesn't have HTTP Content-Length header. We have to pass | 98 // FTP obviously doesn't have HTTP Content-Length header. We have to pass |
100 // the content size information manually. | 99 // the content size information manually. |
101 set_expected_content_size( | 100 set_expected_content_size( |
102 transaction_->GetResponseInfo()->expected_content_size); | 101 transaction_->GetResponseInfo()->expected_content_size); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 NotifyReadComplete(result); | 140 NotifyReadComplete(result); |
142 } | 141 } |
143 | 142 |
144 void URLRequestFtpJob::RestartTransactionWithAuth() { | 143 void URLRequestFtpJob::RestartTransactionWithAuth() { |
145 DCHECK(server_auth_ && server_auth_->state == AUTH_STATE_HAVE_AUTH); | 144 DCHECK(server_auth_ && server_auth_->state == AUTH_STATE_HAVE_AUTH); |
146 | 145 |
147 // No matter what, we want to report our status as IO pending since we will | 146 // No matter what, we want to report our status as IO pending since we will |
148 // be notifying our consumer asynchronously via OnStartCompleted. | 147 // be notifying our consumer asynchronously via OnStartCompleted. |
149 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 148 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
150 | 149 |
151 int rv = transaction_->RestartWithAuth(server_auth_->credentials, | 150 int rv = transaction_->RestartWithAuth( |
152 &start_callback_); | 151 server_auth_->credentials, |
| 152 base::Bind(&URLRequestFtpJob::OnStartCompleted, |
| 153 base::Unretained(this))); |
153 if (rv == ERR_IO_PENDING) | 154 if (rv == ERR_IO_PENDING) |
154 return; | 155 return; |
155 | 156 |
156 MessageLoop::current()->PostTask( | 157 MessageLoop::current()->PostTask( |
157 FROM_HERE, | 158 FROM_HERE, |
158 method_factory_.NewRunnableMethod( | 159 base::Bind(&URLRequestFtpJob::OnStartCompleted, |
159 &URLRequestFtpJob::OnStartCompleted, rv)); | 160 weak_factory_.GetWeakPtr(), rv)); |
160 } | 161 } |
161 | 162 |
162 void URLRequestFtpJob::Start() { | 163 void URLRequestFtpJob::Start() { |
163 DCHECK(!transaction_.get()); | 164 DCHECK(!transaction_.get()); |
164 request_info_.url = request_->url(); | 165 request_info_.url = request_->url(); |
165 StartTransaction(); | 166 StartTransaction(); |
166 } | 167 } |
167 | 168 |
168 void URLRequestFtpJob::Kill() { | 169 void URLRequestFtpJob::Kill() { |
169 if (!transaction_.get()) | 170 if (!transaction_.get()) |
170 return; | 171 return; |
171 transaction_.reset(); | 172 transaction_.reset(); |
172 URLRequestJob::Kill(); | 173 URLRequestJob::Kill(); |
173 method_factory_.RevokeAll(); | 174 weak_factory_.InvalidateWeakPtrs(); |
174 } | 175 } |
175 | 176 |
176 LoadState URLRequestFtpJob::GetLoadState() const { | 177 LoadState URLRequestFtpJob::GetLoadState() const { |
177 return transaction_.get() ? | 178 return transaction_.get() ? |
178 transaction_->GetLoadState() : LOAD_STATE_IDLE; | 179 transaction_->GetLoadState() : LOAD_STATE_IDLE; |
179 } | 180 } |
180 | 181 |
181 bool URLRequestFtpJob::NeedsAuth() { | 182 bool URLRequestFtpJob::NeedsAuth() { |
182 // Note that we only have to worry about cases where an actual FTP server | 183 // Note that we only have to worry about cases where an actual FTP server |
183 // requires auth (and not a proxy), because connecting to FTP via proxy | 184 // requires auth (and not a proxy), because connecting to FTP via proxy |
(...skipping 28 matching lines...) Expand all Loading... |
212 | 213 |
213 void URLRequestFtpJob::CancelAuth() { | 214 void URLRequestFtpJob::CancelAuth() { |
214 DCHECK(NeedsAuth()); | 215 DCHECK(NeedsAuth()); |
215 server_auth_->state = AUTH_STATE_CANCELED; | 216 server_auth_->state = AUTH_STATE_CANCELED; |
216 | 217 |
217 // Once the auth is cancelled, we proceed with the request as though | 218 // Once the auth is cancelled, we proceed with the request as though |
218 // there were no auth. Schedule this for later so that we don't cause | 219 // there were no auth. Schedule this for later so that we don't cause |
219 // any recursing into the caller as a result of this call. | 220 // any recursing into the caller as a result of this call. |
220 MessageLoop::current()->PostTask( | 221 MessageLoop::current()->PostTask( |
221 FROM_HERE, | 222 FROM_HERE, |
222 method_factory_.NewRunnableMethod( | 223 base::Bind(&URLRequestFtpJob::OnStartCompleted, |
223 &URLRequestFtpJob::OnStartCompleted, OK)); | 224 weak_factory_.GetWeakPtr(), OK)); |
224 } | 225 } |
225 | 226 |
226 uint64 URLRequestFtpJob::GetUploadProgress() const { | 227 uint64 URLRequestFtpJob::GetUploadProgress() const { |
227 return 0; | 228 return 0; |
228 } | 229 } |
229 | 230 |
230 bool URLRequestFtpJob::ReadRawData(IOBuffer* buf, | 231 bool URLRequestFtpJob::ReadRawData(IOBuffer* buf, |
231 int buf_size, | 232 int buf_size, |
232 int *bytes_read) { | 233 int *bytes_read) { |
233 DCHECK_NE(buf_size, 0); | 234 DCHECK_NE(buf_size, 0); |
234 DCHECK(bytes_read); | 235 DCHECK(bytes_read); |
235 DCHECK(!read_in_progress_); | 236 DCHECK(!read_in_progress_); |
236 | 237 |
237 int rv = transaction_->Read(buf, buf_size, &read_callback_); | 238 int rv = transaction_->Read(buf, buf_size, |
| 239 base::Bind(&URLRequestFtpJob::OnReadCompleted, |
| 240 base::Unretained(this))); |
238 if (rv >= 0) { | 241 if (rv >= 0) { |
239 *bytes_read = rv; | 242 *bytes_read = rv; |
240 return true; | 243 return true; |
241 } | 244 } |
242 | 245 |
243 if (rv == ERR_IO_PENDING) { | 246 if (rv == ERR_IO_PENDING) { |
244 read_in_progress_ = true; | 247 read_in_progress_ = true; |
245 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 248 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
246 } else { | 249 } else { |
247 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); | 250 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv)); |
248 } | 251 } |
249 return false; | 252 return false; |
250 } | 253 } |
251 | 254 |
252 } // namespace net | 255 } // namespace net |
OLD | NEW |