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

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

Issue 2836503002: Handle empty response to FTP QUIT message. (Closed)
Patch Set: Created 3 years, 8 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_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } 211 }
212 212
213 } // namespace 213 } // namespace
214 214
215 FtpNetworkTransaction::FtpNetworkTransaction( 215 FtpNetworkTransaction::FtpNetworkTransaction(
216 HostResolver* resolver, 216 HostResolver* resolver,
217 ClientSocketFactory* socket_factory) 217 ClientSocketFactory* socket_factory)
218 : command_sent_(COMMAND_NONE), 218 : command_sent_(COMMAND_NONE),
219 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, 219 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete,
220 base::Unretained(this))), 220 base::Unretained(this))),
221 request_(NULL), 221 request_(nullptr),
222 resolver_(resolver), 222 resolver_(resolver),
223 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), 223 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)),
224 read_data_buf_len_(0), 224 read_data_buf_len_(0),
225 last_error_(OK), 225 last_error_(OK),
226 system_type_(SYSTEM_TYPE_UNKNOWN), 226 system_type_(SYSTEM_TYPE_UNKNOWN),
227 // Use image (binary) transfer by default. It should always work, 227 // Use image (binary) transfer by default. It should always work,
228 // whereas the ascii transfer may damage binary data. 228 // whereas the ascii transfer may damage binary data.
229 data_type_(DATA_TYPE_IMAGE), 229 data_type_(DATA_TYPE_IMAGE),
230 resource_type_(RESOURCE_TYPE_UNKNOWN), 230 resource_type_(RESOURCE_TYPE_UNKNOWN),
231 use_epsv_(true), 231 use_epsv_(true),
232 data_connection_port_(0), 232 data_connection_port_(0),
233 socket_factory_(socket_factory), 233 socket_factory_(socket_factory),
234 next_state_(STATE_NONE), 234 next_state_(STATE_NONE),
235 state_after_data_connect_complete_(STATE_NONE) { 235 state_after_data_connect_complete_(STATE_NONE) {}
236 }
237 236
238 FtpNetworkTransaction::~FtpNetworkTransaction() { 237 FtpNetworkTransaction::~FtpNetworkTransaction() {
239 } 238 }
240 239
241 int FtpNetworkTransaction::Stop(int error) { 240 int FtpNetworkTransaction::Stop(int error) {
242 if (command_sent_ == COMMAND_QUIT) 241 if (command_sent_ == COMMAND_QUIT) {
243 return error; 242 if (error != ERR_EMPTY_RESPONSE)
243 return error;
244
245 // For empty responses, if this is propagating an error, then it will return
246 // the error. If the error occurred during a QUIT command, then this will
247 // return OK since there was no previous error. Some FTP servers are lazy
248 // and do not bother responding to QUIT commands.
249 // See https://crbug.com/633841
250 return last_error_;
251 }
244 252
245 next_state_ = STATE_CTRL_WRITE_QUIT; 253 next_state_ = STATE_CTRL_WRITE_QUIT;
246 last_error_ = error; 254 last_error_ = error;
247 return OK; 255 return OK;
248 } 256 }
249 257
250 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, 258 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
251 const CompletionCallback& callback, 259 const CompletionCallback& callback,
252 const NetLogWithSource& net_log) { 260 const NetLogWithSource& net_log) {
253 net_log_ = net_log; 261 net_log_ = net_log;
254 request_ = request_info; 262 request_ = request_info;
255 263
256 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_)); 264 ctrl_response_buffer_ = base::MakeUnique<FtpCtrlResponseBuffer>(net_log_);
257 265
258 if (request_->url.has_username()) { 266 if (request_->url.has_username()) {
259 base::string16 username; 267 base::string16 username;
260 base::string16 password; 268 base::string16 password;
261 GetIdentityFromURL(request_->url, &username, &password); 269 GetIdentityFromURL(request_->url, &username, &password);
262 credentials_.Set(username, password); 270 credentials_.Set(username, password);
263 } else { 271 } else {
264 credentials_.Set(base::ASCIIToUTF16("anonymous"), 272 credentials_.Set(base::ASCIIToUTF16("anonymous"),
265 base::ASCIIToUTF16("chrome@example.com")); 273 base::ASCIIToUTF16("chrome@example.com"));
266 } 274 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 340
333 uint64_t FtpNetworkTransaction::GetUploadProgress() const { 341 uint64_t FtpNetworkTransaction::GetUploadProgress() const {
334 return 0; 342 return 0;
335 } 343 }
336 344
337 void FtpNetworkTransaction::ResetStateForRestart() { 345 void FtpNetworkTransaction::ResetStateForRestart() {
338 command_sent_ = COMMAND_NONE; 346 command_sent_ = COMMAND_NONE;
339 user_callback_.Reset(); 347 user_callback_.Reset();
340 response_ = FtpResponseInfo(); 348 response_ = FtpResponseInfo();
341 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); 349 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen);
342 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_)); 350 ctrl_response_buffer_ = base::MakeUnique<FtpCtrlResponseBuffer>(net_log_);
343 read_data_buf_ = NULL; 351 read_data_buf_ = nullptr;
344 read_data_buf_len_ = 0; 352 read_data_buf_len_ = 0;
345 if (write_buf_.get()) 353 if (write_buf_.get())
346 write_buf_->SetOffset(0); 354 write_buf_->SetOffset(0);
347 last_error_ = OK; 355 last_error_ = OK;
348 data_connection_port_ = 0; 356 data_connection_port_ = 0;
349 ctrl_socket_.reset(); 357 ctrl_socket_.reset();
350 data_socket_.reset(); 358 data_socket_.reset();
351 next_state_ = STATE_NONE; 359 next_state_ = STATE_NONE;
352 state_after_data_connect_complete_ = STATE_NONE; 360 state_after_data_connect_complete_ = STATE_NONE;
353 } 361 }
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 668
661 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { 669 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) {
662 if (result == OK) 670 if (result == OK)
663 next_state_ = STATE_CTRL_CONNECT; 671 next_state_ = STATE_CTRL_CONNECT;
664 return result; 672 return result;
665 } 673 }
666 674
667 int FtpNetworkTransaction::DoCtrlConnect() { 675 int FtpNetworkTransaction::DoCtrlConnect() {
668 next_state_ = STATE_CTRL_CONNECT_COMPLETE; 676 next_state_ = STATE_CTRL_CONNECT_COMPLETE;
669 ctrl_socket_ = socket_factory_->CreateTransportClientSocket( 677 ctrl_socket_ = socket_factory_->CreateTransportClientSocket(
670 addresses_, NULL, net_log_.net_log(), net_log_.source()); 678 addresses_, nullptr, net_log_.net_log(), net_log_.source());
671 net_log_.AddEvent( 679 net_log_.AddEvent(
672 NetLogEventType::FTP_CONTROL_CONNECTION, 680 NetLogEventType::FTP_CONTROL_CONNECTION,
673 ctrl_socket_->NetLog().source().ToEventParametersCallback()); 681 ctrl_socket_->NetLog().source().ToEventParametersCallback());
674 return ctrl_socket_->Connect(io_callback_); 682 return ctrl_socket_->Connect(io_callback_);
675 } 683 }
676 684
677 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { 685 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) {
678 if (result == OK) { 686 if (result == OK) {
679 // Put the peer's IP address and port into the response. 687 // Put the peer's IP address and port into the response.
680 IPEndPoint ip_endpoint; 688 IPEndPoint ip_endpoint;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 write_buf_.get(), write_buf_->BytesRemaining(), io_callback_); 741 write_buf_.get(), write_buf_->BytesRemaining(), io_callback_);
734 } 742 }
735 743
736 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { 744 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) {
737 if (result < 0) 745 if (result < 0)
738 return result; 746 return result;
739 747
740 write_buf_->DidConsume(result); 748 write_buf_->DidConsume(result);
741 if (write_buf_->BytesRemaining() == 0) { 749 if (write_buf_->BytesRemaining() == 0) {
742 // Clear the write buffer. 750 // Clear the write buffer.
743 write_buf_ = NULL; 751 write_buf_ = nullptr;
744 write_command_buf_ = NULL; 752 write_command_buf_ = nullptr;
745 753
746 next_state_ = STATE_CTRL_READ; 754 next_state_ = STATE_CTRL_READ;
747 } else { 755 } else {
748 next_state_ = STATE_CTRL_WRITE; 756 next_state_ = STATE_CTRL_WRITE;
749 } 757 }
750 return OK; 758 return OK;
751 } 759 }
752 760
753 // FTP Commands and responses 761 // FTP Commands and responses
754 762
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 IPEndPoint ip_endpoint; 1221 IPEndPoint ip_endpoint;
1214 AddressList data_address; 1222 AddressList data_address;
1215 // Connect to the same host as the control socket to prevent PASV port 1223 // Connect to the same host as the control socket to prevent PASV port
1216 // scanning attacks. 1224 // scanning attacks.
1217 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); 1225 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint);
1218 if (rv != OK) 1226 if (rv != OK)
1219 return Stop(rv); 1227 return Stop(rv);
1220 data_address = AddressList::CreateFromIPAddress( 1228 data_address = AddressList::CreateFromIPAddress(
1221 ip_endpoint.address(), data_connection_port_); 1229 ip_endpoint.address(), data_connection_port_);
1222 data_socket_ = socket_factory_->CreateTransportClientSocket( 1230 data_socket_ = socket_factory_->CreateTransportClientSocket(
1223 data_address, NULL, net_log_.net_log(), net_log_.source()); 1231 data_address, nullptr, net_log_.net_log(), net_log_.source());
1224 net_log_.AddEvent( 1232 net_log_.AddEvent(
1225 NetLogEventType::FTP_DATA_CONNECTION, 1233 NetLogEventType::FTP_DATA_CONNECTION,
1226 data_socket_->NetLog().source().ToEventParametersCallback()); 1234 data_socket_->NetLog().source().ToEventParametersCallback());
1227 return data_socket_->Connect(io_callback_); 1235 return data_socket_->Connect(io_callback_);
1228 } 1236 }
1229 1237
1230 int FtpNetworkTransaction::DoDataConnectComplete(int result) { 1238 int FtpNetworkTransaction::DoDataConnectComplete(int result) {
1231 if (result != OK && use_epsv_) { 1239 if (result != OK && use_epsv_) {
1232 // It's possible we hit a broken server, sadly. They can break in different 1240 // It's possible we hit a broken server, sadly. They can break in different
1233 // ways. Some time out, some reset a connection. Fall back to PASV. 1241 // ways. Some time out, some reset a connection. Fall back to PASV.
(...skipping 12 matching lines...) Expand all
1246 return Stop(result); 1254 return Stop(result);
1247 1255
1248 next_state_ = state_after_data_connect_complete_; 1256 next_state_ = state_after_data_connect_complete_;
1249 return OK; 1257 return OK;
1250 } 1258 }
1251 1259
1252 int FtpNetworkTransaction::DoDataRead() { 1260 int FtpNetworkTransaction::DoDataRead() {
1253 DCHECK(read_data_buf_.get()); 1261 DCHECK(read_data_buf_.get());
1254 DCHECK_GT(read_data_buf_len_, 0); 1262 DCHECK_GT(read_data_buf_len_, 0);
1255 1263
1256 if (data_socket_ == NULL || !data_socket_->IsConnected()) { 1264 if (!data_socket_ || !data_socket_->IsConnected()) {
1257 // If we don't destroy the data socket completely, some servers will wait 1265 // If we don't destroy the data socket completely, some servers will wait
1258 // for us (http://crbug.com/21127). The half-closed TCP connection needs 1266 // for us (http://crbug.com/21127). The half-closed TCP connection needs
1259 // to be closed on our side too. 1267 // to be closed on our side too.
1260 data_socket_.reset(); 1268 data_socket_.reset();
1261 1269
1262 if (ctrl_socket_->IsConnected()) { 1270 if (ctrl_socket_->IsConnected()) {
1263 // Wait for the server's response, we should get it before sending QUIT. 1271 // Wait for the server's response, we should get it before sending QUIT.
1264 next_state_ = STATE_CTRL_READ; 1272 next_state_ = STATE_CTRL_READ;
1265 return OK; 1273 return OK;
1266 } 1274 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 if (!had_error_type[type]) { 1369 if (!had_error_type[type]) {
1362 had_error_type[type] = true; 1370 had_error_type[type] = true;
1363 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", 1371 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened",
1364 type, NUM_OF_NET_ERROR_TYPES); 1372 type, NUM_OF_NET_ERROR_TYPES);
1365 } 1373 }
1366 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", 1374 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount",
1367 type, NUM_OF_NET_ERROR_TYPES); 1375 type, NUM_OF_NET_ERROR_TYPES);
1368 } 1376 }
1369 1377
1370 } // namespace net 1378 } // 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