| OLD | NEW |
| 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 "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // Size we use for IOBuffers used to receive data from the test data socket. | 27 // Size we use for IOBuffers used to receive data from the test data socket. |
| 28 const int kBufferSize = 128; | 28 const int kBufferSize = 128; |
| 29 | 29 |
| 30 } // namespace | 30 } // namespace |
| 31 | 31 |
| 32 namespace net { | 32 namespace net { |
| 33 | 33 |
| 34 class FtpSocketDataProvider : public DynamicSocketDataProvider { | 34 class FtpSocketDataProvider : public SocketDataProvider { |
| 35 public: | 35 public: |
| 36 enum State { | 36 enum State { |
| 37 NONE, | 37 NONE, |
| 38 PRE_USER, | 38 PRE_USER, |
| 39 PRE_PASSWD, | 39 PRE_PASSWD, |
| 40 PRE_SYST, | 40 PRE_SYST, |
| 41 PRE_PWD, | 41 PRE_PWD, |
| 42 PRE_TYPE, | 42 PRE_TYPE, |
| 43 PRE_SIZE, | 43 PRE_SIZE, |
| 44 PRE_LIST_EPSV, | 44 PRE_LIST_EPSV, |
| 45 PRE_LIST_PASV, | 45 PRE_LIST_PASV, |
| 46 PRE_LIST, | 46 PRE_LIST, |
| 47 PRE_RETR, | 47 PRE_RETR, |
| 48 PRE_RETR_EPSV, | 48 PRE_RETR_EPSV, |
| 49 PRE_RETR_PASV, | 49 PRE_RETR_PASV, |
| 50 PRE_CWD, | 50 PRE_CWD, |
| 51 PRE_QUIT, | 51 PRE_QUIT, |
| 52 PRE_NOPASV, | 52 PRE_NOPASV, |
| 53 QUIT | 53 QUIT |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 FtpSocketDataProvider() | 56 FtpSocketDataProvider() |
| 57 : failure_injection_state_(NONE), | 57 : short_read_limit_(0), |
| 58 allow_unconsumed_reads_(false), |
| 59 failure_injection_state_(NONE), |
| 58 multiline_welcome_(false), | 60 multiline_welcome_(false), |
| 59 use_epsv_(true), | 61 use_epsv_(true), |
| 60 data_type_('I') { | 62 data_type_('I') { |
| 61 Init(); | 63 Init(); |
| 62 } | 64 } |
| 63 | 65 |
| 66 // SocketDataProvider implementation. |
| 67 MockRead OnRead() override { |
| 68 if (reads_.empty()) |
| 69 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED); |
| 70 MockRead result = reads_.front(); |
| 71 if (short_read_limit_ == 0 || result.data_len <= short_read_limit_) { |
| 72 reads_.pop_front(); |
| 73 } else { |
| 74 result.data_len = short_read_limit_; |
| 75 reads_.front().data += result.data_len; |
| 76 reads_.front().data_len -= result.data_len; |
| 77 } |
| 78 return result; |
| 79 } |
| 80 |
| 64 MockWriteResult OnWrite(const std::string& data) override { | 81 MockWriteResult OnWrite(const std::string& data) override { |
| 65 if (InjectFault()) | 82 if (InjectFault()) |
| 66 return MockWriteResult(ASYNC, data.length()); | 83 return MockWriteResult(ASYNC, data.length()); |
| 67 switch (state()) { | 84 switch (state()) { |
| 68 case PRE_USER: | 85 case PRE_USER: |
| 69 return Verify("USER anonymous\r\n", data, PRE_PASSWD, | 86 return Verify("USER anonymous\r\n", data, PRE_PASSWD, |
| 70 "331 Password needed\r\n"); | 87 "331 Password needed\r\n"); |
| 71 case PRE_PASSWD: | 88 case PRE_PASSWD: |
| 72 { | 89 { |
| 73 static const char response_one[] = "230 Welcome\r\n"; | 90 static const char response_one[] = "230 Welcome\r\n"; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 failure_injection_state_ = state; | 134 failure_injection_state_ = state; |
| 118 failure_injection_next_state_ = next_state; | 135 failure_injection_next_state_ = next_state; |
| 119 fault_response_ = response; | 136 fault_response_ = response; |
| 120 } | 137 } |
| 121 | 138 |
| 122 State state() const { | 139 State state() const { |
| 123 return state_; | 140 return state_; |
| 124 } | 141 } |
| 125 | 142 |
| 126 void Reset() override { | 143 void Reset() override { |
| 127 DynamicSocketDataProvider::Reset(); | 144 reads_.clear(); |
| 128 Init(); | 145 Init(); |
| 129 } | 146 } |
| 130 | 147 |
| 131 bool AllReadDataConsumed() const override { return state_ == QUIT; } | 148 bool AllReadDataConsumed() const override { return state_ == QUIT; } |
| 132 | 149 |
| 133 bool AllWriteDataConsumed() const override { return state_ == QUIT; } | 150 bool AllWriteDataConsumed() const override { return state_ == QUIT; } |
| 134 | 151 |
| 135 void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; } | 152 void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; } |
| 136 | 153 |
| 137 bool use_epsv() const { return use_epsv_; } | 154 bool use_epsv() const { return use_epsv_; } |
| 138 void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; } | 155 void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; } |
| 139 | 156 |
| 140 void set_data_type(char data_type) { data_type_ = data_type; } | 157 void set_data_type(char data_type) { data_type_ = data_type; } |
| 141 | 158 |
| 159 int short_read_limit() const { return short_read_limit_; } |
| 160 void set_short_read_limit(int limit) { short_read_limit_ = limit; } |
| 161 |
| 162 void set_allow_unconsumed_reads(bool allow) { |
| 163 allow_unconsumed_reads_ = allow; |
| 164 } |
| 165 |
| 142 protected: | 166 protected: |
| 143 void Init() { | 167 void Init() { |
| 144 state_ = PRE_USER; | 168 state_ = PRE_USER; |
| 145 SimulateRead("220 host TestFTPd\r\n"); | 169 SimulateRead("220 host TestFTPd\r\n"); |
| 146 } | 170 } |
| 147 | 171 |
| 148 // If protocol fault injection has been requested, adjusts state and mocked | 172 // If protocol fault injection has been requested, adjusts state and mocked |
| 149 // read and returns true. | 173 // read and returns true. |
| 150 bool InjectFault() { | 174 bool InjectFault() { |
| 151 if (state_ != failure_injection_state_) | 175 if (state_ != failure_injection_state_) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 170 } | 194 } |
| 171 | 195 |
| 172 MockWriteResult Verify(const std::string& expected, | 196 MockWriteResult Verify(const std::string& expected, |
| 173 const std::string& data, | 197 const std::string& data, |
| 174 State next_state, | 198 State next_state, |
| 175 const char* next_read) { | 199 const char* next_read) { |
| 176 return Verify(expected, data, next_state, | 200 return Verify(expected, data, next_state, |
| 177 next_read, std::strlen(next_read)); | 201 next_read, std::strlen(next_read)); |
| 178 } | 202 } |
| 179 | 203 |
| 204 // The next time there is a read from this socket, it will return |data|. |
| 205 // Before calling SimulateRead next time, the previous data must be consumed. |
| 206 void SimulateRead(const char* data, size_t length) { |
| 207 if (!allow_unconsumed_reads_) { |
| 208 EXPECT_TRUE(reads_.empty()) << "Unconsumed read: " << reads_.front().data; |
| 209 } |
| 210 reads_.push_back(MockRead(ASYNC, data, length)); |
| 211 } |
| 212 void SimulateRead(const char* data) { SimulateRead(data, std::strlen(data)); } |
| 180 | 213 |
| 181 private: | 214 private: |
| 215 // List of reads to be consumed. |
| 216 std::deque<MockRead> reads_; |
| 217 |
| 218 // Max number of bytes we will read at a time. 0 means no limit. |
| 219 int short_read_limit_; |
| 220 |
| 221 // If true, we'll not require the client to consume all data before we |
| 222 // mock the next read. |
| 223 bool allow_unconsumed_reads_; |
| 224 |
| 182 State state_; | 225 State state_; |
| 183 State failure_injection_state_; | 226 State failure_injection_state_; |
| 184 State failure_injection_next_state_; | 227 State failure_injection_next_state_; |
| 185 const char* fault_response_; | 228 const char* fault_response_; |
| 186 | 229 |
| 187 // If true, we will send multiple 230 lines as response after PASS. | 230 // If true, we will send multiple 230 lines as response after PASS. |
| 188 bool multiline_welcome_; | 231 bool multiline_welcome_; |
| 189 | 232 |
| 190 // If true, we will use EPSV command. | 233 // If true, we will use EPSV command. |
| 191 bool use_epsv_; | 234 bool use_epsv_; |
| (...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) { | 986 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) { |
| 944 FtpSocketDataProviderDirectoryListing ctrl_socket; | 987 FtpSocketDataProviderDirectoryListing ctrl_socket; |
| 945 ctrl_socket.set_short_read_limit(5); | 988 ctrl_socket.set_short_read_limit(5); |
| 946 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | 989 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); |
| 947 } | 990 } |
| 948 | 991 |
| 949 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) { | 992 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) { |
| 950 FtpSocketDataProviderDirectoryListing ctrl_socket; | 993 FtpSocketDataProviderDirectoryListing ctrl_socket; |
| 951 // The client will not consume all three 230 lines. That's good, we want to | 994 // The client will not consume all three 230 lines. That's good, we want to |
| 952 // test that scenario. | 995 // test that scenario. |
| 953 ctrl_socket.allow_unconsumed_reads(true); | 996 ctrl_socket.set_allow_unconsumed_reads(true); |
| 954 ctrl_socket.set_multiline_welcome(true); | 997 ctrl_socket.set_multiline_welcome(true); |
| 955 ctrl_socket.set_short_read_limit(5); | 998 ctrl_socket.set_short_read_limit(5); |
| 956 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | 999 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); |
| 957 } | 1000 } |
| 958 | 1001 |
| 959 // Regression test for http://crbug.com/60555. | 1002 // Regression test for http://crbug.com/60555. |
| 960 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) { | 1003 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) { |
| 961 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket; | 1004 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket; |
| 962 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | 1005 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); |
| 963 } | 1006 } |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 FtpSocketDataProvider::PRE_TYPE, | 1617 FtpSocketDataProvider::PRE_TYPE, |
| 1575 "257 \"\"\r\n", | 1618 "257 \"\"\r\n", |
| 1576 OK); | 1619 OK); |
| 1577 } | 1620 } |
| 1578 | 1621 |
| 1579 INSTANTIATE_TEST_CASE_P(FTP, | 1622 INSTANTIATE_TEST_CASE_P(FTP, |
| 1580 FtpNetworkTransactionTest, | 1623 FtpNetworkTransactionTest, |
| 1581 ::testing::Values(AF_INET, AF_INET6)); | 1624 ::testing::Values(AF_INET, AF_INET6)); |
| 1582 | 1625 |
| 1583 } // namespace net | 1626 } // namespace net |
| OLD | NEW |