Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: net/ftp/ftp_network_transaction.cc

Issue 173270: Implement RestartWithAuth for NewFtpTransaction. (Closed)
Patch Set: win compile fixes Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // 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/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "net/base/connection_type_histograms.h" 9 #include "net/base/connection_type_histograms.h"
10 #include "net/base/load_log.h" 10 #include "net/base/load_log.h"
(...skipping 18 matching lines...) Expand all
29 FtpNetworkSession* session, 29 FtpNetworkSession* session,
30 ClientSocketFactory* socket_factory) 30 ClientSocketFactory* socket_factory)
31 : command_sent_(COMMAND_NONE), 31 : command_sent_(COMMAND_NONE),
32 ALLOW_THIS_IN_INITIALIZER_LIST( 32 ALLOW_THIS_IN_INITIALIZER_LIST(
33 io_callback_(this, &FtpNetworkTransaction::OnIOComplete)), 33 io_callback_(this, &FtpNetworkTransaction::OnIOComplete)),
34 user_callback_(NULL), 34 user_callback_(NULL),
35 session_(session), 35 session_(session),
36 request_(NULL), 36 request_(NULL),
37 resolver_(session->host_resolver()), 37 resolver_(session->host_resolver()),
38 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), 38 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)),
39 ctrl_response_buffer_(new FtpCtrlResponseBuffer()),
39 read_data_buf_len_(0), 40 read_data_buf_len_(0),
40 file_data_len_(0), 41 file_data_len_(0),
41 write_command_buf_written_(0), 42 write_command_buf_written_(0),
42 last_error_(OK), 43 last_error_(OK),
43 is_anonymous_(false),
44 retr_failed_(false), 44 retr_failed_(false),
45 data_connection_port_(0), 45 data_connection_port_(0),
46 socket_factory_(socket_factory), 46 socket_factory_(socket_factory),
47 next_state_(STATE_NONE) { 47 next_state_(STATE_NONE) {
48 } 48 }
49 49
50 FtpNetworkTransaction::~FtpNetworkTransaction() { 50 FtpNetworkTransaction::~FtpNetworkTransaction() {
51 } 51 }
52 52
53 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, 53 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
54 CompletionCallback* callback, 54 CompletionCallback* callback,
55 LoadLog* load_log) { 55 LoadLog* load_log) {
56 load_log_ = load_log; 56 load_log_ = load_log;
57 request_ = request_info; 57 request_ = request_info;
58 58
59 if (request_->url.has_username()) {
60 username_ = UTF8ToWide(request_->url.username());
wtc 2009/08/25 20:52:50 Please ask Darin and Brett whether the embedded us
eroman 2009/09/01 07:12:37 They definitely do need to be unescaped. See Http
61 if (request_->url.has_password())
eroman 2009/09/01 07:12:37 Don't actually need the guard, will just be empty
62 password_ = UTF8ToWide(request_->url.password());
63 else
wtc 2009/08/25 20:52:50 Do we need the "else" here? password_ is initiali
64 password_ = L"";
65 } else {
66 username_ = L"anonymous";
67 password_ = L"chrome@example.com";
68 }
69
59 next_state_ = STATE_CTRL_INIT; 70 next_state_ = STATE_CTRL_INIT;
60 int rv = DoLoop(OK); 71 int rv = DoLoop(OK);
61 if (rv == ERR_IO_PENDING) 72 if (rv == ERR_IO_PENDING)
62 user_callback_ = callback; 73 user_callback_ = callback;
63 return rv; 74 return rv;
64 } 75 }
65 76
66 int FtpNetworkTransaction::Stop(int error) { 77 int FtpNetworkTransaction::Stop(int error) {
67 if (command_sent_ == COMMAND_QUIT) 78 if (command_sent_ == COMMAND_QUIT)
68 return error; 79 return error;
69 80
70 next_state_ = STATE_CTRL_WRITE_QUIT; 81 next_state_ = STATE_CTRL_WRITE_QUIT;
71 last_error_ = error; 82 last_error_ = error;
72 return OK; 83 return OK;
73 } 84 }
74 85
75 int FtpNetworkTransaction::RestartWithAuth(const std::wstring& username, 86 int FtpNetworkTransaction::RestartWithAuth(const std::wstring& username,
76 const std::wstring& password, 87 const std::wstring& password,
77 CompletionCallback* callback) { 88 CompletionCallback* callback) {
78 return ERR_FAILED; 89 ResetStateForRestart();
90
91 username_ = username;
92 password_ = password;
93
94 next_state_ = STATE_CTRL_INIT;
95 int rv = DoLoop(OK);
96 if (rv == ERR_IO_PENDING)
97 user_callback_ = callback;
98 return rv;
79 } 99 }
80 100
81 int FtpNetworkTransaction::RestartIgnoringLastError( 101 int FtpNetworkTransaction::RestartIgnoringLastError(
82 CompletionCallback* callback) { 102 CompletionCallback* callback) {
83 return ERR_FAILED; 103 return ERR_FAILED;
84 } 104 }
85 105
86 int FtpNetworkTransaction::Read(IOBuffer* buf, 106 int FtpNetworkTransaction::Read(IOBuffer* buf,
87 int buf_len, 107 int buf_len,
88 CompletionCallback* callback) { 108 CompletionCallback* callback) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 uint64 FtpNetworkTransaction::GetUploadProgress() const { 147 uint64 FtpNetworkTransaction::GetUploadProgress() const {
128 return 0; 148 return 0;
129 } 149 }
130 150
131 // Used to prepare and send FTP command. 151 // Used to prepare and send FTP command.
132 int FtpNetworkTransaction::SendFtpCommand(const std::string& command, 152 int FtpNetworkTransaction::SendFtpCommand(const std::string& command,
133 Command cmd) { 153 Command cmd) {
134 // If we send a new command when we still have unprocessed responses 154 // If we send a new command when we still have unprocessed responses
135 // for previous commands, the response receiving code will have no way to know 155 // for previous commands, the response receiving code will have no way to know
136 // which responses are for which command. 156 // which responses are for which command.
137 DCHECK(!ctrl_response_buffer_.ResponseAvailable()); 157 DCHECK(!ctrl_response_buffer_->ResponseAvailable());
138 158
139 DCHECK(!write_command_buf_); 159 DCHECK(!write_command_buf_);
140 DCHECK(!write_buf_); 160 DCHECK(!write_buf_);
141 DLOG(INFO) << " >> " << command; 161 DLOG(INFO) << " >> " << command;
142 162
143 command_sent_ = cmd; 163 command_sent_ = cmd;
144 164
145 write_command_buf_ = new IOBufferWithSize(command.length() + 2); 165 write_command_buf_ = new IOBufferWithSize(command.length() + 2);
146 write_buf_ = new ReusedIOBuffer(write_command_buf_, 166 write_buf_ = new ReusedIOBuffer(write_command_buf_,
147 write_command_buf_->size()); 167 write_command_buf_->size());
(...skipping 21 matching lines...) Expand all
169 189
170 if (response_code >= 500 && response_code <= 599) 190 if (response_code >= 500 && response_code <= 599)
171 return ERROR_CLASS_PERMANENT_ERROR; 191 return ERROR_CLASS_PERMANENT_ERROR;
172 192
173 // We should not be called on invalid error codes. 193 // We should not be called on invalid error codes.
174 NOTREACHED(); 194 NOTREACHED();
175 return ERROR_CLASS_PERMANENT_ERROR; 195 return ERROR_CLASS_PERMANENT_ERROR;
176 } 196 }
177 197
178 int FtpNetworkTransaction::ProcessCtrlResponse() { 198 int FtpNetworkTransaction::ProcessCtrlResponse() {
179 FtpCtrlResponse response = ctrl_response_buffer_.PopResponse(); 199 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse();
180 200
181 int rv = OK; 201 int rv = OK;
182 switch (command_sent_) { 202 switch (command_sent_) {
183 case COMMAND_NONE: 203 case COMMAND_NONE:
184 // TODO(phajdan.jr): Check for errors in the welcome message. 204 // TODO(phajdan.jr): Check for errors in the welcome message.
185 next_state_ = STATE_CTRL_WRITE_USER; 205 next_state_ = STATE_CTRL_WRITE_USER;
186 break; 206 break;
187 case COMMAND_USER: 207 case COMMAND_USER:
188 rv = ProcessResponseUSER(response); 208 rv = ProcessResponseUSER(response);
189 break; 209 break;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 case COMMAND_QUIT: 243 case COMMAND_QUIT:
224 rv = ProcessResponseQUIT(response); 244 rv = ProcessResponseQUIT(response);
225 break; 245 break;
226 default: 246 default:
227 LOG(DFATAL) << "Unexpected value of command_sent_: " << command_sent_; 247 LOG(DFATAL) << "Unexpected value of command_sent_: " << command_sent_;
228 return ERR_UNEXPECTED; 248 return ERR_UNEXPECTED;
229 } 249 }
230 250
231 // We may get multiple responses for some commands, 251 // We may get multiple responses for some commands,
232 // see http://crbug.com/18036. 252 // see http://crbug.com/18036.
233 while (ctrl_response_buffer_.ResponseAvailable() && rv == OK) { 253 while (ctrl_response_buffer_->ResponseAvailable() && rv == OK) {
234 response = ctrl_response_buffer_.PopResponse(); 254 response = ctrl_response_buffer_->PopResponse();
235 255
236 switch (command_sent_) { 256 switch (command_sent_) {
237 case COMMAND_RETR: 257 case COMMAND_RETR:
238 rv = ProcessResponseRETR(response); 258 rv = ProcessResponseRETR(response);
239 break; 259 break;
240 default: 260 default:
241 // Multiple responses for other commands are invalid. 261 // Multiple responses for other commands are invalid.
242 return Stop(ERR_INVALID_RESPONSE); 262 return Stop(ERR_INVALID_RESPONSE);
243 } 263 }
244 } 264 }
245 265
246 return rv; 266 return rv;
247 } 267 }
248 268
269 void FtpNetworkTransaction::ResetStateForRestart() {
270 command_sent_ = COMMAND_NONE;
271 user_callback_ = NULL;
272 response_ = FtpResponseInfo();
273 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen);
274 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer());
275 read_data_buf_ = NULL;
276 read_data_buf_len_ = 0;
277 file_data_len_ = 0;
278 write_command_buf_written_ = 0;
279 last_error_ = OK;
280 retr_failed_ = false;
281 data_connection_port_ = 0;
282 ctrl_socket_.reset();
283 data_socket_.reset();
284 next_state_ = STATE_NONE;
285 }
286
249 void FtpNetworkTransaction::DoCallback(int rv) { 287 void FtpNetworkTransaction::DoCallback(int rv) {
250 DCHECK(rv != ERR_IO_PENDING); 288 DCHECK(rv != ERR_IO_PENDING);
251 DCHECK(user_callback_); 289 DCHECK(user_callback_);
252 290
253 // Since Run may result in Read being called, clear callback_ up front. 291 // Since Run may result in Read being called, clear callback_ up front.
254 CompletionCallback* c = user_callback_; 292 CompletionCallback* c = user_callback_;
255 user_callback_ = NULL; 293 user_callback_ = NULL;
256 c->Run(rv); 294 c->Run(rv);
257 } 295 }
258 296
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 return ctrl_socket_->Read( 474 return ctrl_socket_->Read(
437 read_ctrl_buf_, 475 read_ctrl_buf_,
438 kCtrlBufLen, 476 kCtrlBufLen,
439 &io_callback_); 477 &io_callback_);
440 } 478 }
441 479
442 int FtpNetworkTransaction::DoCtrlReadComplete(int result) { 480 int FtpNetworkTransaction::DoCtrlReadComplete(int result) {
443 if (result < 0) 481 if (result < 0)
444 return Stop(result); 482 return Stop(result);
445 483
446 ctrl_response_buffer_.ConsumeData(read_ctrl_buf_->data(), result); 484 ctrl_response_buffer_->ConsumeData(read_ctrl_buf_->data(), result);
447 485
448 if (!ctrl_response_buffer_.ResponseAvailable()) { 486 if (!ctrl_response_buffer_->ResponseAvailable()) {
449 // Read more data from the control socket. 487 // Read more data from the control socket.
450 next_state_ = STATE_CTRL_READ; 488 next_state_ = STATE_CTRL_READ;
451 return OK; 489 return OK;
452 } 490 }
453 491
454 return ProcessCtrlResponse(); 492 return ProcessCtrlResponse();
455 } 493 }
456 494
457 int FtpNetworkTransaction::DoCtrlWrite() { 495 int FtpNetworkTransaction::DoCtrlWrite() {
458 next_state_ = STATE_CTRL_WRITE_COMPLETE; 496 next_state_ = STATE_CTRL_WRITE_COMPLETE;
(...skipping 20 matching lines...) Expand all
479 } else { 517 } else {
480 next_state_ = STATE_CTRL_WRITE; 518 next_state_ = STATE_CTRL_WRITE;
481 } 519 }
482 return OK; 520 return OK;
483 } 521 }
484 522
485 // FTP Commands and responses 523 // FTP Commands and responses
486 524
487 // USER Command. 525 // USER Command.
488 int FtpNetworkTransaction::DoCtrlWriteUSER() { 526 int FtpNetworkTransaction::DoCtrlWriteUSER() {
489 std::string command = "USER"; 527 std::string command = "USER " + WideToUTF8(username_);
wtc 2009/08/25 20:52:50 Can you add a comment to the header to explain why
490 if (request_->url.has_username()) {
491 command.append(" ");
492 command.append(request_->url.username());
493 } else {
494 is_anonymous_ = true;
495 command.append(" anonymous");
496 }
497 next_state_ = STATE_CTRL_READ; 528 next_state_ = STATE_CTRL_READ;
498 return SendFtpCommand(command, COMMAND_USER); 529 return SendFtpCommand(command, COMMAND_USER);
499 } 530 }
500 531
501 int FtpNetworkTransaction::ProcessResponseUSER( 532 int FtpNetworkTransaction::ProcessResponseUSER(
502 const FtpCtrlResponse& response) { 533 const FtpCtrlResponse& response) {
503 switch (GetErrorClass(response.status_code)) { 534 switch (GetErrorClass(response.status_code)) {
504 case ERROR_CLASS_OK: 535 case ERROR_CLASS_OK:
505 next_state_ = STATE_CTRL_WRITE_SYST; 536 next_state_ = STATE_CTRL_WRITE_SYST;
506 break; 537 break;
507 case ERROR_CLASS_INFO_NEEDED: 538 case ERROR_CLASS_INFO_NEEDED:
508 next_state_ = STATE_CTRL_WRITE_PASS; 539 next_state_ = STATE_CTRL_WRITE_PASS;
509 break; 540 break;
510 case ERROR_CLASS_TRANSIENT_ERROR: 541 case ERROR_CLASS_TRANSIENT_ERROR:
511 if (response.status_code == 421) 542 if (response.status_code == 421)
512 return Stop(ERR_FAILED); 543 return Stop(ERR_FAILED);
513 break; 544 break;
514 case ERROR_CLASS_PERMANENT_ERROR: 545 case ERROR_CLASS_PERMANENT_ERROR:
515 return Stop(ERR_FAILED); 546 return Stop(ERR_FAILED);
516 default: 547 default:
517 NOTREACHED(); 548 NOTREACHED();
518 return Stop(ERR_UNEXPECTED); 549 return Stop(ERR_UNEXPECTED);
519 } 550 }
520 return OK; 551 return OK;
521 } 552 }
522 553
523 // PASS command. 554 // PASS command.
524 int FtpNetworkTransaction::DoCtrlWritePASS() { 555 int FtpNetworkTransaction::DoCtrlWritePASS() {
525 std::string command = "PASS"; 556 std::string command = "PASS " + WideToUTF8(password_);
eroman 2009/09/01 07:12:37 PLEASE READ: This looks dangerous! |username_| an
526 if (request_->url.has_password()) {
527 command.append(" ");
528 command.append(request_->url.password());
529 } else {
530 command.append(" ");
531 command.append("chrome@example.com");
532 }
533 next_state_ = STATE_CTRL_READ; 557 next_state_ = STATE_CTRL_READ;
534 return SendFtpCommand(command, COMMAND_PASS); 558 return SendFtpCommand(command, COMMAND_PASS);
535 } 559 }
536 560
537 int FtpNetworkTransaction::ProcessResponsePASS( 561 int FtpNetworkTransaction::ProcessResponsePASS(
538 const FtpCtrlResponse& response) { 562 const FtpCtrlResponse& response) {
539 switch (GetErrorClass(response.status_code)) { 563 switch (GetErrorClass(response.status_code)) {
540 case ERROR_CLASS_OK: 564 case ERROR_CLASS_OK:
541 next_state_ = STATE_CTRL_WRITE_SYST; 565 next_state_ = STATE_CTRL_WRITE_SYST;
542 break; 566 break;
543 case ERROR_CLASS_INFO_NEEDED: 567 case ERROR_CLASS_INFO_NEEDED:
544 next_state_ = STATE_CTRL_WRITE_ACCT; 568 next_state_ = STATE_CTRL_WRITE_ACCT;
545 break; 569 break;
546 case ERROR_CLASS_TRANSIENT_ERROR: 570 case ERROR_CLASS_TRANSIENT_ERROR:
547 if (response.status_code == 421) { 571 if (response.status_code == 421) {
548 // TODO(ibrar): Retry here. 572 // TODO(ibrar): Retry here.
549 } 573 }
550 return Stop(ERR_FAILED); 574 return Stop(ERR_FAILED);
551 case ERROR_CLASS_PERMANENT_ERROR: 575 case ERROR_CLASS_PERMANENT_ERROR:
552 if (response.status_code == 503) { 576 if (response.status_code == 503) {
553 next_state_ = STATE_CTRL_WRITE_USER; 577 next_state_ = STATE_CTRL_WRITE_USER;
554 } else { 578 } else {
555 // TODO(ibrar): Retry here. 579 response_.auth_needed = true;
eroman 2009/09/01 07:12:37 Hm, I dont know about this... will have to look mo
556 return Stop(ERR_FAILED); 580 return Stop(ERR_FAILED);
557 } 581 }
558 break; 582 break;
559 default: 583 default:
560 NOTREACHED(); 584 NOTREACHED();
561 return Stop(ERR_UNEXPECTED); 585 return Stop(ERR_UNEXPECTED);
562 } 586 }
563 return OK; 587 return OK;
564 } 588 }
565 589
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 read_data_buf_->data()[0] = 0; 998 read_data_buf_->data()[0] = 0;
975 return data_socket_->Read(read_data_buf_, read_data_buf_len_, 999 return data_socket_->Read(read_data_buf_, read_data_buf_len_,
976 &io_callback_); 1000 &io_callback_);
977 } 1001 }
978 1002
979 int FtpNetworkTransaction::DoDataReadComplete(int result) { 1003 int FtpNetworkTransaction::DoDataReadComplete(int result) {
980 return result; 1004 return result;
981 } 1005 }
982 1006
983 } // namespace net 1007 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698