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