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/ftp/ftp_network_transaction.h" | 5 #include "net/ftp/ftp_network_transaction.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 199 |
200 } // namespace | 200 } // namespace |
201 | 201 |
202 namespace net { | 202 namespace net { |
203 | 203 |
204 FtpNetworkTransaction::FtpNetworkTransaction( | 204 FtpNetworkTransaction::FtpNetworkTransaction( |
205 FtpNetworkSession* session, | 205 FtpNetworkSession* session, |
206 ClientSocketFactory* socket_factory) | 206 ClientSocketFactory* socket_factory) |
207 : command_sent_(COMMAND_NONE), | 207 : command_sent_(COMMAND_NONE), |
208 ALLOW_THIS_IN_INITIALIZER_LIST( | 208 ALLOW_THIS_IN_INITIALIZER_LIST( |
209 io_callback_(this, &FtpNetworkTransaction::OnIOComplete)), | 209 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, |
210 user_callback_(NULL), | 210 base::Unretained(this)))), |
211 session_(session), | 211 session_(session), |
212 request_(NULL), | 212 request_(NULL), |
213 resolver_(session->host_resolver()), | 213 resolver_(session->host_resolver()), |
214 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), | 214 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), |
215 ctrl_response_buffer_(new FtpCtrlResponseBuffer()), | 215 ctrl_response_buffer_(new FtpCtrlResponseBuffer()), |
216 read_data_buf_len_(0), | 216 read_data_buf_len_(0), |
217 last_error_(OK), | 217 last_error_(OK), |
218 system_type_(SYSTEM_TYPE_UNKNOWN), | 218 system_type_(SYSTEM_TYPE_UNKNOWN), |
219 // Use image (binary) transfer by default. It should always work, | 219 // Use image (binary) transfer by default. It should always work, |
220 // whereas the ascii transfer may damage binary data. | 220 // whereas the ascii transfer may damage binary data. |
(...skipping 11 matching lines...) Expand all Loading... |
232 int FtpNetworkTransaction::Stop(int error) { | 232 int FtpNetworkTransaction::Stop(int error) { |
233 if (command_sent_ == COMMAND_QUIT) | 233 if (command_sent_ == COMMAND_QUIT) |
234 return error; | 234 return error; |
235 | 235 |
236 next_state_ = STATE_CTRL_WRITE_QUIT; | 236 next_state_ = STATE_CTRL_WRITE_QUIT; |
237 last_error_ = error; | 237 last_error_ = error; |
238 return OK; | 238 return OK; |
239 } | 239 } |
240 | 240 |
241 int FtpNetworkTransaction::RestartIgnoringLastError( | 241 int FtpNetworkTransaction::RestartIgnoringLastError( |
242 OldCompletionCallback* callback) { | 242 const CompletionCallback& callback) { |
243 return ERR_NOT_IMPLEMENTED; | 243 return ERR_NOT_IMPLEMENTED; |
244 } | 244 } |
245 | 245 |
246 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, | 246 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, |
247 OldCompletionCallback* callback, | 247 const CompletionCallback& callback, |
248 const BoundNetLog& net_log) { | 248 const BoundNetLog& net_log) { |
249 net_log_ = net_log; | 249 net_log_ = net_log; |
250 request_ = request_info; | 250 request_ = request_info; |
251 | 251 |
252 if (request_->url.has_username()) { | 252 if (request_->url.has_username()) { |
253 string16 username; | 253 string16 username; |
254 string16 password; | 254 string16 password; |
255 GetIdentityFromURL(request_->url, &username, &password); | 255 GetIdentityFromURL(request_->url, &username, &password); |
256 credentials_.Set(username, password); | 256 credentials_.Set(username, password); |
257 } else { | 257 } else { |
258 credentials_.Set(ASCIIToUTF16("anonymous"), | 258 credentials_.Set(ASCIIToUTF16("anonymous"), |
259 ASCIIToUTF16("chrome@example.com")); | 259 ASCIIToUTF16("chrome@example.com")); |
260 } | 260 } |
261 | 261 |
262 DetectTypecode(); | 262 DetectTypecode(); |
263 | 263 |
264 next_state_ = STATE_CTRL_RESOLVE_HOST; | 264 next_state_ = STATE_CTRL_RESOLVE_HOST; |
265 int rv = DoLoop(OK); | 265 int rv = DoLoop(OK); |
266 if (rv == ERR_IO_PENDING) | 266 if (rv == ERR_IO_PENDING) |
267 user_callback_ = callback; | 267 user_callback_ = callback; |
268 return rv; | 268 return rv; |
269 } | 269 } |
270 | 270 |
271 int FtpNetworkTransaction::RestartWithAuth(const AuthCredentials& credentials, | 271 int FtpNetworkTransaction::RestartWithAuth(const AuthCredentials& credentials, |
272 OldCompletionCallback* callback) { | 272 const CompletionCallback& callback) { |
273 ResetStateForRestart(); | 273 ResetStateForRestart(); |
274 | 274 |
275 credentials_ = credentials; | 275 credentials_ = credentials; |
276 | 276 |
277 next_state_ = STATE_CTRL_RESOLVE_HOST; | 277 next_state_ = STATE_CTRL_RESOLVE_HOST; |
278 int rv = DoLoop(OK); | 278 int rv = DoLoop(OK); |
279 if (rv == ERR_IO_PENDING) | 279 if (rv == ERR_IO_PENDING) |
280 user_callback_ = callback; | 280 user_callback_ = callback; |
281 return rv; | 281 return rv; |
282 } | 282 } |
283 | 283 |
284 int FtpNetworkTransaction::Read(IOBuffer* buf, | 284 int FtpNetworkTransaction::Read(IOBuffer* buf, |
285 int buf_len, | 285 int buf_len, |
286 OldCompletionCallback* callback) { | 286 const CompletionCallback& callback) { |
287 DCHECK(buf); | 287 DCHECK(buf); |
288 DCHECK_GT(buf_len, 0); | 288 DCHECK_GT(buf_len, 0); |
289 | 289 |
290 read_data_buf_ = buf; | 290 read_data_buf_ = buf; |
291 read_data_buf_len_ = buf_len; | 291 read_data_buf_len_ = buf_len; |
292 | 292 |
293 next_state_ = STATE_DATA_READ; | 293 next_state_ = STATE_DATA_READ; |
294 int rv = DoLoop(OK); | 294 int rv = DoLoop(OK); |
295 if (rv == ERR_IO_PENDING) | 295 if (rv == ERR_IO_PENDING) |
296 user_callback_ = callback; | 296 user_callback_ = callback; |
(...skipping 26 matching lines...) Expand all Loading... |
323 | 323 |
324 return LOAD_STATE_IDLE; | 324 return LOAD_STATE_IDLE; |
325 } | 325 } |
326 | 326 |
327 uint64 FtpNetworkTransaction::GetUploadProgress() const { | 327 uint64 FtpNetworkTransaction::GetUploadProgress() const { |
328 return 0; | 328 return 0; |
329 } | 329 } |
330 | 330 |
331 void FtpNetworkTransaction::ResetStateForRestart() { | 331 void FtpNetworkTransaction::ResetStateForRestart() { |
332 command_sent_ = COMMAND_NONE; | 332 command_sent_ = COMMAND_NONE; |
333 user_callback_ = NULL; | 333 user_callback_.Reset(); |
334 response_ = FtpResponseInfo(); | 334 response_ = FtpResponseInfo(); |
335 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); | 335 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); |
336 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer()); | 336 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer()); |
337 read_data_buf_ = NULL; | 337 read_data_buf_ = NULL; |
338 read_data_buf_len_ = 0; | 338 read_data_buf_len_ = 0; |
339 if (write_buf_) | 339 if (write_buf_) |
340 write_buf_->SetOffset(0); | 340 write_buf_->SetOffset(0); |
341 last_error_ = OK; | 341 last_error_ = OK; |
342 data_connection_port_ = 0; | 342 data_connection_port_ = 0; |
343 ctrl_socket_.reset(); | 343 ctrl_socket_.reset(); |
344 data_socket_.reset(); | 344 data_socket_.reset(); |
345 next_state_ = STATE_NONE; | 345 next_state_ = STATE_NONE; |
346 } | 346 } |
347 | 347 |
348 void FtpNetworkTransaction::DoCallback(int rv) { | 348 void FtpNetworkTransaction::DoCallback(int rv) { |
349 DCHECK(rv != ERR_IO_PENDING); | 349 DCHECK(rv != ERR_IO_PENDING); |
350 DCHECK(user_callback_); | 350 DCHECK(!user_callback_.is_null()); |
351 | 351 |
352 // Since Run may result in Read being called, clear callback_ up front. | 352 // Since Run may result in Read being called, clear callback_ up front. |
353 OldCompletionCallback* c = user_callback_; | 353 CompletionCallback c = user_callback_; |
354 user_callback_ = NULL; | 354 user_callback_.Reset(); |
355 c->Run(rv); | 355 c.Run(rv); |
356 } | 356 } |
357 | 357 |
358 void FtpNetworkTransaction::OnIOComplete(int result) { | 358 void FtpNetworkTransaction::OnIOComplete(int result) { |
359 int rv = DoLoop(result); | 359 int rv = DoLoop(result); |
360 if (rv != ERR_IO_PENDING) | 360 if (rv != ERR_IO_PENDING) |
361 DoCallback(rv); | 361 DoCallback(rv); |
362 } | 362 } |
363 | 363 |
364 int FtpNetworkTransaction::ProcessCtrlResponse() { | 364 int FtpNetworkTransaction::ProcessCtrlResponse() { |
365 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse(); | 365 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse(); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { | 638 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { |
639 if (result == OK) | 639 if (result == OK) |
640 next_state_ = STATE_CTRL_CONNECT; | 640 next_state_ = STATE_CTRL_CONNECT; |
641 return result; | 641 return result; |
642 } | 642 } |
643 | 643 |
644 int FtpNetworkTransaction::DoCtrlConnect() { | 644 int FtpNetworkTransaction::DoCtrlConnect() { |
645 next_state_ = STATE_CTRL_CONNECT_COMPLETE; | 645 next_state_ = STATE_CTRL_CONNECT_COMPLETE; |
646 ctrl_socket_.reset(socket_factory_->CreateTransportClientSocket( | 646 ctrl_socket_.reset(socket_factory_->CreateTransportClientSocket( |
647 addresses_, net_log_.net_log(), net_log_.source())); | 647 addresses_, net_log_.net_log(), net_log_.source())); |
648 return ctrl_socket_->Connect(&io_callback_); | 648 return ctrl_socket_->Connect(io_callback_); |
649 } | 649 } |
650 | 650 |
651 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { | 651 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { |
652 if (result == OK) { | 652 if (result == OK) { |
653 // Put the peer's IP address and port into the response. | 653 // Put the peer's IP address and port into the response. |
654 AddressList address; | 654 AddressList address; |
655 result = ctrl_socket_->GetPeerAddress(&address); | 655 result = ctrl_socket_->GetPeerAddress(&address); |
656 if (result == OK) { | 656 if (result == OK) { |
657 response_.socket_address = HostPortPair::FromAddrInfo(address.head()); | 657 response_.socket_address = HostPortPair::FromAddrInfo(address.head()); |
658 next_state_ = STATE_CTRL_READ; | 658 next_state_ = STATE_CTRL_READ; |
659 } | 659 } |
660 } | 660 } |
661 return result; | 661 return result; |
662 } | 662 } |
663 | 663 |
664 int FtpNetworkTransaction::DoCtrlRead() { | 664 int FtpNetworkTransaction::DoCtrlRead() { |
665 next_state_ = STATE_CTRL_READ_COMPLETE; | 665 next_state_ = STATE_CTRL_READ_COMPLETE; |
666 return ctrl_socket_->Read( | 666 return ctrl_socket_->Read(read_ctrl_buf_, kCtrlBufLen, io_callback_); |
667 read_ctrl_buf_, | |
668 kCtrlBufLen, | |
669 &io_callback_); | |
670 } | 667 } |
671 | 668 |
672 int FtpNetworkTransaction::DoCtrlReadComplete(int result) { | 669 int FtpNetworkTransaction::DoCtrlReadComplete(int result) { |
673 if (result == 0) { | 670 if (result == 0) { |
674 // Some servers (for example Pure-FTPd) apparently close the control | 671 // Some servers (for example Pure-FTPd) apparently close the control |
675 // connection when anonymous login is not permitted. For more details | 672 // connection when anonymous login is not permitted. For more details |
676 // see http://crbug.com/25023. | 673 // see http://crbug.com/25023. |
677 if (command_sent_ == COMMAND_USER && | 674 if (command_sent_ == COMMAND_USER && |
678 credentials_.username() == ASCIIToUTF16("anonymous")) { | 675 credentials_.username() == ASCIIToUTF16("anonymous")) { |
679 response_.needs_auth = true; | 676 response_.needs_auth = true; |
(...skipping 12 matching lines...) Expand all Loading... |
692 } | 689 } |
693 | 690 |
694 return ProcessCtrlResponse(); | 691 return ProcessCtrlResponse(); |
695 } | 692 } |
696 | 693 |
697 int FtpNetworkTransaction::DoCtrlWrite() { | 694 int FtpNetworkTransaction::DoCtrlWrite() { |
698 next_state_ = STATE_CTRL_WRITE_COMPLETE; | 695 next_state_ = STATE_CTRL_WRITE_COMPLETE; |
699 | 696 |
700 return ctrl_socket_->Write(write_buf_, | 697 return ctrl_socket_->Write(write_buf_, |
701 write_buf_->BytesRemaining(), | 698 write_buf_->BytesRemaining(), |
702 &io_callback_); | 699 io_callback_); |
703 } | 700 } |
704 | 701 |
705 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { | 702 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { |
706 if (result < 0) | 703 if (result < 0) |
707 return result; | 704 return result; |
708 | 705 |
709 write_buf_->DidConsume(result); | 706 write_buf_->DidConsume(result); |
710 if (write_buf_->BytesRemaining() == 0) { | 707 if (write_buf_->BytesRemaining() == 0) { |
711 // Clear the write buffer. | 708 // Clear the write buffer. |
712 write_buf_ = NULL; | 709 write_buf_ = NULL; |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 next_state_ = STATE_DATA_CONNECT_COMPLETE; | 1190 next_state_ = STATE_DATA_CONNECT_COMPLETE; |
1194 AddressList data_address; | 1191 AddressList data_address; |
1195 // Connect to the same host as the control socket to prevent PASV port | 1192 // Connect to the same host as the control socket to prevent PASV port |
1196 // scanning attacks. | 1193 // scanning attacks. |
1197 int rv = ctrl_socket_->GetPeerAddress(&data_address); | 1194 int rv = ctrl_socket_->GetPeerAddress(&data_address); |
1198 if (rv != OK) | 1195 if (rv != OK) |
1199 return Stop(rv); | 1196 return Stop(rv); |
1200 data_address.SetPort(data_connection_port_); | 1197 data_address.SetPort(data_connection_port_); |
1201 data_socket_.reset(socket_factory_->CreateTransportClientSocket( | 1198 data_socket_.reset(socket_factory_->CreateTransportClientSocket( |
1202 data_address, net_log_.net_log(), net_log_.source())); | 1199 data_address, net_log_.net_log(), net_log_.source())); |
1203 return data_socket_->Connect(&io_callback_); | 1200 return data_socket_->Connect(io_callback_); |
1204 } | 1201 } |
1205 | 1202 |
1206 int FtpNetworkTransaction::DoDataConnectComplete(int result) { | 1203 int FtpNetworkTransaction::DoDataConnectComplete(int result) { |
1207 if (result != OK && use_epsv_) { | 1204 if (result != OK && use_epsv_) { |
1208 // It's possible we hit a broken server, sadly. They can break in different | 1205 // It's possible we hit a broken server, sadly. They can break in different |
1209 // ways. Some time out, some reset a connection. Fall back to PASV. | 1206 // ways. Some time out, some reset a connection. Fall back to PASV. |
1210 // TODO(phajdan.jr): remember it for future transactions with this server. | 1207 // TODO(phajdan.jr): remember it for future transactions with this server. |
1211 // TODO(phajdan.jr): write a test for this code path. | 1208 // TODO(phajdan.jr): write a test for this code path. |
1212 use_epsv_ = false; | 1209 use_epsv_ = false; |
1213 next_state_ = STATE_CTRL_WRITE_PASV; | 1210 next_state_ = STATE_CTRL_WRITE_PASV; |
(...skipping 26 matching lines...) Expand all Loading... |
1240 next_state_ = STATE_CTRL_READ; | 1237 next_state_ = STATE_CTRL_READ; |
1241 return OK; | 1238 return OK; |
1242 } | 1239 } |
1243 | 1240 |
1244 // We are no longer connected to the server, so just finish the transaction. | 1241 // We are no longer connected to the server, so just finish the transaction. |
1245 return Stop(OK); | 1242 return Stop(OK); |
1246 } | 1243 } |
1247 | 1244 |
1248 next_state_ = STATE_DATA_READ_COMPLETE; | 1245 next_state_ = STATE_DATA_READ_COMPLETE; |
1249 read_data_buf_->data()[0] = 0; | 1246 read_data_buf_->data()[0] = 0; |
1250 return data_socket_->Read(read_data_buf_, read_data_buf_len_, | 1247 return data_socket_->Read(read_data_buf_, read_data_buf_len_, io_callback_); |
1251 &io_callback_); | |
1252 } | 1248 } |
1253 | 1249 |
1254 int FtpNetworkTransaction::DoDataReadComplete(int result) { | 1250 int FtpNetworkTransaction::DoDataReadComplete(int result) { |
1255 return result; | 1251 return result; |
1256 } | 1252 } |
1257 | 1253 |
1258 // We're using a histogram as a group of counters, with one bucket for each | 1254 // We're using a histogram as a group of counters, with one bucket for each |
1259 // enumeration value. We're only interested in the values of the counters. | 1255 // enumeration value. We're only interested in the values of the counters. |
1260 // Ignore the shape, average, and standard deviation of the histograms because | 1256 // Ignore the shape, average, and standard deviation of the histograms because |
1261 // they are meaningless. | 1257 // they are meaningless. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 if (!had_error_type[type]) { | 1333 if (!had_error_type[type]) { |
1338 had_error_type[type] = true; | 1334 had_error_type[type] = true; |
1339 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1335 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
1340 type, NUM_OF_NET_ERROR_TYPES); | 1336 type, NUM_OF_NET_ERROR_TYPES); |
1341 } | 1337 } |
1342 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1338 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
1343 type, NUM_OF_NET_ERROR_TYPES); | 1339 type, NUM_OF_NET_ERROR_TYPES); |
1344 } | 1340 } |
1345 | 1341 |
1346 } // namespace net | 1342 } // namespace net |
OLD | NEW |