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

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

Issue 39130: FTP Transaction code for new Portable FTP(Patch SET-3) (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « net/ftp/ftp_network_transaction.h ('k') | net/ftp/ftp_request_info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/logging.h" 8 #include "base/string_util.h"
9 #include "net/base/client_socket.h" 9 #include "net/base/client_socket.h"
10 #include "net/base/client_socket_factory.h"
11 #include "net/base/connection_type_histograms.h"
12 #include "net/base/dns_resolution_observer.h"
10 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
11 #include "net/ftp/ftp_network_session.h" 14 #include "net/ftp/ftp_network_session.h"
15 #include "net/ftp/ftp_request_info.h"
16
17
18 #define CRLF "\015\012"
19
20 const int kCtrlBufLen = 1024;
12 21
13 namespace net { 22 namespace net {
14 23
15 FtpNetworkTransaction::FtpNetworkTransaction( 24 FtpNetworkTransaction::FtpNetworkTransaction(
16 FtpNetworkSession* session, ClientSocketFactory* socket_factory) 25 FtpNetworkSession* session, ClientSocketFactory* socket_factory)
17 : ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, 26 : ALLOW_THIS_IN_INITIALIZER_LIST(
18 &FtpNetworkTransaction::OnIOComplete)), 27 io_callback_(this, &FtpNetworkTransaction::OnIOComplete)),
19 user_callback_(NULL), 28 user_callback_(NULL),
20 session_(session), 29 session_(session),
21 socket_factory_(socket_factory), 30 socket_factory_(socket_factory),
22 next_state_(STATE_NONE) { 31 next_state_(STATE_NONE),
32 command_sent_(COMMAND_NONE),
33 read_data_buf_(NULL),
34 read_data_buf_len_(0),
35 file_data_len_(0),
36 data_connection_port_(0),
37 read_ctrl_buf_size_(0),
38 response_message_buf_len_(0),
39 last_error_(OK) {
40 read_ctrl_buf_size_ = kCtrlBufLen;
41 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen);
42 response_message_buf_ = new IOBuffer(kCtrlBufLen);
23 } 43 }
24 44
25 FtpNetworkTransaction::~FtpNetworkTransaction() { 45 FtpNetworkTransaction::~FtpNetworkTransaction() {
26 } 46 }
27 47
28 void FtpNetworkTransaction::Destroy() {
29 delete this;
30 }
31
32 int FtpNetworkTransaction::Start( 48 int FtpNetworkTransaction::Start(
33 const FtpRequestInfo* request_info, CompletionCallback* callback) { 49 const FtpRequestInfo* request_info, CompletionCallback* callback) {
34 request_ = request_info; 50 request_ = request_info;
35 51
36 next_state_ = STATE_CTRL_INIT; 52 next_state_ = STATE_CTRL_INIT;
37 int rv = DoLoop(OK); 53 int rv = DoLoop(OK);
38 if (rv == ERR_IO_PENDING) 54 if (rv == ERR_IO_PENDING)
39 user_callback_ = callback; 55 user_callback_ = callback;
40 return rv; 56 return rv;
41 } 57 }
58 int FtpNetworkTransaction::Stop(int error) {
59 next_state_ = STATE_CTRL_WRITE_QUIT;
60 last_error_ = error;
61 return OK;
62 }
42 63
43 int FtpNetworkTransaction::RestartWithAuth( 64 int FtpNetworkTransaction::RestartWithAuth(
44 const std::wstring& username, const std::wstring& password, 65 const std::wstring& username, const std::wstring& password,
45 CompletionCallback* callback) { 66 CompletionCallback* callback) {
46 return ERR_FAILED; 67 return ERR_FAILED;
47 } 68 }
48 69
70 int FtpNetworkTransaction::RestartIgnoringLastError(
71 CompletionCallback* callback) {
72 return ERR_FAILED;
73 }
74
49 int FtpNetworkTransaction::Read( 75 int FtpNetworkTransaction::Read(
50 char* buf, int buf_len, CompletionCallback* callback) { 76 IOBuffer* buf, int buf_len, CompletionCallback* callback) {
51 return ERR_FAILED; 77 DCHECK(buf);
78 DCHECK(buf_len > 0);
79
80 if (data_socket_ == NULL)
81 return 0; // Data socket closed, no more data left.
82
83 if (!data_socket_->IsConnected())
84 return 0; // Data socket disconnected, no more data left.
85
86 read_data_buf_ = buf;
87 read_data_buf_len_ = buf_len;
88
89 next_state_ = STATE_DATA_READ;
90
91 int rv = DoLoop(OK);
92 if (rv == ERR_IO_PENDING)
93 user_callback_ = callback;
94 if (rv == 0) {
95 data_socket_->Disconnect();
96 }
97 return rv;
52 } 98 }
53 99
54 const FtpResponseInfo* FtpNetworkTransaction::GetResponseInfo() const { 100 const FtpResponseInfo* FtpNetworkTransaction::GetResponseInfo() const {
55 return NULL; 101 return &response_;
56 } 102 }
57 103
58 LoadState FtpNetworkTransaction::GetLoadState() const { 104 LoadState FtpNetworkTransaction::GetLoadState() const {
59 return LOAD_STATE_IDLE; 105 return LOAD_STATE_IDLE;
60 } 106 }
61 107
62 uint64 FtpNetworkTransaction::GetUploadProgress() const { 108 uint64 FtpNetworkTransaction::GetUploadProgress() const {
63 return 0; 109 return 0;
64 } 110 }
65 111
112 // Used to prepare and send FTP commad.
113 int FtpNetworkTransaction::SendFtpCommand(std::string& command, Command cmd) {
114 response_message_buf_len_ = 0;
115 command_sent_ = cmd;
116 DLOG(INFO) << " >> " << command;
117 command.append(CRLF);
118 const char* buf = command.c_str();
119 int buf_len = command.size();
120 return ctrl_socket_->Write(buf, buf_len, &io_callback_);
121 }
122
123 int FtpNetworkTransaction::GetRespnseCode() {
124 std::string str(response_message_buf_->data(), 3);
125 return StringToInt(str);
126 }
127
128 int FtpNetworkTransaction::ProcessResponse(int response_code) {
129 int rv = OK;
130 switch (command_sent_) {
131 case COMMAND_NONE:
132 next_state_ = STATE_CTRL_WRITE_USER;
133 break;
134 case COMMAND_USER:
135 rv = ProcessResponseUSER(response_code);
136 break;
137 case COMMAND_PASS:
138 rv = ProcessResponsePASS(response_code);
139 break;
140 case COMMAND_ACCT:
141 rv = ProcessResponseACCT(response_code);
142 break;
143 case COMMAND_SYST:
144 rv = ProcessResponseSYST(response_code);
145 break;
146 case COMMAND_PWD:
147 rv = ProcessResponsePWD(response_code);
148 break;
149 case COMMAND_TYPE:
150 rv = ProcessResponseTYPE(response_code);
151 break;
152 case COMMAND_PASV:
153 rv = ProcessResponsePASV(response_code);
154 break;
155 case COMMAND_SIZE:
156 rv = ProcessResponseSIZE(response_code);
157 break;
158 case COMMAND_RETR:
159 rv = ProcessResponseRETR(response_code);
160 break;
161 case COMMAND_CWD:
162 rv = ProcessResponseCWD(response_code);
163 break;
164 case COMMAND_LIST:
165 rv = ProcessResponseLIST(response_code);
166 break;
167 case COMMAND_QUIT:
168 rv = ProcessResponseQUIT(response_code);
169 break;
170 default:
171 DLOG(INFO) << "Missing Command response handling!";
172 return ERR_FAILED;
173 }
174 return rv;
175 }
176
66 void FtpNetworkTransaction::DoCallback(int rv) { 177 void FtpNetworkTransaction::DoCallback(int rv) {
67 DCHECK(rv != ERR_IO_PENDING); 178 DCHECK(rv != ERR_IO_PENDING);
68 DCHECK(user_callback_); 179 DCHECK(user_callback_);
69 180
70 // Since Run may result in Read being called, clear callback_ up front. 181 // Since Run may result in Read being called, clear callback_ up front.
71 CompletionCallback* c = user_callback_; 182 CompletionCallback* c = user_callback_;
72 user_callback_ = NULL; 183 user_callback_ = NULL;
73 c->Run(rv); 184 c->Run(rv);
74 } 185 }
75 186
(...skipping 25 matching lines...) Expand all
101 case STATE_CTRL_RESOLVE_HOST_COMPLETE: 212 case STATE_CTRL_RESOLVE_HOST_COMPLETE:
102 rv = DoCtrlResolveHostComplete(rv); 213 rv = DoCtrlResolveHostComplete(rv);
103 break; 214 break;
104 case STATE_CTRL_CONNECT: 215 case STATE_CTRL_CONNECT:
105 DCHECK(rv == OK); 216 DCHECK(rv == OK);
106 rv = DoCtrlConnect(); 217 rv = DoCtrlConnect();
107 break; 218 break;
108 case STATE_CTRL_CONNECT_COMPLETE: 219 case STATE_CTRL_CONNECT_COMPLETE:
109 rv = DoCtrlConnectComplete(rv); 220 rv = DoCtrlConnectComplete(rv);
110 break; 221 break;
111 case STATE_CTRL_WRITE:
112 DCHECK(rv == OK);
113 rv = DoCtrlWrite();
114 break;
115 case STATE_CTRL_WRITE_COMPLETE:
116 rv = DoCtrlWriteComplete(rv);
117 break;
118 case STATE_CTRL_READ: 222 case STATE_CTRL_READ:
119 DCHECK(rv == OK);
120 rv = DoCtrlRead(); 223 rv = DoCtrlRead();
121 break; 224 break;
122 case STATE_CTRL_READ_COMPLETE: 225 case STATE_CTRL_READ_COMPLETE:
123 rv = DoCtrlReadComplete(rv); 226 rv = DoCtrlReadComplete(rv);
124 break; 227 break;
228 case STATE_CTRL_WRITE_USER:
229 DCHECK(rv == OK);
230 rv = DoCtrlWriteUSER();
231 break;
232 case STATE_CTRL_WRITE_PASS:
233 DCHECK(rv == OK);
234 rv = DoCtrlWritePASS();
235 break;
236 case STATE_CTRL_WRITE_SYST:
237 DCHECK(rv == OK);
238 rv = DoCtrlWriteSYST();
239 break;
240 case STATE_CTRL_WRITE_ACCT:
241 DCHECK(rv == OK);
242 rv = DoCtrlWriteACCT();
243 break;
244 case STATE_CTRL_WRITE_PWD:
245 DCHECK(rv == OK);
246 rv = DoCtrlWritePWD();
247 break;
248 case STATE_CTRL_WRITE_TYPE:
249 DCHECK(rv == OK);
250 rv = DoCtrlWriteTYPE();
251 break;
252 case STATE_CTRL_WRITE_PASV:
253 DCHECK(rv == OK);
254 rv = DoCtrlWritePASV();
255 break;
256 case STATE_CTRL_WRITE_RETR:
257 DCHECK(rv == OK);
258 rv = DoCtrlWriteRETR();
259 break;
260 case STATE_CTRL_WRITE_SIZE:
261 DCHECK(rv == OK);
262 rv = DoCtrlWriteSIZE();
263 break;
264 case STATE_CTRL_WRITE_CWD:
265 rv = DoCtrlWriteCWD();
266 break;
267 case STATE_CTRL_WRITE_LIST:
268 rv = DoCtrlWriteLIST();
269 break;
270 case STATE_CTRL_WRITE_QUIT:
271 rv = DoCtrlWriteQUIT();
272 break;
273
125 case STATE_DATA_CONNECT: 274 case STATE_DATA_CONNECT:
126 DCHECK(rv == OK); 275 DCHECK(rv == OK);
127 rv = DoDataConnect(); 276 rv = DoDataConnect();
128 break; 277 break;
129 case STATE_DATA_CONNECT_COMPLETE: 278 case STATE_DATA_CONNECT_COMPLETE:
130 rv = DoDataConnectComplete(rv); 279 rv = DoDataConnectComplete(rv);
131 break; 280 break;
132 case STATE_DATA_READ: 281 case STATE_DATA_READ:
133 DCHECK(rv == OK);
134 rv = DoDataRead(); 282 rv = DoDataRead();
135 break; 283 break;
136 case STATE_DATA_READ_COMPLETE: 284 case STATE_DATA_READ_COMPLETE:
137 rv = DoDataReadComplete(rv); 285 rv = DoDataReadComplete(rv);
138 break; 286 break;
139 default: 287 default:
140 NOTREACHED() << "bad state"; 288 NOTREACHED() << "bad state";
141 rv = ERR_FAILED; 289 rv = ERR_FAILED;
142 break; 290 break;
143 } 291 }
144 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 292 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
145
146 return rv; 293 return rv;
147 } 294 }
148 295
296 // TODO(ibrar): Yet to see if we need any intialization
149 int FtpNetworkTransaction::DoCtrlInit() { 297 int FtpNetworkTransaction::DoCtrlInit() {
150 return ERR_FAILED; // TODO(darin): implement me 298 next_state_ = STATE_CTRL_INIT_COMPLETE;
299 return OK;
151 } 300 }
152 301
153 int FtpNetworkTransaction::DoCtrlInitComplete(int result) { 302 int FtpNetworkTransaction::DoCtrlInitComplete(int result) {
154 return ERR_FAILED; // TODO(darin): implement me 303 next_state_ = STATE_CTRL_RESOLVE_HOST;
304 return OK;
155 } 305 }
156 306
157 int FtpNetworkTransaction::DoCtrlResolveHost() { 307 int FtpNetworkTransaction::DoCtrlResolveHost() {
158 return ERR_FAILED; // TODO(darin): implement me 308 next_state_ = STATE_CTRL_RESOLVE_HOST_COMPLETE;
309
310 std::string host;
311 int port;
312
313 host = request_->url.host();
314 port = request_->url.EffectiveIntPort();
315
316 DidStartDnsResolution(host, this);
317 return resolver_.Resolve(host, port, &addresses_, &io_callback_);
159 } 318 }
160 319
161 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { 320 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) {
162 return ERR_FAILED; // TODO(darin): implement me 321 bool ok = (result == OK);
322 DidFinishDnsResolutionWithStatus(ok, GURL(), this);
323 if (ok) {
324 next_state_ = STATE_CTRL_CONNECT;
325 return result;
326 }
327 return ERR_FAILED;
163 } 328 }
164 329
165 int FtpNetworkTransaction::DoCtrlConnect() { 330 int FtpNetworkTransaction::DoCtrlConnect() {
166 return ERR_FAILED; // TODO(darin): implement me 331 next_state_ = STATE_CTRL_CONNECT_COMPLETE;
332 ctrl_socket_.reset(socket_factory_->CreateTCPClientSocket(addresses_));
333 return ctrl_socket_->Connect(&io_callback_);
167 } 334 }
168 335
169 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { 336 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) {
170 return ERR_FAILED; // TODO(darin): implement me 337 next_state_ = STATE_CTRL_READ;
171 } 338 return result;
172
173 int FtpNetworkTransaction::DoCtrlWrite() {
174 return ERR_FAILED; // TODO(darin): implement me
175 }
176
177 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) {
178 return ERR_FAILED; // TODO(darin): implement me
179 } 339 }
180 340
181 int FtpNetworkTransaction::DoCtrlRead() { 341 int FtpNetworkTransaction::DoCtrlRead() {
182 return ERR_FAILED; // TODO(darin): implement me 342 next_state_ = STATE_CTRL_READ_COMPLETE;
343 read_ctrl_buf_->data()[0] = 0;
344 return ctrl_socket_->Read(read_ctrl_buf_->data(),
345 read_ctrl_buf_size_ - 1, &io_callback_);
183 } 346 }
184 347
185 int FtpNetworkTransaction::DoCtrlReadComplete(int result) { 348 int FtpNetworkTransaction::DoCtrlReadComplete(int result) {
186 return ERR_FAILED; // TODO(darin): implement me 349 if (result < 0)
187 } 350 return Stop(ERR_FAILED);
188 351 int response_code;
352 // Null termination added, now we can treat this as string.
353 read_ctrl_buf_->data()[result] = 0;
354 memcpy(response_message_buf_->data() + response_message_buf_len_,
355 read_ctrl_buf_->data(), result);
356
357 response_message_buf_len_ = response_message_buf_len_ + result;
358 for (int i = 0; i < response_message_buf_len_; i++) {
359 if (response_message_buf_->data()[i] == '\r' &&
360 response_message_buf_->data()[i + 1] == '\n') {
361 if (response_message_buf_len_ > 3 &&
362 response_message_buf_->data()[3] == ' ') {
363 response_message_buf_->data()[response_message_buf_len_ - 2] = 0;
364 response_code = GetRespnseCode();
365 return ProcessResponse(response_code);
366 } else {
367 response_message_buf_len_ -= (i + 2);
368 memcpy(response_message_buf_->data(),
369 response_message_buf_->data() + i + 2,
370 response_message_buf_len_);
371 i = 0;
372 }
373 }
374 }
375 next_state_ = STATE_CTRL_READ;
376 return OK;
377 }
378
379 // FTP Commands and responses
380
381 // USER Command.
382 int FtpNetworkTransaction::DoCtrlWriteUSER() {
383 std::string command = "USER ";
384 if (request_->url.has_username()) {
385 command.append(request_->url.username());
386 } else {
387 command.append("anonymous");
388 }
389 next_state_ = STATE_CTRL_READ;
390 return SendFtpCommand(command, COMMAND_USER);
391 }
392
393 int FtpNetworkTransaction::ProcessResponseUSER(int response_code) {
394 switch (GetErrorClass(response_code)) {
395 case ERROR_CLASS_INITIATED:
396 case ERROR_CLASS_OK:
397 next_state_ = STATE_CTRL_WRITE_USER;
398 break;
399 case ERROR_CLASS_PENDING:
400 next_state_ = STATE_CTRL_WRITE_PASS;
401 break;
402 case ERROR_CLASS_ERROR_RETRY:
403 if (response_code == 421)
404 return Stop(ERR_FAILED);
405 break;
406 case ERROR_CLASS_ERROR:
407 return Stop(ERR_FAILED);
408 default:
409 return Stop(ERR_FAILED);
410 }
411 return OK;
412 }
413
414 // PASS command.
415 int FtpNetworkTransaction::DoCtrlWritePASS() {
416 std::string command = "PASS ";
417 if (request_->url.has_password()) {
418 command.append(request_->url.password());
419 } else {
420 command.append("IEUser@");
421 }
422 next_state_ = STATE_CTRL_READ;
423 return SendFtpCommand(command, COMMAND_PASS);
424 }
425
426 int FtpNetworkTransaction::ProcessResponsePASS(int response_code) {
427 switch (GetErrorClass(response_code)) {
428 case ERROR_CLASS_INITIATED:
429 case ERROR_CLASS_OK:
430 next_state_ = STATE_CTRL_WRITE_SYST;
431 break;
432 case ERROR_CLASS_PENDING:
433 next_state_ = STATE_CTRL_WRITE_ACCT;
434 break;
435 case ERROR_CLASS_ERROR_RETRY:
436 return Stop(ERR_FAILED);
437 case ERROR_CLASS_ERROR:
438 if (response_code == 503) {
439 next_state_ = STATE_CTRL_WRITE_PASS;
440 } else {
441 return Stop(ERR_FAILED);
442 }
443 break;
444 default:
445 return Stop(ERR_FAILED);
446 }
447 return OK;
448 }
449
450 // ACCT command.
451 int FtpNetworkTransaction::DoCtrlWriteACCT() {
452 std::string command = "ACCT noaccount";
453 next_state_ = STATE_CTRL_READ;
454 return SendFtpCommand(command, COMMAND_ACCT);
455 }
456
457 int FtpNetworkTransaction::ProcessResponseACCT(int response_code) {
458 switch (GetErrorClass(response_code)) {
459 case ERROR_CLASS_INITIATED:
460 return Stop(ERR_FAILED);
461 case ERROR_CLASS_OK:
462 next_state_ = STATE_CTRL_WRITE_SYST;
463 break;
464 case ERROR_CLASS_PENDING:
465 return Stop(ERR_FAILED);
466 case ERROR_CLASS_ERROR_RETRY:
467 return Stop(ERR_FAILED);
468 case ERROR_CLASS_ERROR:
469 return Stop(ERR_FAILED);
470 default:
471 return Stop(ERR_FAILED);
472 }
473 return OK;
474 }
475
476 // SYST command.
477 int FtpNetworkTransaction::DoCtrlWriteSYST() {
478 std::string command = "SYST";
479 next_state_ = STATE_CTRL_READ;
480 return SendFtpCommand(command, COMMAND_SYST);
481 }
482
483 int FtpNetworkTransaction::ProcessResponseSYST(int response_code) {
484 next_state_ = STATE_CTRL_WRITE_PWD;
485 return OK;
486 }
487
488 // PWD command.
489 int FtpNetworkTransaction::DoCtrlWritePWD() {
490 std::string command = "PWD";
491 next_state_ = STATE_CTRL_READ;
492 return SendFtpCommand(command, COMMAND_PWD);
493 }
494
495 int FtpNetworkTransaction::ProcessResponsePWD(int response_code) {
496 switch (GetErrorClass(response_code)) {
497 case ERROR_CLASS_INITIATED:
498 return Stop(ERR_FAILED);
499 case ERROR_CLASS_OK:
500 next_state_ = STATE_CTRL_WRITE_TYPE;
501 break;
502 case ERROR_CLASS_PENDING:
503 return Stop(ERR_FAILED);
504 case ERROR_CLASS_ERROR_RETRY:
505 return Stop(ERR_FAILED);
506 case ERROR_CLASS_ERROR:
507 return Stop(ERR_FAILED);
508 default:
509 return Stop(ERR_FAILED);
510 }
511 return OK;
512 }
513
514 // TYPE command.
515 int FtpNetworkTransaction::DoCtrlWriteTYPE() {
516 std::string command = "TYPE I";
517 next_state_ = STATE_CTRL_READ;
518 return SendFtpCommand(command, COMMAND_TYPE);
519 }
520
521 int FtpNetworkTransaction::ProcessResponseTYPE(int response_code) {
522 switch (GetErrorClass(response_code)) {
523 case ERROR_CLASS_INITIATED:
524 return Stop(ERR_FAILED);
525 case ERROR_CLASS_OK:
526 next_state_ = STATE_CTRL_WRITE_PASV;
527 break;
528 case ERROR_CLASS_PENDING:
529 return Stop(ERR_FAILED);
530 case ERROR_CLASS_ERROR_RETRY:
531 return Stop(ERR_FAILED);
532 case ERROR_CLASS_ERROR:
533 return Stop(ERR_FAILED);
534 default:
535 return Stop(ERR_FAILED);
536 }
537 return OK;
538 }
539
540 // PASV command
541 int FtpNetworkTransaction::DoCtrlWritePASV() {
542 std::string command = "PASV ";
543 next_state_ = STATE_CTRL_READ;
544 return SendFtpCommand(command, COMMAND_PASV);
545 }
546
547 // There are two way we can receive IP address and port.
548 // (127,0,0,1,23,21) IP address and port encapsulate in ().
549 // 127,0,0,1,23,21 IP address and port without ().
550 int FtpNetworkTransaction::ProcessResponsePASV(int response_code) {
551 switch (GetErrorClass(response_code)) {
552 case ERROR_CLASS_INITIATED:
553 return Stop(ERR_FAILED);
554 case ERROR_CLASS_OK:
555 char* ptr;
556 int i0, i1, i2, i3, p0, p1;
557 ptr = read_ctrl_buf_->data(); // Try with bracket.
558 while (*ptr && *ptr != '(')
559 ++ptr;
560 if (*ptr) {
561 ++ptr;
562 } else {
563 ptr = read_ctrl_buf_->data(); // Try without bracket.
564 while (*ptr && *ptr != ',')
565 ++ptr;
566 while (*ptr && *ptr != ' ')
567 --ptr;
568 }
569 if (sscanf_s(ptr, "%ld,%ld,%ld,%ld,%ld,%ld", &i0, &i1, &i2, &i3, &p0,
570 &p1) == 6) {
571 data_connection_ip_ = StringPrintf("%ld.%ld.%ld.%ld", i0, i1, i2, i3);
572 data_connection_port_ = (p0 << 8) + p1;
573 next_state_ = STATE_DATA_CONNECT;
574 } else {
575 return Stop(ERR_FAILED);
576 }
577 break;
578 case ERROR_CLASS_PENDING:
579 return Stop(ERR_FAILED);
580 case ERROR_CLASS_ERROR_RETRY:
581 return Stop(ERR_FAILED);
582 case ERROR_CLASS_ERROR:
583 return Stop(ERR_FAILED);
584 default:
585 return Stop(ERR_FAILED);
586 }
587 return OK;
588 }
589
590 // SIZE command
591 int FtpNetworkTransaction::DoCtrlWriteSIZE() {
592 std::string command = "SIZE ";
593 if (request_->url.has_path())
594 command.append(request_->url.path());
595 next_state_ = STATE_CTRL_READ;
596 return SendFtpCommand(command, COMMAND_SIZE);
597 }
598
599 int FtpNetworkTransaction::ProcessResponseSIZE(int response_code) {
600 switch (GetErrorClass(response_code)) {
601 case ERROR_CLASS_INITIATED:
602 next_state_ = STATE_CTRL_WRITE_LIST;
603 break;
604 case ERROR_CLASS_OK:
605 next_state_ = STATE_CTRL_WRITE_RETR;
606 if (!StringToInt(read_ctrl_buf_->data() + 4, &file_data_len_))
607 return Stop(ERR_FAILED);
608 break;
609 case ERROR_CLASS_PENDING:
610 next_state_ = STATE_CTRL_WRITE_LIST;
611 break;
612 case ERROR_CLASS_ERROR_RETRY:
613 next_state_ = STATE_CTRL_WRITE_LIST;
614 break;
615 case ERROR_CLASS_ERROR:
616 next_state_ = STATE_CTRL_WRITE_LIST;
617 break;
618 default:
619 return Stop(ERR_FAILED);
620 }
621 return OK;
622 }
623
624 // RETR command
625 int FtpNetworkTransaction::DoCtrlWriteRETR() {
626 std::string command = "RETR ";
627 if (request_->url.has_path())
628 command.append(request_->url.path());
629 next_state_ = STATE_CTRL_READ;
630 return SendFtpCommand(command, COMMAND_RETR);
631 }
632
633 int FtpNetworkTransaction::ProcessResponseRETR(int response_code) {
634 switch (GetErrorClass(response_code)) {
635 case ERROR_CLASS_INITIATED:
636 next_state_ = STATE_CTRL_WRITE_QUIT;
637 ctrl_socket_->Disconnect();
638 break;
639 case ERROR_CLASS_OK:
640 break; // FTP Done
641 case ERROR_CLASS_PENDING:
642 next_state_ = STATE_CTRL_WRITE_PASV;
643 break;
644 case ERROR_CLASS_ERROR_RETRY:
645 if (response_code == 421 || response_code == 425 || response_code == 426)
646 return Stop(ERR_FAILED);
647 return ERR_FAILED; // TODO(ibrar): Retry here.
648 case ERROR_CLASS_ERROR:
649 next_state_ = STATE_CTRL_WRITE_CWD;
650 break;
651 default:
652 return Stop(ERR_FAILED);
653 }
654 return OK;
655 }
656
657 // CWD command
658 int FtpNetworkTransaction::DoCtrlWriteCWD() {
659 std::string command = "CWD";
660 next_state_ = STATE_CTRL_READ;
661 return SendFtpCommand(command, COMMAND_CWD);
662 }
663
664 int FtpNetworkTransaction::ProcessResponseCWD(int response_code) {
665 switch (GetErrorClass(response_code)) {
666 case ERROR_CLASS_INITIATED:
667 return Stop(ERR_FAILED);
668 case ERROR_CLASS_OK:
669 next_state_ = STATE_CTRL_WRITE_LIST;
670 case ERROR_CLASS_PENDING:
671 return Stop(ERR_FAILED);
672 case ERROR_CLASS_ERROR_RETRY:
673 return Stop(ERR_FAILED);
674 case ERROR_CLASS_ERROR:
675 return Stop(ERR_FAILED);
676 default:
677 return Stop(ERR_FAILED);
678 }
679 return OK;
680 }
681
682 // LIST command
683 int FtpNetworkTransaction::DoCtrlWriteLIST() {
684 std::string command = "LIST ";
685 if (request_->url.has_path())
686 command.append(request_->url.path());
687 next_state_ = STATE_CTRL_READ;
688 return SendFtpCommand(command, COMMAND_LIST);
689 }
690
691 int FtpNetworkTransaction::ProcessResponseLIST(int response_code) {
692 switch (GetErrorClass(response_code)) {
693 case ERROR_CLASS_INITIATED:
694 next_state_ = STATE_CTRL_WRITE_QUIT;
695 response_.is_directory_listing = true;
696 break;
697 case ERROR_CLASS_OK:
698 next_state_ = STATE_CTRL_WRITE_QUIT;
699 response_.is_directory_listing = true;
700 break;
701 case ERROR_CLASS_PENDING:
702 return Stop(ERR_FAILED);
703 case ERROR_CLASS_ERROR_RETRY:
704 return Stop(ERR_FAILED);
705 case ERROR_CLASS_ERROR:
706 return Stop(ERR_FAILED);
707 default:
708 return Stop(ERR_FAILED);
709 }
710 return OK;
711 }
712
713 // Quit command
714 int FtpNetworkTransaction::DoCtrlWriteQUIT() {
715 std::string command = "QUIT";
716 next_state_ = STATE_CTRL_READ;
717 return SendFtpCommand(command, COMMAND_QUIT);
718 }
719
720 int FtpNetworkTransaction::ProcessResponseQUIT(int response_code) {
721 ctrl_socket_->Disconnect();
722 return last_error_;
723 }
724
725 // Data Connection
189 int FtpNetworkTransaction::DoDataConnect() { 726 int FtpNetworkTransaction::DoDataConnect() {
190 return ERR_FAILED; // TODO(darin): implement me 727 next_state_ = STATE_DATA_CONNECT_COMPLETE;
728 AddressList adr;
729 int err = resolver_.Resolve(data_connection_ip_,
730 data_connection_port_, &adr, NULL);
731 data_socket_.reset(socket_factory_->CreateTCPClientSocket(adr));
732 return data_socket_->Connect(&io_callback_);
191 } 733 }
192 734
193 int FtpNetworkTransaction::DoDataConnectComplete(int result) { 735 int FtpNetworkTransaction::DoDataConnectComplete(int result) {
194 return ERR_FAILED; // TODO(darin): implement me 736 next_state_ = STATE_CTRL_WRITE_SIZE;
737 return result;
195 } 738 }
196 739
197 int FtpNetworkTransaction::DoDataRead() { 740 int FtpNetworkTransaction::DoDataRead() {
198 return ERR_FAILED; // TODO(darin): implement me 741 DCHECK(read_data_buf_);
742 DCHECK(read_data_buf_len_ > 0);
743
744 next_state_ = STATE_DATA_READ_COMPLETE;
745 read_data_buf_->data()[0] = 0;
746 return data_socket_->Read(read_data_buf_->data(),
747 read_data_buf_len_, &io_callback_);
199 } 748 }
200 749
201 int FtpNetworkTransaction::DoDataReadComplete(int result) { 750 int FtpNetworkTransaction::DoDataReadComplete(int result) {
202 return ERR_FAILED; // TODO(darin): implement me 751 DLOG(INFO) << read_data_buf_->data(); // The read_data_buf_ is NULL
752 // terminated string.
753 return result;
203 } 754 }
204 755
205 } // namespace net 756 } // namespace net
OLDNEW
« no previous file with comments | « net/ftp/ftp_network_transaction.h ('k') | net/ftp/ftp_request_info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698