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 junit.framework.TestCase;
26
27 import org.apache.commons.net.ftp.parser.UnixFTPEntryParser;
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 type) {
41 systemType = type;
42 }
43 }
44
45 private static final class PassiveNatWorkAroundLocalClient extends FTPClient {
46 private final String passiveModeServerIP;
47
48 public PassiveNatWorkAroundLocalClient(final String passiveModeServerIP) {
49 this.passiveModeServerIP = passiveModeServerIP;
50 }
51
52 @Override
53 public InetAddress getRemoteAddress() {
54 try {
55 return InetAddress.getByName(passiveModeServerIP);
56 } catch (final Exception e) {
57 throw new IllegalStateException(e);
58 }
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 testParseClient() {
132 for (int i = 0; i < TESTS.length; i += 2) {
133 assertEquals("Failed to parse", TESTS[i + 1], FTPClient.parsePathname(TESTS[i]));
134 }
135 }
136
137
138 public void testParsePassiveModeReplyForLocalAddressWithNatWorkaround() throws Exception {
139 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
140 client.setIpAddressFromPasvResponse(true);
141 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
142 assertEquals("8.8.8.8", client.getPassiveHost());
143 client.setIpAddressFromPasvResponse(false);
144 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
145 assertNull(client.getPassiveHost());
146 }
147
148 @SuppressWarnings("deprecation")
149 public void testParsePassiveModeReplyForLocalAddressWithNatWorkaroundDisabled() throws Exception {
150 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
151 client.setPassiveNatWorkaround(false);
152 client.setIpAddressFromPasvResponse(true);
153 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
154 assertEquals("172.16.204.138", client.getPassiveHost());
155 client.setIpAddressFromPasvResponse(false);
156 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
157 assertNull(client.getPassiveHost());
158 }
159
160 public void testParsePassiveModeReplyForLocalAddressWithoutNatWorkaroundStrategy() throws Exception {
161 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
162 client.setPassiveNatWorkaroundStrategy(null);
163 client.setIpAddressFromPasvResponse(true);
164 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
165 assertEquals("172.16.204.138", client.getPassiveHost());
166 client.setIpAddressFromPasvResponse(false);
167 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
168 assertNull(client.getPassiveHost());
169 }
170
171 public void testParsePassiveModeReplyForLocalAddressWithSimpleNatWorkaroundStrategy() throws Exception {
172 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
173 client.setPassiveNatWorkaroundStrategy(hostname -> "4.4.4.4");
174 client.setIpAddressFromPasvResponse(true);
175 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
176 assertEquals("4.4.4.4", client.getPassiveHost());
177 client.setIpAddressFromPasvResponse(false);
178 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
179 assertNull(client.getPassiveHost());
180 }
181
182 public void testParsePassiveModeReplyForNonLocalAddressWithNatWorkaround() throws Exception {
183 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
184 client.setIpAddressFromPasvResponse(true);
185 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
186 assertEquals("8.8.4.4", client.getPassiveHost());
187 client.setIpAddressFromPasvResponse(false);
188 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
189 assertNull(client.getPassiveHost());
190 }
191
192 @SuppressWarnings("deprecation")
193 public void testParsePassiveModeReplyForNonLocalAddressWithNatWorkaroundDisabled() throws Exception {
194 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
195 client.setPassiveNatWorkaround(false);
196 client.setIpAddressFromPasvResponse(true);
197 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
198 assertEquals("8.8.4.4", client.getPassiveHost());
199 client.setIpAddressFromPasvResponse(false);
200 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
201 assertNull(client.getPassiveHost());
202 }
203
204 public void testParsePassiveModeReplyForNonLocalAddressWithoutNatWorkaroundStrategy() throws Exception {
205 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
206 client.setPassiveNatWorkaroundStrategy(null);
207 client.setIpAddressFromPasvResponse(true);
208 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
209 assertEquals("8.8.4.4", client.getPassiveHost());
210 client.setIpAddressFromPasvResponse(false);
211 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
212 assertNull(client.getPassiveHost());
213 }
214
215 public void testParserCachingNullKey() throws Exception {
216 final LocalClient client = new LocalClient();
217 client.setSystemType(FTPClientConfig.SYST_UNIX);
218 assertNull(client.getEntryParser());
219 client.createParser(null);
220 final FTPFileEntryParser entryParser = client.getEntryParser();
221 assertNotNull(entryParser);
222 client.createParser(null);
223 assertSame(entryParser, client.getEntryParser());
224 client.setSystemType(FTPClientConfig.SYST_NT);
225 client.createParser(null);
226 assertSame(entryParser, client.getEntryParser());
227 }
228
229 public void testParserCachingWithKey() throws Exception {
230 final FTPClient client = new FTPClient();
231 assertNull(client.getEntryParser());
232 client.createParser(FTPClientConfig.SYST_UNIX);
233 final FTPFileEntryParser entryParserSYST = client.getEntryParser();
234 assertNotNull(entryParserSYST);
235 client.createParser(FTPClientConfig.SYST_UNIX);
236 assertSame(entryParserSYST, client.getEntryParser());
237 client.createParser(FTPClientConfig.SYST_VMS);
238 final FTPFileEntryParser entryParserVMS = client.getEntryParser();
239 assertNotSame(entryParserSYST, entryParserVMS);
240 client.createParser(FTPClientConfig.SYST_VMS);
241 assertSame(entryParserVMS, client.getEntryParser());
242 client.createParser(FTPClientConfig.SYST_UNIX);
243 assertNotSame(entryParserVMS, client.getEntryParser());
244 }
245
246 public void testUnparseableFiles() throws Exception {
247 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
248 baos.write("-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
249 baos.write(new byte[] { '\r', '\n' });
250 baos.write("zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
251 baos.write(new byte[] { '\r', '\n' });
252 final FTPFileEntryParser parser = new UnixFTPEntryParser();
253 final FTPClientConfig config = new FTPClientConfig();
254 FTPListParseEngine engine = new FTPListParseEngine(parser, config);
255 config.setUnparseableEntries(false);
256 engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null);
257 FTPFile[] files = engine.getFiles();
258 assertEquals(1, files.length);
259 config.setUnparseableEntries(true);
260 engine = new FTPListParseEngine(parser, config);
261 engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null);
262 files = engine.getFiles();
263 assertEquals(2, files.length);
264 }
265 }