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 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 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 testParseClient() {
87 for (int i = 0; i < TESTS.length; i += 2) {
88 assertEquals("Failed to parse", TESTS[i + 1], FTPClient.parsePathname(TESTS[i]));
89 }
90 }
91
92 public void testParsePassiveModeReplyForLocalAddressWithNatWorkaround() throws Exception {
93 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
94 client.setIpAddressFromPasvResponse(true);
95 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
96 assertEquals("8.8.8.8", client.getPassiveHost());
97 client.setIpAddressFromPasvResponse(false);
98 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
99 assertNull(client.getPassiveHost());
100 }
101
102 @SuppressWarnings("deprecation")
103 public void testParsePassiveModeReplyForLocalAddressWithNatWorkaroundDisabled() throws Exception {
104 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
105 client.setPassiveNatWorkaround(false);
106 client.setIpAddressFromPasvResponse(true);
107 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
108 assertEquals("172.16.204.138", client.getPassiveHost());
109 client.setIpAddressFromPasvResponse(false);
110 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
111 assertNull(client.getPassiveHost());
112 }
113
114 public void testParsePassiveModeReplyForLocalAddressWithoutNatWorkaroundStrategy() throws Exception {
115 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
116 client.setPassiveNatWorkaroundStrategy(null);
117 client.setIpAddressFromPasvResponse(true);
118 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
119 assertEquals("172.16.204.138", client.getPassiveHost());
120 client.setIpAddressFromPasvResponse(false);
121 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
122 assertNull(client.getPassiveHost());
123 }
124
125 public void testParsePassiveModeReplyForLocalAddressWithSimpleNatWorkaroundStrategy() throws Exception {
126 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
127 client.setPassiveNatWorkaroundStrategy(hostname -> "4.4.4.4");
128 client.setIpAddressFromPasvResponse(true);
129 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
130 assertEquals("4.4.4.4", client.getPassiveHost());
131 client.setIpAddressFromPasvResponse(false);
132 client._parsePassiveModeReply("227 Entering Passive Mode (172,16,204,138,192,22).");
133 assertNull(client.getPassiveHost());
134 }
135
136 public void testParsePassiveModeReplyForNonLocalAddressWithNatWorkaround() throws Exception {
137 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
138 client.setIpAddressFromPasvResponse(true);
139 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
140 assertEquals("8.8.4.4", client.getPassiveHost());
141 client.setIpAddressFromPasvResponse(false);
142 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
143 assertNull(client.getPassiveHost());
144 }
145
146 @SuppressWarnings("deprecation")
147 public void testParsePassiveModeReplyForNonLocalAddressWithNatWorkaroundDisabled() throws Exception {
148 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
149 client.setPassiveNatWorkaround(false);
150 client.setIpAddressFromPasvResponse(true);
151 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
152 assertEquals("8.8.4.4", client.getPassiveHost());
153 client.setIpAddressFromPasvResponse(false);
154 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
155 assertNull(client.getPassiveHost());
156 }
157
158 public void testParsePassiveModeReplyForNonLocalAddressWithoutNatWorkaroundStrategy() throws Exception {
159 final FTPClient client = new PassiveNatWorkAroundLocalClient("8.8.8.8");
160 client.setPassiveNatWorkaroundStrategy(null);
161 client.setIpAddressFromPasvResponse(true);
162 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
163 assertEquals("8.8.4.4", client.getPassiveHost());
164 client.setIpAddressFromPasvResponse(false);
165 client._parsePassiveModeReply("227 Entering Passive Mode (8,8,4,4,192,22).");
166 assertNull(client.getPassiveHost());
167 }
168
169 public void testParserCachingNullKey() throws Exception {
170 final LocalClient client = new LocalClient();
171 client.setSystemType(FTPClientConfig.SYST_UNIX);
172 assertNull(client.getEntryParser());
173 client.createParser(null);
174 final FTPFileEntryParser entryParser = client.getEntryParser();
175 assertNotNull(entryParser);
176 client.createParser(null);
177 assertSame(entryParser, client.getEntryParser());
178 client.setSystemType(FTPClientConfig.SYST_NT);
179 client.createParser(null);
180 assertSame(entryParser, client.getEntryParser());
181 }
182
183 public void testParserCachingWithKey() throws Exception {
184 final FTPClient client = new FTPClient();
185 assertNull(client.getEntryParser());
186 client.createParser(FTPClientConfig.SYST_UNIX);
187 final FTPFileEntryParser entryParserSYST = client.getEntryParser();
188 assertNotNull(entryParserSYST);
189 client.createParser(FTPClientConfig.SYST_UNIX);
190 assertSame(entryParserSYST, client.getEntryParser());
191 client.createParser(FTPClientConfig.SYST_VMS);
192 final FTPFileEntryParser entryParserVMS = client.getEntryParser();
193 assertNotSame(entryParserSYST, entryParserVMS);
194 client.createParser(FTPClientConfig.SYST_VMS);
195 assertSame(entryParserVMS, client.getEntryParser());
196 client.createParser(FTPClientConfig.SYST_UNIX);
197 assertNotSame(entryParserVMS, client.getEntryParser());
198 }
199
200 public void testUnparseableFiles() throws Exception {
201 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
202 baos.write("-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
203 baos.write(new byte[] { '\r', '\n' });
204 baos.write("zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox".getBytes());
205 baos.write(new byte[] { '\r', '\n' });
206 final FTPFileEntryParser parser = new UnixFTPEntryParser();
207 final FTPClientConfig config = new FTPClientConfig();
208 FTPListParseEngine engine = new FTPListParseEngine(parser, config);
209 config.setUnparseableEntries(false);
210 engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null);
211 FTPFile[] files = engine.getFiles();
212 assertEquals(1, files.length);
213 config.setUnparseableEntries(true);
214 engine = new FTPListParseEngine(parser, config);
215 engine.readServerList(new ByteArrayInputStream(baos.toByteArray()), null);
216 files = engine.getFiles();
217 assertEquals(2, files.length);
218 }
219 }