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 |