1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.ftp;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.net.InetAddress;
24
25 import org.apache.commons.net.ftp.parser.UnixFTPEntryParser;
26
27 import junit.framework.TestCase;
28
29 public class FTPClientTest extends TestCase {
30
31 private static final class LocalClient extends FTPClient {
32
33 private String systemType;
34
35 @Override
36 public String getSystemType() throws IOException {
37 return systemType;
38 }
39
40 public void setSystemType(final String systemType) {
41 this.systemType = systemType;
42 }
43 }
44
45 private static final class PassiveNatWorkAroundLocalClient extends FTPClient {
46
47 private final String passiveModeServerIP;
48
49 public PassiveNatWorkAroundLocalClient(final String passiveModeServerIP) {
50 this.passiveModeServerIP = passiveModeServerIP;
51 }
52
53 @Override
54 public InetAddress getRemoteAddress() {
55 try {
56 return InetAddress.getByName(passiveModeServerIP);
57 } catch (final Exception e) {
58 throw new IllegalStateException(e);
59 }
60 }
61 }
62
63 private static final String[] TESTS = { "257 /path/without/quotes", "/path/without/quotes",
64
65 "257 \"/path/with/delimiting/quotes/without/commentary\"", "/path/with/delimiting/quotes/without/commentary",
66
67 "257 \"/path/with/quotes\"\" /inside/but/without/commentary\"", "/path/with/quotes\" /inside/but/without/commentary",
68
69 "257 \"/path/with/quotes\"\" /inside/string\" and with commentary", "/path/with/quotes\" /inside/string",
70
71 "257 \"/path/with/quotes\"\" /inside/string\" and with commentary that also \"contains quotes\"", "/path/with/quotes\" /inside/string",
72
73 "257 \"/path/without/trailing/quote",
74 "\"/path/without/trailing/quote",
75
76 "257 root is current directory.",
77 "root is current directory.",
78
79 "257 \"/\"",
80 "/", };
81
82 public FTPClientTest(final String name) {
83 super(name);
84 }
85
86 public void testCopyStreamListener() {
87 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
88 assertNull(client.getCopyStreamListener());
89 }
90
91 public void testGetActivePort() {
92 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
93 assertEquals(0, client.getActivePort());
94 }
95
96 public void testGetAutodetectUTF8() {
97 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
98 assertFalse(client.getAutodetectUTF8());
99 }
100
101 public void testGetBufferSize() {
102 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
103 assertEquals(0, client.getBufferSize());
104 }
105
106 public void testGetControlKeepAliveReplyTimeout() {
107 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
108 assertEquals(1_000, client.getControlKeepAliveReplyTimeout());
109 }
110
111 public void testGetControlKeepAliveTimeout() {
112 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
113 assertEquals(0, client.getControlKeepAliveTimeout());
114 }
115
116 public void testGetCslDebug() {
117 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
118 assertNull(client.getCslDebug());
119 }
120
121 public void testGetPassiveLocalIPAddress() {
122 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
123 assertNull(client.getPassiveLocalIPAddress());
124 }
125
126 public void testGetPassivePort() {
127 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
128 assertEquals(-1, client.getPassivePort());
129 }
130
131 public void testLoadResourceProperties() {
132 assertNull(FTPClient.loadResourceProperties(null));
133 assertNull(FTPClient.loadResourceProperties("this/does/not/exist.properties"));
134 assertNull(FTPClient.loadResourceProperties("/this/does/not/exist.properties"));
135 assertNull(FTPClient.loadResourceProperties(FTPClient.SYSTEM_TYPE_PROPERTIES));
136 assertNotNull(FTPClient.loadResourceProperties(""));
137 assertNotNull(FTPClient.loadResourceProperties("/org/apache/commons/net/examples/examples.properties"));
138 assertNotNull(FTPClient.loadResourceProperties("/org/apache/commons/net/test.properties"));
139 }
140
141 public void testParseClient() {
142 for (int i = 0; i < TESTS.length; i += 2) {
143 assertEquals("Failed to parse", TESTS[i + 1], FTPClient.parsePathname(TESTS[i]));
144 }
145 }
146
147 public void testParsePassiveModeReplyForLocalAddressWithNatWorkaround() throws Exception {
148 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
149 client.setIpAddressFromPasvResponse(true);
150 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
151 assertEquals("8.8.8.8", client.getPassiveHost());
152 client.setIpAddressFromPasvResponse(false);
153 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
154 assertNull(client.getPassiveHost());
155 }
156
157 @SuppressWarnings("deprecation")
158 public void testParsePassiveModeReplyForLocalAddressWithNatWorkaroundDisabled() throws Exception {
159 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
160 client.setPassiveNatWorkaround(false);
161 client.setIpAddressFromPasvResponse(true);
162 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
163 assertEquals("172.16.204.138", client.getPassiveHost());
164 client.setIpAddressFromPasvResponse(false);
165 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
166 assertNull(client.getPassiveHost());
167 }
168
169 public void testParsePassiveModeReplyForLocalAddressWithoutNatWorkaroundStrategy() throws Exception {
170 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
171 client.setPassiveNatWorkaroundStrategy(null);
172 client.setIpAddressFromPasvResponse(true);
173 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
174 assertEquals("172.16.204.138", client.getPassiveHost());
175 client.setIpAddressFromPasvResponse(false);
176 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
177 assertNull(client.getPassiveHost());
178 }
179
180 public void testParsePassiveModeReplyForLocalAddressWithSimpleNatWorkaroundStrategy() throws Exception {
181 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
182 client.setPassiveNatWorkaroundStrategy(hostname -> "4.4.4.4");
183 client.setIpAddressFromPasvResponse(true);
184 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
185 assertEquals("4.4.4.4", client.getPassiveHost());
186 client.setIpAddressFromPasvResponse(false);
187 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
188 assertNull(client.getPassiveHost());
189 }
190
191 public void testParsePassiveModeReplyForNonLocalAddressWithNatWorkaround() throws Exception {
192 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
193 client.setIpAddressFromPasvResponse(true);
194 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
195 assertEquals("8.8.4.4", client.getPassiveHost());
196 client.setIpAddressFromPasvResponse(false);
197 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
198 assertNull(client.getPassiveHost());
199 }
200
201 @SuppressWarnings("deprecation")
202 public void testParsePassiveModeReplyForNonLocalAddressWithNatWorkaroundDisabled() throws Exception {
203 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
204 client.setPassiveNatWorkaround(false);
205 client.setIpAddressFromPasvResponse(true);
206 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
207 assertEquals("8.8.4.4", client.getPassiveHost());
208 client.setIpAddressFromPasvResponse(false);
209 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
210 assertNull(client.getPassiveHost());
211 }
212
213 public void testParsePassiveModeReplyForNonLocalAddressWithoutNatWorkaroundStrategy() throws Exception {
214 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
215 client.setPassiveNatWorkaroundStrategy(null);
216 client.setIpAddressFromPasvResponse(true);
217 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
218 assertEquals("8.8.4.4", client.getPassiveHost());
219 client.setIpAddressFromPasvResponse(false);
220 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
221 assertNull(client.getPassiveHost());
222 }
223
224 public void testParserCachingNullKey() throws Exception {
225 final LocalClient client = new LocalClient();
226 client.setSystemType(FTPClientConfig.SYST_UNIX);
227 assertNull(client.getEntryParser());
228 client.createParser(null);
229 final FTPFileEntryParser entryParser = client.getEntryParser();
230 assertNotNull(entryParser);
231 client.createParser(null);
232 assertSame(entryParser, client.getEntryParser());
233 client.setSystemType(FTPClientConfig.SYST_NT);
234 client.createParser(null);
235 assertSame(entryParser, client.getEntryParser());
236 }
237
238 public void testParserCachingWithKey() throws Exception {
239 final FTPClient client = new FTPClient();
240 assertNull(client.getEntryParser());
241 client.createParser(FTPClientConfig.SYST_UNIX);
242 final FTPFileEntryParser entryParserSYST = client.getEntryParser();
243 assertNotNull(entryParserSYST);
244 client.createParser(FTPClientConfig.SYST_UNIX);
245 assertSame(entryParserSYST, client.getEntryParser());
246 client.createParser(FTPClientConfig.SYST_VMS);
247 final FTPFileEntryParser entryParserVMS = client.getEntryParser();
248 assertNotSame(entryParserSYST, entryParserVMS);
249 client.createParser(FTPClientConfig.SYST_VMS);
250 assertSame(entryParserVMS, client.getEntryParser());
251 client.createParser(FTPClientConfig.SYST_UNIX);
252 assertNotSame(entryParserVMS, client.getEntryParser());
253 }
254
255 public void testUnparseableFiles() throws Exception {
256 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
257 baos.write("-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
258 baos.write(new byte[] { '\r', '\n' });
259 baos.write("zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
260 baos.write(new byte[] { '\r', '\n' });
261 final FTPFileEntryParser parser = new UnixFTPEntryParser();
262 final FTPClientConfig config = new FTPClientConfig();
263 FTPListParseEngine engine = new FTPListParseEngine(parser, config);
264 config.setUnparseableEntries(false);
265 engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null);
266 FTPFile[] files = engine.getFiles();
267 assertEquals(1, files.length);
268 config.setUnparseableEntries(true);
269 engine = new FTPListParseEngine(parser, config);
270 engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null);
271 files = engine.getFiles();
272 assertEquals(2, files.length);
273 }
274 }