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

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

Issue 891013002: Clean up FTPNetworkTransaction to match the latest trace (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 232
233 int FtpNetworkTransaction::Stop(int error) { 233 int FtpNetworkTransaction::Stop(int error) {
234 if (command_sent_ == COMMAND_QUIT) 234 if (command_sent_ == COMMAND_QUIT)
235 return error; 235 return error;
236 236
237 next_state_ = STATE_CTRL_WRITE_QUIT; 237 next_state_ = STATE_CTRL_WRITE_QUIT;
238 last_error_ = error; 238 last_error_ = error;
239 return OK; 239 return OK;
240 } 240 }
241 241
242 int FtpNetworkTransaction::RestartIgnoringLastError(
xunjieli 2015/01/30 21:50:44 This is never used anywhere. Is it okay to remove
davidben 2015/02/04 18:51:18 Sounds good. :-)
243 const CompletionCallback& callback) {
244 return ERR_NOT_IMPLEMENTED;
245 }
246
247 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, 242 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
248 const CompletionCallback& callback, 243 const CompletionCallback& callback,
249 const BoundNetLog& net_log) { 244 const BoundNetLog& net_log) {
250 net_log_ = net_log; 245 net_log_ = net_log;
251 request_ = request_info; 246 request_ = request_info;
252 247
253 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_)); 248 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_));
254 249
255 if (request_->url.has_username()) { 250 if (request_->url.has_username()) {
256 base::string16 username; 251 base::string16 username;
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 1021
1027 // RETR command 1022 // RETR command
1028 int FtpNetworkTransaction::DoCtrlWriteRETR() { 1023 int FtpNetworkTransaction::DoCtrlWriteRETR() {
1029 std::string command = "RETR " + GetRequestPathForFtpCommand(false); 1024 std::string command = "RETR " + GetRequestPathForFtpCommand(false);
1030 next_state_ = STATE_CTRL_READ; 1025 next_state_ = STATE_CTRL_READ;
1031 return SendFtpCommand(command, command, COMMAND_RETR); 1026 return SendFtpCommand(command, command, COMMAND_RETR);
1032 } 1027 }
1033 1028
1034 int FtpNetworkTransaction::ProcessResponseRETR( 1029 int FtpNetworkTransaction::ProcessResponseRETR(
1035 const FtpCtrlResponse& response) { 1030 const FtpCtrlResponse& response) {
1031 // Resource type should be either filled in by DetectTypecode() or
1032 // detected with CWD. RETR is sent only when the resource is a file.
1033 DCHECK_EQ(RESOURCE_TYPE_FILE, resource_type_);
1034
1036 switch (GetErrorClass(response.status_code)) { 1035 switch (GetErrorClass(response.status_code)) {
1037 case ERROR_CLASS_INITIATED: 1036 case ERROR_CLASS_INITIATED:
1038 // We want the client to start reading the response at this point. 1037 // We want the client to start reading the response at this point.
1039 // It got here either through Start or RestartWithAuth. We want that 1038 // It got here either through Start or RestartWithAuth. We want that
1040 // method to complete. Not setting next state here will make DoLoop exit 1039 // method to complete. Not setting next state here will make DoLoop exit
1041 // and in turn make Start/RestartWithAuth complete. 1040 // and in turn make Start/RestartWithAuth complete.
1042 resource_type_ = RESOURCE_TYPE_FILE;
1043 break; 1041 break;
1044 case ERROR_CLASS_OK: 1042 case ERROR_CLASS_OK:
1045 resource_type_ = RESOURCE_TYPE_FILE;
1046 next_state_ = STATE_CTRL_WRITE_QUIT; 1043 next_state_ = STATE_CTRL_WRITE_QUIT;
1047 break; 1044 break;
1048 case ERROR_CLASS_INFO_NEEDED: 1045 case ERROR_CLASS_INFO_NEEDED:
1049 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1046 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1050 case ERROR_CLASS_TRANSIENT_ERROR: 1047 case ERROR_CLASS_TRANSIENT_ERROR:
1051 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1048 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1052 case ERROR_CLASS_PERMANENT_ERROR: 1049 case ERROR_CLASS_PERMANENT_ERROR:
1053 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1050 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1054 default: 1051 default:
1055 NOTREACHED(); 1052 NOTREACHED();
1056 return Stop(ERR_UNEXPECTED); 1053 return Stop(ERR_UNEXPECTED);
1057 } 1054 }
1058 1055
1059 // We should be sure about our resource type now. Otherwise we risk
1060 // an infinite loop (RETR can later send CWD, and CWD can later send RETR).
1061 DCHECK_NE(RESOURCE_TYPE_UNKNOWN, resource_type_);
1062
1063 return OK; 1056 return OK;
1064 } 1057 }
1065 1058
1066 // SIZE command 1059 // SIZE command
1067 int FtpNetworkTransaction::DoCtrlWriteSIZE() { 1060 int FtpNetworkTransaction::DoCtrlWriteSIZE() {
1068 std::string command = "SIZE " + GetRequestPathForFtpCommand(false); 1061 std::string command = "SIZE " + GetRequestPathForFtpCommand(false);
1069 next_state_ = STATE_CTRL_READ; 1062 next_state_ = STATE_CTRL_READ;
1070 return SendFtpCommand(command, command, COMMAND_SIZE); 1063 return SendFtpCommand(command, command, COMMAND_SIZE);
1071 } 1064 }
1072 1065
(...skipping 18 matching lines...) Expand all
1091 break; 1084 break;
1092 case ERROR_CLASS_INFO_NEEDED: 1085 case ERROR_CLASS_INFO_NEEDED:
1093 break; 1086 break;
1094 case ERROR_CLASS_TRANSIENT_ERROR: 1087 case ERROR_CLASS_TRANSIENT_ERROR:
1095 break; 1088 break;
1096 case ERROR_CLASS_PERMANENT_ERROR: 1089 case ERROR_CLASS_PERMANENT_ERROR:
1097 // It's possible that SIZE failed because the path is a directory. 1090 // It's possible that SIZE failed because the path is a directory.
1098 if (resource_type_ == RESOURCE_TYPE_UNKNOWN && 1091 if (resource_type_ == RESOURCE_TYPE_UNKNOWN &&
1099 response.status_code != 550) { 1092 response.status_code != 550) {
1100 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1093 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1101 } 1094 }
davidben 2015/02/04 18:51:18 Do you know what this code does? I'm confused what
xunjieli 2015/02/04 20:29:29 The Stop case is not tested in the code. I think i
1102 break; 1095 break;
1103 default: 1096 default:
1104 NOTREACHED(); 1097 NOTREACHED();
1105 return Stop(ERR_UNEXPECTED); 1098 return Stop(ERR_UNEXPECTED);
1106 } 1099 }
1107 if (resource_type_ == RESOURCE_TYPE_FILE) 1100 if (resource_type_ == RESOURCE_TYPE_FILE)
1108 EstablishDataConnection(STATE_CTRL_WRITE_RETR); 1101 EstablishDataConnection(STATE_CTRL_WRITE_RETR);
1109 else 1102 else
1110 next_state_ = STATE_CTRL_WRITE_CWD; 1103 next_state_ = STATE_CTRL_WRITE_CWD;
1111 return OK; 1104 return OK;
1112 } 1105 }
1113 1106
1114 // CWD command 1107 // CWD command
1115 int FtpNetworkTransaction::DoCtrlWriteCWD() { 1108 int FtpNetworkTransaction::DoCtrlWriteCWD() {
1116 std::string command = "CWD " + GetRequestPathForFtpCommand(true); 1109 std::string command = "CWD " + GetRequestPathForFtpCommand(true);
1117 next_state_ = STATE_CTRL_READ; 1110 next_state_ = STATE_CTRL_READ;
1118 return SendFtpCommand(command, command, COMMAND_CWD); 1111 return SendFtpCommand(command, command, COMMAND_CWD);
1119 } 1112 }
1120 1113
1121 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { 1114 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) {
1122 // We should never issue CWD if we know the target resource is a file. 1115 // CWD should be invoked only when the resource is not a file.
1123 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); 1116 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_);
1124 1117
1125 switch (GetErrorClass(response.status_code)) { 1118 switch (GetErrorClass(response.status_code)) {
1126 case ERROR_CLASS_INITIATED: 1119 case ERROR_CLASS_INITIATED:
1127 return Stop(ERR_INVALID_RESPONSE); 1120 return Stop(ERR_INVALID_RESPONSE);
1128 case ERROR_CLASS_OK: 1121 case ERROR_CLASS_OK:
1122 resource_type_ = RESOURCE_TYPE_DIRECTORY;
1129 EstablishDataConnection(STATE_CTRL_WRITE_LIST); 1123 EstablishDataConnection(STATE_CTRL_WRITE_LIST);
1130 break; 1124 break;
1131 case ERROR_CLASS_INFO_NEEDED: 1125 case ERROR_CLASS_INFO_NEEDED:
1132 return Stop(ERR_INVALID_RESPONSE); 1126 return Stop(ERR_INVALID_RESPONSE);
1133 case ERROR_CLASS_TRANSIENT_ERROR: 1127 case ERROR_CLASS_TRANSIENT_ERROR:
1134 // Some FTP servers send response 451 (not a valid CWD response according 1128 // Some FTP servers send response 451 (not a valid CWD response according
1135 // to RFC 959) instead of 550. 1129 // to RFC 959) instead of 550.
1136 if (response.status_code == 451) 1130 if (response.status_code == 451)
1137 return ProcessResponseCWDNotADirectory(); 1131 return ProcessResponseCWDNotADirectory();
1138 1132
1139 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1133 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1140 case ERROR_CLASS_PERMANENT_ERROR: 1134 case ERROR_CLASS_PERMANENT_ERROR:
1141 if (response.status_code == 550) 1135 if (response.status_code == 550)
1142 return ProcessResponseCWDNotADirectory(); 1136 return ProcessResponseCWDNotADirectory();
1143 1137
1144 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1138 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1145 default: 1139 default:
1146 NOTREACHED(); 1140 NOTREACHED();
1147 return Stop(ERR_UNEXPECTED); 1141 return Stop(ERR_UNEXPECTED);
1148 } 1142 }
1149 1143
1150 return OK; 1144 return OK;
1151 } 1145 }
1152 1146
1153 int FtpNetworkTransaction::ProcessResponseCWDNotADirectory() { 1147 int FtpNetworkTransaction::ProcessResponseCWDNotADirectory() {
1154 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) { 1148 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) {
davidben 2015/02/05 19:42:57 Oof, I'm sorry! I was wrong that RESOURCE_TYPE_UNK
xunjieli 2015/02/05 20:21:57 Done. Hmm yep, saving a RETR is probably better th
1155 // We're assuming that the resource is a directory, but the server 1149 // We're assuming that the resource is a directory, but the server
1156 // says it's not true. The most probable interpretation is that it 1150 // says it's not true. The most probable interpretation is that it
1157 // doesn't exist (with FTP we can't be sure). 1151 // doesn't exist (with FTP we can't be sure).
1158 return Stop(ERR_FILE_NOT_FOUND); 1152 return Stop(ERR_FILE_NOT_FOUND);
1159 } 1153 }
1160 1154
1161 // We are here because SIZE failed and we are not sure what the resource 1155 // If it is not a directory, it is probably a file.
1162 // type is. It could still be file, and SIZE could fail because of
1163 // an access error (http://crbug.com/56734). Try RETR just to be sure.
1164 resource_type_ = RESOURCE_TYPE_FILE; 1156 resource_type_ = RESOURCE_TYPE_FILE;
1165 1157
1166 EstablishDataConnection(STATE_CTRL_WRITE_RETR); 1158 EstablishDataConnection(STATE_CTRL_WRITE_RETR);
1167 return OK; 1159 return OK;
1168 } 1160 }
1169 1161
1170 // LIST command 1162 // LIST command
1171 int FtpNetworkTransaction::DoCtrlWriteLIST() { 1163 int FtpNetworkTransaction::DoCtrlWriteLIST() {
1172 // Use the -l option for mod_ftp configured in LISTIsNLST mode: the option 1164 // Use the -l option for mod_ftp configured in LISTIsNLST mode: the option
1173 // forces LIST output instead of NLST (which would be ambiguous for us 1165 // forces LIST output instead of NLST (which would be ambiguous for us
1174 // to parse). 1166 // to parse).
1175 std::string command("LIST -l"); 1167 std::string command("LIST -l");
xunjieli 2015/01/30 21:50:44 I wonder if we should remove "-l". This is not a p
davidben 2015/02/04 18:51:18 Hrm. Apparently it was added in https://chromiumco
xunjieli 2015/02/04 20:29:29 Sounds good to me. no easy way around this I gues
1176 if (system_type_ == SYSTEM_TYPE_VMS) 1168 if (system_type_ == SYSTEM_TYPE_VMS)
1177 command = "LIST *.*;0"; 1169 command = "LIST *.*;0";
1178 1170
1179 next_state_ = STATE_CTRL_READ; 1171 next_state_ = STATE_CTRL_READ;
1180 return SendFtpCommand(command, command, COMMAND_LIST); 1172 return SendFtpCommand(command, command, COMMAND_LIST);
1181 } 1173 }
1182 1174
1183 int FtpNetworkTransaction::ProcessResponseLIST( 1175 int FtpNetworkTransaction::ProcessResponseLIST(
1184 const FtpCtrlResponse& response) { 1176 const FtpCtrlResponse& response) {
1177 // Resource type should be either filled in by DetectTypecode() or
1178 // detected with CWD. LIST is sent only when the resource is a directory.
1179 DCHECK_EQ(RESOURCE_TYPE_DIRECTORY, resource_type_);
1180
1185 switch (GetErrorClass(response.status_code)) { 1181 switch (GetErrorClass(response.status_code)) {
1186 case ERROR_CLASS_INITIATED: 1182 case ERROR_CLASS_INITIATED:
1187 // We want the client to start reading the response at this point. 1183 // We want the client to start reading the response at this point.
1188 // It got here either through Start or RestartWithAuth. We want that 1184 // It got here either through Start or RestartWithAuth. We want that
1189 // method to complete. Not setting next state here will make DoLoop exit 1185 // method to complete. Not setting next state here will make DoLoop exit
1190 // and in turn make Start/RestartWithAuth complete. 1186 // and in turn make Start/RestartWithAuth complete.
1191 response_.is_directory_listing = true; 1187 response_.is_directory_listing = true;
1192 break; 1188 break;
1193 case ERROR_CLASS_OK: 1189 case ERROR_CLASS_OK:
1194 response_.is_directory_listing = true; 1190 response_.is_directory_listing = true;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 if (!had_error_type[type]) { 1371 if (!had_error_type[type]) {
1376 had_error_type[type] = true; 1372 had_error_type[type] = true;
1377 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", 1373 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened",
1378 type, NUM_OF_NET_ERROR_TYPES); 1374 type, NUM_OF_NET_ERROR_TYPES);
1379 } 1375 }
1380 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", 1376 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount",
1381 type, NUM_OF_NET_ERROR_TYPES); 1377 type, NUM_OF_NET_ERROR_TYPES);
1382 } 1378 }
1383 1379
1384 } // namespace net 1380 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698