OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 break; | 364 break; |
365 case COMMAND_SIZE: | 365 case COMMAND_SIZE: |
366 rv = ProcessResponseSIZE(response); | 366 rv = ProcessResponseSIZE(response); |
367 break; | 367 break; |
368 case COMMAND_RETR: | 368 case COMMAND_RETR: |
369 rv = ProcessResponseRETR(response); | 369 rv = ProcessResponseRETR(response); |
370 break; | 370 break; |
371 case COMMAND_CWD: | 371 case COMMAND_CWD: |
372 rv = ProcessResponseCWD(response); | 372 rv = ProcessResponseCWD(response); |
373 break; | 373 break; |
374 case COMMAND_MLSD: | |
375 rv = ProcessResponseMLSD(response); | |
376 break; | |
377 case COMMAND_LIST: | 374 case COMMAND_LIST: |
378 rv = ProcessResponseLIST(response); | 375 rv = ProcessResponseLIST(response); |
379 break; | 376 break; |
380 case COMMAND_QUIT: | 377 case COMMAND_QUIT: |
381 rv = ProcessResponseQUIT(response); | 378 rv = ProcessResponseQUIT(response); |
382 break; | 379 break; |
383 default: | 380 default: |
384 LOG(DFATAL) << "Unexpected value of command_sent_: " << command_sent_; | 381 LOG(DFATAL) << "Unexpected value of command_sent_: " << command_sent_; |
385 return ERR_UNEXPECTED; | 382 return ERR_UNEXPECTED; |
386 } | 383 } |
387 | 384 |
388 // We may get multiple responses for some commands, | 385 // We may get multiple responses for some commands, |
389 // see http://crbug.com/18036. | 386 // see http://crbug.com/18036. |
390 while (ctrl_response_buffer_->ResponseAvailable() && rv == OK) { | 387 while (ctrl_response_buffer_->ResponseAvailable() && rv == OK) { |
391 response = ctrl_response_buffer_->PopResponse(); | 388 response = ctrl_response_buffer_->PopResponse(); |
392 | 389 |
393 switch (command_sent_) { | 390 switch (command_sent_) { |
394 case COMMAND_RETR: | 391 case COMMAND_RETR: |
395 rv = ProcessResponseRETR(response); | 392 rv = ProcessResponseRETR(response); |
396 break; | 393 break; |
397 case COMMAND_MLSD: | |
398 rv = ProcessResponseMLSD(response); | |
399 break; | |
400 case COMMAND_LIST: | 394 case COMMAND_LIST: |
401 rv = ProcessResponseLIST(response); | 395 rv = ProcessResponseLIST(response); |
402 break; | 396 break; |
403 default: | 397 default: |
404 // Multiple responses for other commands are invalid. | 398 // Multiple responses for other commands are invalid. |
405 return Stop(ERR_INVALID_RESPONSE); | 399 return Stop(ERR_INVALID_RESPONSE); |
406 } | 400 } |
407 } | 401 } |
408 | 402 |
409 return rv; | 403 return rv; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 rv = DoCtrlWriteRETR(); | 560 rv = DoCtrlWriteRETR(); |
567 break; | 561 break; |
568 case STATE_CTRL_WRITE_SIZE: | 562 case STATE_CTRL_WRITE_SIZE: |
569 DCHECK(rv == OK); | 563 DCHECK(rv == OK); |
570 rv = DoCtrlWriteSIZE(); | 564 rv = DoCtrlWriteSIZE(); |
571 break; | 565 break; |
572 case STATE_CTRL_WRITE_CWD: | 566 case STATE_CTRL_WRITE_CWD: |
573 DCHECK(rv == OK); | 567 DCHECK(rv == OK); |
574 rv = DoCtrlWriteCWD(); | 568 rv = DoCtrlWriteCWD(); |
575 break; | 569 break; |
576 case STATE_CTRL_WRITE_MLSD: | |
577 DCHECK(rv == 0); | |
578 rv = DoCtrlWriteMLSD(); | |
579 break; | |
580 case STATE_CTRL_WRITE_LIST: | 570 case STATE_CTRL_WRITE_LIST: |
581 DCHECK(rv == OK); | 571 DCHECK(rv == OK); |
582 rv = DoCtrlWriteLIST(); | 572 rv = DoCtrlWriteLIST(); |
583 break; | 573 break; |
584 case STATE_CTRL_WRITE_QUIT: | 574 case STATE_CTRL_WRITE_QUIT: |
585 DCHECK(rv == OK); | 575 DCHECK(rv == OK); |
586 rv = DoCtrlWriteQUIT(); | 576 rv = DoCtrlWriteQUIT(); |
587 break; | 577 break; |
588 case STATE_DATA_CONNECT: | 578 case STATE_DATA_CONNECT: |
589 DCHECK(rv == OK); | 579 DCHECK(rv == OK); |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 } | 1056 } |
1067 | 1057 |
1068 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { | 1058 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { |
1069 // We should never issue CWD if we know the target resource is a file. | 1059 // We should never issue CWD if we know the target resource is a file. |
1070 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); | 1060 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); |
1071 | 1061 |
1072 switch (GetErrorClass(response.status_code)) { | 1062 switch (GetErrorClass(response.status_code)) { |
1073 case ERROR_CLASS_INITIATED: | 1063 case ERROR_CLASS_INITIATED: |
1074 return Stop(ERR_INVALID_RESPONSE); | 1064 return Stop(ERR_INVALID_RESPONSE); |
1075 case ERROR_CLASS_OK: | 1065 case ERROR_CLASS_OK: |
1076 next_state_ = STATE_CTRL_WRITE_MLSD; | 1066 next_state_ = STATE_CTRL_WRITE_LIST; |
1077 break; | 1067 break; |
1078 case ERROR_CLASS_INFO_NEEDED: | 1068 case ERROR_CLASS_INFO_NEEDED: |
1079 return Stop(ERR_INVALID_RESPONSE); | 1069 return Stop(ERR_INVALID_RESPONSE); |
1080 case ERROR_CLASS_TRANSIENT_ERROR: | 1070 case ERROR_CLASS_TRANSIENT_ERROR: |
1081 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); | 1071 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); |
1082 case ERROR_CLASS_PERMANENT_ERROR: | 1072 case ERROR_CLASS_PERMANENT_ERROR: |
1083 if (response.status_code == 550) { | 1073 if (response.status_code == 550) { |
1084 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) { | 1074 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) { |
1085 // We're assuming that the resource is a directory, but the server | 1075 // We're assuming that the resource is a directory, but the server |
1086 // says it's not true. The most probable interpretation is that it | 1076 // says it's not true. The most probable interpretation is that it |
(...skipping 10 matching lines...) Expand all Loading... |
1097 } | 1087 } |
1098 | 1088 |
1099 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); | 1089 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); |
1100 default: | 1090 default: |
1101 NOTREACHED(); | 1091 NOTREACHED(); |
1102 return Stop(ERR_UNEXPECTED); | 1092 return Stop(ERR_UNEXPECTED); |
1103 } | 1093 } |
1104 return OK; | 1094 return OK; |
1105 } | 1095 } |
1106 | 1096 |
1107 // MLSD command | |
1108 int FtpNetworkTransaction::DoCtrlWriteMLSD() { | |
1109 next_state_ = STATE_CTRL_READ; | |
1110 return SendFtpCommand("MLSD", COMMAND_MLSD); | |
1111 } | |
1112 | |
1113 int FtpNetworkTransaction::ProcessResponseMLSD( | |
1114 const FtpCtrlResponse& response) { | |
1115 switch (GetErrorClass(response.status_code)) { | |
1116 case ERROR_CLASS_INITIATED: | |
1117 // We want the client to start reading the response at this point. | |
1118 // It got here either through Start or RestartWithAuth. We want that | |
1119 // method to complete. Not setting next state here will make DoLoop exit | |
1120 // and in turn make Start/RestartWithAuth complete. | |
1121 response_.is_directory_listing = true; | |
1122 break; | |
1123 case ERROR_CLASS_OK: | |
1124 response_.is_directory_listing = true; | |
1125 next_state_ = STATE_CTRL_WRITE_QUIT; | |
1126 break; | |
1127 case ERROR_CLASS_INFO_NEEDED: | |
1128 return Stop(ERR_INVALID_RESPONSE); | |
1129 case ERROR_CLASS_TRANSIENT_ERROR: | |
1130 case ERROR_CLASS_PERMANENT_ERROR: | |
1131 // Fallback to the LIST command, more widely supported, | |
1132 // but without a specified output format. | |
1133 next_state_ = STATE_CTRL_WRITE_LIST; | |
1134 break; | |
1135 default: | |
1136 NOTREACHED(); | |
1137 return Stop(ERR_UNEXPECTED); | |
1138 } | |
1139 return OK; | |
1140 } | |
1141 | |
1142 // LIST command | 1097 // LIST command |
1143 int FtpNetworkTransaction::DoCtrlWriteLIST() { | 1098 int FtpNetworkTransaction::DoCtrlWriteLIST() { |
1144 std::string command(system_type_ == SYSTEM_TYPE_VMS ? "LIST *.*;0" : "LIST"); | 1099 std::string command(system_type_ == SYSTEM_TYPE_VMS ? "LIST *.*;0" : "LIST"); |
1145 next_state_ = STATE_CTRL_READ; | 1100 next_state_ = STATE_CTRL_READ; |
1146 return SendFtpCommand(command, COMMAND_LIST); | 1101 return SendFtpCommand(command, COMMAND_LIST); |
1147 } | 1102 } |
1148 | 1103 |
1149 int FtpNetworkTransaction::ProcessResponseLIST( | 1104 int FtpNetworkTransaction::ProcessResponseLIST( |
1150 const FtpCtrlResponse& response) { | 1105 const FtpCtrlResponse& response) { |
1151 switch (GetErrorClass(response.status_code)) { | 1106 switch (GetErrorClass(response.status_code)) { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 if (!had_error_type[type]) { | 1291 if (!had_error_type[type]) { |
1337 had_error_type[type] = true; | 1292 had_error_type[type] = true; |
1338 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1293 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
1339 type, NUM_OF_NET_ERROR_TYPES); | 1294 type, NUM_OF_NET_ERROR_TYPES); |
1340 } | 1295 } |
1341 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1296 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
1342 type, NUM_OF_NET_ERROR_TYPES); | 1297 type, NUM_OF_NET_ERROR_TYPES); |
1343 } | 1298 } |
1344 | 1299 |
1345 } // namespace net | 1300 } // namespace net |
OLD | NEW |