Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/ftp/FtpURL.java
38838 views
1
/*
2
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.io.*;
25
import java.net.*;
26
27
/*
28
* @test
29
* @bug 4398880
30
* @summary FTP URL processing modified to conform to RFC 1738
31
*/
32
33
public class FtpURL {
34
/**
35
* A class that simulates, on a separate, an FTP server.
36
*/
37
38
private class FtpServer extends Thread {
39
private ServerSocket server;
40
private int port;
41
private boolean done = false;
42
private boolean portEnabled = true;
43
private boolean pasvEnabled = true;
44
private String username;
45
private String password;
46
private String cwd;
47
private String filename;
48
private String type;
49
private boolean list = false;
50
51
/**
52
* This Inner class will handle ONE client at a time.
53
* That's where 99% of the protocol handling is done.
54
*/
55
56
private class FtpServerHandler {
57
BufferedReader in;
58
PrintWriter out;
59
Socket client;
60
private final int ERROR = 0;
61
private final int USER = 1;
62
private final int PASS = 2;
63
private final int CWD = 3;
64
private final int CDUP = 4;
65
private final int PWD = 5;
66
private final int TYPE = 6;
67
private final int NOOP = 7;
68
private final int RETR = 8;
69
private final int PASV = 9;
70
private final int PORT = 10;
71
private final int LIST = 11;
72
private final int REIN = 12;
73
private final int QUIT = 13;
74
private final int STOR = 14;
75
private final int NLST = 15;
76
private final int RNFR = 16;
77
private final int RNTO = 17;
78
String[] cmds = { "USER", "PASS", "CWD", "CDUP", "PWD", "TYPE",
79
"NOOP", "RETR", "PASV", "PORT", "LIST", "REIN",
80
"QUIT", "STOR", "NLST", "RNFR", "RNTO" };
81
private String arg = null;
82
private ServerSocket pasv = null;
83
private int data_port = 0;
84
private InetAddress data_addr = null;
85
86
/**
87
* Parses a line to match it with one of the supported FTP commands.
88
* Returns the command number.
89
*/
90
91
private int parseCmd(String cmd) {
92
if (cmd == null || cmd.length() < 3)
93
return ERROR;
94
int blank = cmd.indexOf(' ');
95
if (blank < 0)
96
blank = cmd.length();
97
if (blank < 3)
98
return ERROR;
99
String s = cmd.substring(0, blank);
100
if (cmd.length() > blank+1)
101
arg = cmd.substring(blank+1, cmd.length());
102
else
103
arg = null;
104
for (int i = 0; i < cmds.length; i++) {
105
if (s.equalsIgnoreCase(cmds[i]))
106
return i+1;
107
}
108
return ERROR;
109
}
110
111
public FtpServerHandler(Socket cl) {
112
client = cl;
113
}
114
115
protected boolean isPasvSet() {
116
if (pasv != null && !pasvEnabled) {
117
try {
118
pasv.close();
119
} catch (IOException ex) {
120
}
121
pasv = null;
122
}
123
if (pasvEnabled && pasv != null)
124
return true;
125
return false;
126
}
127
128
/**
129
* Open the data socket with the client. This can be the
130
* result of a "PASV" or "PORT" command.
131
*/
132
133
protected OutputStream getOutDataStream() {
134
try {
135
if (isPasvSet()) {
136
Socket s = pasv.accept();
137
return s.getOutputStream();
138
}
139
if (data_addr != null) {
140
Socket s = new Socket(data_addr, data_port);
141
data_addr = null;
142
data_port = 0;
143
return s.getOutputStream();
144
}
145
} catch (Exception e) {
146
e.printStackTrace();
147
}
148
return null;
149
}
150
151
protected InputStream getInDataStream() {
152
try {
153
if (isPasvSet()) {
154
Socket s = pasv.accept();
155
return s.getInputStream();
156
}
157
if (data_addr != null) {
158
Socket s = new Socket(data_addr, data_port);
159
data_addr = null;
160
data_port = 0;
161
return s.getInputStream();
162
}
163
} catch (Exception e) {
164
e.printStackTrace();
165
}
166
return null;
167
}
168
169
/**
170
* Handles the protocol exchange with the client.
171
*/
172
173
public void run() {
174
boolean done = false;
175
String str;
176
int res;
177
boolean logged = false;
178
boolean waitpass = false;
179
180
try {
181
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
182
out = new PrintWriter(client.getOutputStream(), true);
183
out.println("220 tatooine FTP server (SunOS 5.8) ready.");
184
} catch (Exception ex) {
185
return;
186
}
187
synchronized (FtpServer.this) {
188
while (!done) {
189
try {
190
str = in.readLine();
191
res = parseCmd(str);
192
if ((res > PASS && res != QUIT) && !logged) {
193
out.println("530 Not logged in.");
194
continue;
195
}
196
switch (res) {
197
case ERROR:
198
out.println("500 '" + str + "': command not understood.");
199
break;
200
case USER:
201
if (!logged && !waitpass) {
202
username = str.substring(5);
203
password = null;
204
cwd = null;
205
if ("user2".equals(username)) {
206
out.println("230 Guest login ok, access restrictions apply.");
207
logged = true;
208
} else {
209
out.println("331 Password required for " + arg);
210
waitpass = true;
211
}
212
} else {
213
out.println("503 Bad sequence of commands.");
214
}
215
break;
216
case PASS:
217
if (!logged && waitpass) {
218
out.println("230 Guest login ok, access restrictions apply.");
219
password = str.substring(5);
220
logged = true;
221
waitpass = false;
222
} else
223
out.println("503 Bad sequence of commands.");
224
break;
225
case QUIT:
226
out.println("221 Goodbye.");
227
out.flush();
228
out.close();
229
if (pasv != null)
230
pasv.close();
231
done = true;
232
break;
233
case TYPE:
234
out.println("200 Type set to " + arg + ".");
235
type = arg;
236
break;
237
case CWD:
238
out.println("250 CWD command successful.");
239
if (cwd == null)
240
cwd = str.substring(4);
241
else
242
cwd = cwd + "/" + str.substring(4);
243
break;
244
case CDUP:
245
out.println("250 CWD command successful.");
246
break;
247
case PWD:
248
out.println("257 \"" + cwd + "\" is current directory");
249
break;
250
case PASV:
251
if (!pasvEnabled) {
252
out.println("500 PASV is disabled, use PORT instead.");
253
continue;
254
}
255
try {
256
if (pasv == null)
257
pasv = new ServerSocket(0);
258
int port = pasv.getLocalPort();
259
out.println("227 Entering Passive Mode (127,0,0,1," +
260
(port >> 8) + "," + (port & 0xff) +")");
261
} catch (IOException ssex) {
262
out.println("425 Can't build data connection: Connection refused.");
263
}
264
break;
265
case PORT:
266
if (!portEnabled) {
267
out.println("500 PORT is disabled, use PASV instead");
268
continue;
269
}
270
StringBuffer host;
271
int i=0, j=4;
272
while (j>0) {
273
i = arg.indexOf(',', i+1);
274
if (i < 0)
275
break;
276
j--;
277
}
278
if (j != 0) {
279
out.println("500 '" + arg + "': command not understood.");
280
continue;
281
}
282
try {
283
host = new StringBuffer(arg.substring(0,i));
284
for (j=0; j < host.length(); j++)
285
if (host.charAt(j) == ',')
286
host.setCharAt(j, '.');
287
String ports = arg.substring(i+1);
288
i = ports.indexOf(',');
289
data_port = Integer.parseInt(ports.substring(0,i)) << 8;
290
data_port += (Integer.parseInt(ports.substring(i+1)));
291
data_addr = InetAddress.getByName(host.toString());
292
out.println("200 Command okay.");
293
} catch (Exception ex3) {
294
data_port = 0;
295
data_addr = null;
296
out.println("500 '" + arg + "': command not understood.");
297
}
298
break;
299
case RETR:
300
{
301
filename = str.substring(5);
302
OutputStream dout = getOutDataStream();
303
if (dout != null) {
304
out.println("200 Command okay.");
305
PrintWriter pout = new PrintWriter(new BufferedOutputStream(dout));
306
pout.println("Hello World!");
307
pout.flush();
308
pout.close();
309
list = false;
310
} else
311
out.println("425 Can't build data connection: Connection refused.");
312
}
313
break;
314
case NLST:
315
filename = arg;
316
case LIST:
317
{
318
OutputStream dout = getOutDataStream();
319
if (dout != null) {
320
out.println("200 Command okay.");
321
PrintWriter pout = new PrintWriter(new BufferedOutputStream(dout));
322
pout.println("total 130");
323
pout.println("drwxrwxrwt 7 sys sys 577 May 12 03:30 .");
324
pout.println("drwxr-xr-x 39 root root 1024 Mar 27 12:55 ..");
325
pout.println("drwxrwxr-x 2 root root 176 Apr 10 12:02 .X11-pipe");
326
pout.println("drwxrwxr-x 2 root root 176 Apr 10 12:02 .X11-unix");
327
pout.println("drwxrwxrwx 2 root root 179 Mar 30 15:09 .pcmcia");
328
pout.println("drwxrwxrwx 2 jladen staff 117 Mar 30 18:18 .removable");
329
pout.println("drwxrwxrwt 2 root root 327 Mar 30 15:08 .rpc_door");
330
pout.println("-rw-r--r-- 1 root other 21 May 5 16:59 hello2.txt");
331
pout.println("-rw-rw-r-- 1 root sys 5968 Mar 30 15:08 ps_data");
332
pout.flush();
333
pout.close();
334
list = true;
335
try {
336
FtpServer.this.wait ();
337
} catch (Exception e) {}
338
} else
339
out.println("425 Can't build data connection: Connection refused.");
340
}
341
break;
342
case STOR:
343
{
344
InputStream is = getInDataStream();
345
if (is != null) {
346
out.println("200 Command okay.");
347
BufferedInputStream din = new BufferedInputStream(is);
348
int val;
349
do {
350
val = din.read();
351
} while (val != -1);
352
din.close();
353
} else
354
out.println("425 Can't build data connection: Connection refused.");
355
}
356
break;
357
}
358
} catch (IOException ioe) {
359
ioe.printStackTrace();
360
try {
361
out.close();
362
} catch (Exception ex2) {
363
}
364
done = true;
365
}
366
}
367
}
368
}
369
}
370
371
public FtpServer(int port) {
372
this.port = port;
373
try {
374
server = new ServerSocket(port);
375
} catch (IOException e) {
376
}
377
}
378
379
public FtpServer() {
380
this(21);
381
}
382
383
public int getPort() {
384
if (server != null)
385
return server.getLocalPort();
386
return 0;
387
}
388
389
/**
390
* A way to tell the server that it can stop.
391
*/
392
synchronized public void terminate() {
393
done = true;
394
}
395
396
synchronized public void setPortEnabled(boolean ok) {
397
portEnabled = ok;
398
}
399
400
synchronized public void setPasvEnabled(boolean ok) {
401
pasvEnabled = ok;
402
}
403
404
String getUsername() {
405
return username;
406
}
407
408
String getPassword() {
409
return password;
410
}
411
412
String pwd() {
413
return cwd;
414
}
415
416
String getFilename() {
417
return filename;
418
}
419
420
String getType() {
421
return type;
422
}
423
424
synchronized boolean getList() {
425
notify ();
426
return list;
427
}
428
429
/*
430
* All we got to do here is create a ServerSocket and wait for connections.
431
* When a connection happens, we just have to create a thread that will
432
* handle it.
433
*/
434
public void run() {
435
try {
436
Socket client;
437
for (int i=0; i<2; i++) {
438
client = server.accept();
439
(new FtpServerHandler(client)).run();
440
}
441
} catch(Exception e) {
442
} finally {
443
try { server.close(); } catch (IOException unused) {}
444
}
445
}
446
}
447
public static void main(String[] args) throws Exception {
448
FtpURL test = new FtpURL();
449
}
450
451
public FtpURL() throws Exception {
452
FtpServer server = new FtpServer(0);
453
BufferedReader in = null;
454
try {
455
server.start();
456
int port = server.getPort();
457
458
// Now let's check the URL handler
459
460
URL url = new URL("ftp://user:password@localhost:" + port + "/%2Fetc/motd;type=a");
461
URLConnection con = url.openConnection();
462
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
463
String s;
464
do {
465
s = in.readLine();
466
} while (s != null);
467
if (!("user".equals(server.getUsername())))
468
throw new RuntimeException("Inccorect username received");
469
if (!("password".equals(server.getPassword())))
470
throw new RuntimeException("Inccorect password received");
471
if (!("/etc".equals(server.pwd())))
472
throw new RuntimeException("Inccorect directory received");
473
if (!("motd".equals(server.getFilename())))
474
throw new RuntimeException("Inccorect username received");
475
if (!("A".equals(server.getType())))
476
throw new RuntimeException("Incorrect type received");
477
478
in.close();
479
// We're done!
480
481
// Second URL test
482
port = server.getPort();
483
484
// Now let's check the URL handler
485
486
url = new URL("ftp://user2@localhost:" + port + "/%2Fusr/bin;type=d");
487
con = url.openConnection();
488
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
489
do {
490
s = in.readLine();
491
} while (s != null);
492
if (!server.getList())
493
throw new RuntimeException(";type=d didn't generate a NLST");
494
if (server.getPassword() != null)
495
throw new RuntimeException("password should be null!");
496
if (! "bin".equals(server.getFilename()))
497
throw new RuntimeException("Incorrect filename received");
498
if (! "/usr".equals(server.pwd()))
499
throw new RuntimeException("Incorrect pwd received");
500
// We're done!
501
502
} catch (Exception e) {
503
throw new RuntimeException("FTP support error: " + e.getMessage());
504
} finally {
505
try { in.close(); } catch (IOException unused) {}
506
server.terminate();
507
server.server.close();
508
}
509
}
510
}
511
512