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

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

Issue 903273002: Update from https://crrev.com/315085 (Closed) Base URL: git@github.com:domokit/mojo.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
« no previous file with comments | « net/ftp/ftp_network_transaction.h ('k') | net/ftp/ftp_network_transaction_unittest.cc » ('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) 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(
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 15 matching lines...) Expand all
1088 // Some FTP servers (for example, the qnx one) send a SIZE even for 1081 // Some FTP servers (for example, the qnx one) send a SIZE even for
1089 // directories. 1082 // directories.
1090 response_.expected_content_size = size; 1083 response_.expected_content_size = size;
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.
1091 // TODO(xunjieli): Add a test for this case.
1098 if (resource_type_ == RESOURCE_TYPE_UNKNOWN && 1092 if (resource_type_ == RESOURCE_TYPE_UNKNOWN &&
1099 response.status_code != 550) { 1093 response.status_code != 550) {
1100 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); 1094 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1101 } 1095 }
1102 break; 1096 break;
1103 default: 1097 default:
1104 NOTREACHED(); 1098 NOTREACHED();
1105 return Stop(ERR_UNEXPECTED); 1099 return Stop(ERR_UNEXPECTED);
1106 } 1100 }
1101
1102 // If the resource is known beforehand to be a file, RETR should be issued,
1103 // otherwise do CWD which will detect the resource type.
1107 if (resource_type_ == RESOURCE_TYPE_FILE) 1104 if (resource_type_ == RESOURCE_TYPE_FILE)
1108 EstablishDataConnection(STATE_CTRL_WRITE_RETR); 1105 EstablishDataConnection(STATE_CTRL_WRITE_RETR);
1109 else 1106 else
1110 next_state_ = STATE_CTRL_WRITE_CWD; 1107 next_state_ = STATE_CTRL_WRITE_CWD;
1111 return OK; 1108 return OK;
1112 } 1109 }
1113 1110
1114 // CWD command 1111 // CWD command
1115 int FtpNetworkTransaction::DoCtrlWriteCWD() { 1112 int FtpNetworkTransaction::DoCtrlWriteCWD() {
1116 std::string command = "CWD " + GetRequestPathForFtpCommand(true); 1113 std::string command = "CWD " + GetRequestPathForFtpCommand(true);
1117 next_state_ = STATE_CTRL_READ; 1114 next_state_ = STATE_CTRL_READ;
1118 return SendFtpCommand(command, command, COMMAND_CWD); 1115 return SendFtpCommand(command, command, COMMAND_CWD);
1119 } 1116 }
1120 1117
1121 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { 1118 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) {
1122 // We should never issue CWD if we know the target resource is a file. 1119 // CWD should be invoked only when the resource is not a file.
1123 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); 1120 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_);
1124 1121
1125 switch (GetErrorClass(response.status_code)) { 1122 switch (GetErrorClass(response.status_code)) {
1126 case ERROR_CLASS_INITIATED: 1123 case ERROR_CLASS_INITIATED:
1127 return Stop(ERR_INVALID_RESPONSE); 1124 return Stop(ERR_INVALID_RESPONSE);
1128 case ERROR_CLASS_OK: 1125 case ERROR_CLASS_OK:
1126 resource_type_ = RESOURCE_TYPE_DIRECTORY;
1129 EstablishDataConnection(STATE_CTRL_WRITE_LIST); 1127 EstablishDataConnection(STATE_CTRL_WRITE_LIST);
1130 break; 1128 break;
1131 case ERROR_CLASS_INFO_NEEDED: 1129 case ERROR_CLASS_INFO_NEEDED:
1132 return Stop(ERR_INVALID_RESPONSE); 1130 return Stop(ERR_INVALID_RESPONSE);
1133 case ERROR_CLASS_TRANSIENT_ERROR: 1131 case ERROR_CLASS_TRANSIENT_ERROR:
1134 // Some FTP servers send response 451 (not a valid CWD response according 1132 // Some FTP servers send response 451 (not a valid CWD response according
1135 // to RFC 959) instead of 550. 1133 // to RFC 959) instead of 550.
1136 if (response.status_code == 451) 1134 if (response.status_code == 451)
1137 return ProcessResponseCWDNotADirectory(); 1135 return ProcessResponseCWDNotADirectory();
1138 1136
(...skipping 12 matching lines...) Expand all
1151 } 1149 }
1152 1150
1153 int FtpNetworkTransaction::ProcessResponseCWDNotADirectory() { 1151 int FtpNetworkTransaction::ProcessResponseCWDNotADirectory() {
1154 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) { 1152 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) {
1155 // We're assuming that the resource is a directory, but the server 1153 // 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 1154 // says it's not true. The most probable interpretation is that it
1157 // doesn't exist (with FTP we can't be sure). 1155 // doesn't exist (with FTP we can't be sure).
1158 return Stop(ERR_FILE_NOT_FOUND); 1156 return Stop(ERR_FILE_NOT_FOUND);
1159 } 1157 }
1160 1158
1161 // We are here because SIZE failed and we are not sure what the resource 1159 // 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; 1160 resource_type_ = RESOURCE_TYPE_FILE;
1165 1161
1166 EstablishDataConnection(STATE_CTRL_WRITE_RETR); 1162 EstablishDataConnection(STATE_CTRL_WRITE_RETR);
1167 return OK; 1163 return OK;
1168 } 1164 }
1169 1165
1170 // LIST command 1166 // LIST command
1171 int FtpNetworkTransaction::DoCtrlWriteLIST() { 1167 int FtpNetworkTransaction::DoCtrlWriteLIST() {
1172 // Use the -l option for mod_ftp configured in LISTIsNLST mode: the option 1168 // 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 1169 // forces LIST output instead of NLST (which would be ambiguous for us
1174 // to parse). 1170 // to parse).
1175 std::string command("LIST -l"); 1171 std::string command("LIST -l");
1176 if (system_type_ == SYSTEM_TYPE_VMS) 1172 if (system_type_ == SYSTEM_TYPE_VMS)
1177 command = "LIST *.*;0"; 1173 command = "LIST *.*;0";
1178 1174
1179 next_state_ = STATE_CTRL_READ; 1175 next_state_ = STATE_CTRL_READ;
1180 return SendFtpCommand(command, command, COMMAND_LIST); 1176 return SendFtpCommand(command, command, COMMAND_LIST);
1181 } 1177 }
1182 1178
1183 int FtpNetworkTransaction::ProcessResponseLIST( 1179 int FtpNetworkTransaction::ProcessResponseLIST(
1184 const FtpCtrlResponse& response) { 1180 const FtpCtrlResponse& response) {
1181 // Resource type should be either filled in by DetectTypecode() or
1182 // detected with CWD. LIST is sent only when the resource is a directory.
1183 DCHECK_EQ(RESOURCE_TYPE_DIRECTORY, resource_type_);
1184
1185 switch (GetErrorClass(response.status_code)) { 1185 switch (GetErrorClass(response.status_code)) {
1186 case ERROR_CLASS_INITIATED: 1186 case ERROR_CLASS_INITIATED:
1187 // We want the client to start reading the response at this point. 1187 // We want the client to start reading the response at this point.
1188 // It got here either through Start or RestartWithAuth. We want that 1188 // It got here either through Start or RestartWithAuth. We want that
1189 // method to complete. Not setting next state here will make DoLoop exit 1189 // method to complete. Not setting next state here will make DoLoop exit
1190 // and in turn make Start/RestartWithAuth complete. 1190 // and in turn make Start/RestartWithAuth complete.
1191 response_.is_directory_listing = true; 1191 response_.is_directory_listing = true;
1192 break; 1192 break;
1193 case ERROR_CLASS_OK: 1193 case ERROR_CLASS_OK:
1194 response_.is_directory_listing = true; 1194 response_.is_directory_listing = true;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 if (!had_error_type[type]) { 1375 if (!had_error_type[type]) {
1376 had_error_type[type] = true; 1376 had_error_type[type] = true;
1377 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", 1377 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened",
1378 type, NUM_OF_NET_ERROR_TYPES); 1378 type, NUM_OF_NET_ERROR_TYPES);
1379 } 1379 }
1380 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", 1380 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount",
1381 type, NUM_OF_NET_ERROR_TYPES); 1381 type, NUM_OF_NET_ERROR_TYPES);
1382 } 1382 }
1383 1383
1384 } // namespace net 1384 } // namespace net
OLDNEW
« no previous file with comments | « net/ftp/ftp_network_transaction.h ('k') | net/ftp/ftp_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698