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

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

Issue 160537: Correctly handle multiple control responses for RETR command. (Closed)
Patch Set: Created 11 years, 4 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_ctrl_response_buffer.cc ('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) 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/string_util.h" 8 #include "base/string_util.h"
9 #include "net/base/connection_type_histograms.h" 9 #include "net/base/connection_type_histograms.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 return LOAD_STATE_IDLE; 103 return LOAD_STATE_IDLE;
104 } 104 }
105 105
106 uint64 FtpNetworkTransaction::GetUploadProgress() const { 106 uint64 FtpNetworkTransaction::GetUploadProgress() const {
107 return 0; 107 return 0;
108 } 108 }
109 109
110 // Used to prepare and send FTP commad. 110 // Used to prepare and send FTP commad.
111 int FtpNetworkTransaction::SendFtpCommand(const std::string& command, 111 int FtpNetworkTransaction::SendFtpCommand(const std::string& command,
112 Command cmd) { 112 Command cmd) {
113 // If we send a new command when we still have unprocessed responses
114 // for previous commands, the response receiving code will have no way to know
115 // which responses are for which command.
116 DCHECK(!ctrl_response_buffer_.ResponseAvailable());
117
113 DCHECK(!write_command_buf_); 118 DCHECK(!write_command_buf_);
114 DCHECK(!write_buf_); 119 DCHECK(!write_buf_);
115 DLOG(INFO) << " >> " << command; 120 DLOG(INFO) << " >> " << command;
116 121
117 command_sent_ = cmd; 122 command_sent_ = cmd;
118 write_buf_written_ = 0; 123 write_buf_written_ = 0;
119 write_command_buf_ = new IOBufferWithSize(command.length() + 2); 124 write_command_buf_ = new IOBufferWithSize(command.length() + 2);
120 write_buf_ = new ReusedIOBuffer(write_command_buf_, 125 write_buf_ = new ReusedIOBuffer(write_command_buf_,
121 write_command_buf_->size()); 126 write_command_buf_->size());
122 memcpy(write_command_buf_->data(), command.data(), command.length()); 127 memcpy(write_command_buf_->data(), command.data(), command.length());
123 memcpy(write_command_buf_->data() + command.length(), kCRLF, 2); 128 memcpy(write_command_buf_->data() + command.length(), kCRLF, 2);
124 129
125 next_state_ = STATE_CTRL_WRITE_COMMAND; 130 next_state_ = STATE_CTRL_WRITE_COMMAND;
126 return OK; 131 return OK;
127 } 132 }
128 133
129 int FtpNetworkTransaction::ProcessCtrlResponse() { 134 int FtpNetworkTransaction::ProcessCtrlResponse() {
130 FtpCtrlResponse response = ctrl_response_buffer_.PopResponse(); 135 FtpCtrlResponse response = ctrl_response_buffer_.PopResponse();
wtc 2009/08/04 23:46:30 Should this function empty ctrl_response_buffer_ b
131 136
132 // TODO(phajdan.jr): Remove when http://crbug.com/18036 is diagnosed.
133 DLOG(INFO) << "Consumed one control response.";
134
135 // We always expect only one response, even if it's multiline.
136 DCHECK(!ctrl_response_buffer_.ResponseAvailable());
137
138 int rv = OK; 137 int rv = OK;
139 switch (command_sent_) { 138 switch (command_sent_) {
140 case COMMAND_NONE: 139 case COMMAND_NONE:
141 // TODO(phajdan.jr): Check for errors in the welcome message. 140 // TODO(phajdan.jr): Check for errors in the welcome message.
142 next_state_ = STATE_CTRL_WRITE_USER; 141 next_state_ = STATE_CTRL_WRITE_USER;
143 break; 142 break;
144 case COMMAND_USER: 143 case COMMAND_USER:
145 rv = ProcessResponseUSER(response); 144 rv = ProcessResponseUSER(response);
146 break; 145 break;
147 case COMMAND_PASS: 146 case COMMAND_PASS:
(...skipping 29 matching lines...) Expand all
177 case COMMAND_MDTM: 176 case COMMAND_MDTM:
178 rv = ProcessResponseMDTM(response); 177 rv = ProcessResponseMDTM(response);
179 break; 178 break;
180 case COMMAND_QUIT: 179 case COMMAND_QUIT:
181 rv = ProcessResponseQUIT(response); 180 rv = ProcessResponseQUIT(response);
182 break; 181 break;
183 default: 182 default:
184 DLOG(INFO) << "Missing Command response handling!"; 183 DLOG(INFO) << "Missing Command response handling!";
185 return ERR_FAILED; 184 return ERR_FAILED;
186 } 185 }
186
187 // We may get multiple responses for some commands,
188 // see http://crbug.com/18036.
189 while (ctrl_response_buffer_.ResponseAvailable() && rv == OK) {
190 response = ctrl_response_buffer_.PopResponse();
191
192 switch (command_sent_) {
193 case COMMAND_RETR:
194 rv = ProcessResponseRETR(response);
195 break;
196 default:
197 // Multiple responses for other commands are invalid.
198 return ERR_INVALID_RESPONSE;
199 }
200 }
201
187 return rv; 202 return rv;
188 } 203 }
189 204
190 void FtpNetworkTransaction::DoCallback(int rv) { 205 void FtpNetworkTransaction::DoCallback(int rv) {
191 DCHECK(rv != ERR_IO_PENDING); 206 DCHECK(rv != ERR_IO_PENDING);
192 DCHECK(user_callback_); 207 DCHECK(user_callback_);
193 208
194 // Since Run may result in Read being called, clear callback_ up front. 209 // Since Run may result in Read being called, clear callback_ up front.
195 CompletionCallback* c = user_callback_; 210 CompletionCallback* c = user_callback_;
196 user_callback_ = NULL; 211 user_callback_ = NULL;
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 command.append(" /"); 733 command.append(" /");
719 } 734 }
720 next_state_ = STATE_CTRL_READ; 735 next_state_ = STATE_CTRL_READ;
721 return SendFtpCommand(command, COMMAND_RETR); 736 return SendFtpCommand(command, COMMAND_RETR);
722 } 737 }
723 738
724 int FtpNetworkTransaction::ProcessResponseRETR( 739 int FtpNetworkTransaction::ProcessResponseRETR(
725 const FtpCtrlResponse& response) { 740 const FtpCtrlResponse& response) {
726 switch (GetErrorClass(response.status_code)) { 741 switch (GetErrorClass(response.status_code)) {
727 case ERROR_CLASS_INITIATED: 742 case ERROR_CLASS_INITIATED:
743 next_state_ = STATE_CTRL_READ;
728 break; 744 break;
729 case ERROR_CLASS_OK: 745 case ERROR_CLASS_OK:
730 next_state_ = STATE_CTRL_WRITE_QUIT; 746 next_state_ = STATE_CTRL_WRITE_QUIT;
731 break; 747 break;
732 case ERROR_CLASS_PENDING: 748 case ERROR_CLASS_PENDING:
733 next_state_ = STATE_CTRL_WRITE_PASV; 749 next_state_ = STATE_CTRL_WRITE_PASV;
734 break; 750 break;
735 case ERROR_CLASS_ERROR_RETRY: 751 case ERROR_CLASS_ERROR_RETRY:
736 if (response.status_code == 421 || response.status_code == 425 || 752 if (response.status_code == 421 || response.status_code == 425 ||
737 response.status_code == 426) 753 response.status_code == 426)
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 read_data_buf_->data()[0] = 0; 925 read_data_buf_->data()[0] = 0;
910 return data_socket_->Read(read_data_buf_, read_data_buf_len_, 926 return data_socket_->Read(read_data_buf_, read_data_buf_len_,
911 &io_callback_); 927 &io_callback_);
912 } 928 }
913 929
914 int FtpNetworkTransaction::DoDataReadComplete(int result) { 930 int FtpNetworkTransaction::DoDataReadComplete(int result) {
915 return result; 931 return result;
916 } 932 }
917 933
918 } // namespace net 934 } // namespace net
OLDNEW
« no previous file with comments | « net/ftp/ftp_ctrl_response_buffer.cc ('k') | net/ftp/ftp_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698