8223880: Update sun/net/ftp/FtpURL.java and sun/net/ftp/FtpURLConnectionLeak.java to work with IPv6 addresses

This fix updates three tests: sun/net/ftp/FtpURL.java, sun/net/ftp/FtpURLConnectionLeak.java, and sun/net/ftp/FtpGetContent.java, to work with IPv6 addresses

Reviewed-by: chegar, aeubanks, vtewari
This commit is contained in:
Daniel Fuchs 2019-05-15 19:34:34 +01:00
parent e0a87ef8fc
commit 9e686ef2d1
3 changed files with 105 additions and 17 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,8 @@ import java.net.*;
* @test
* @bug 4255280
* @summary URL.getContent() loses first six bytes for ftp URLs
* @run main FtpGetContent
* @run main/othervm -Djava.net.preferIPv6Addresses=true FtpGetContent
*/
public class FtpGetContent {
@ -38,11 +40,12 @@ public class FtpGetContent {
*/
private class FtpServer extends Thread {
private ServerSocket server;
private final ServerSocket server;
private int port;
private boolean done = false;
private boolean portEnabled = true;
private boolean pasvEnabled = true;
private boolean extendedEnabled = true;
private String username;
private String password;
private String cwd;
@ -77,9 +80,10 @@ public class FtpGetContent {
private final int NLST = 15;
private final int RNFR = 16;
private final int RNTO = 17;
private final int EPSV = 18;
String[] cmds = { "USER", "PASS", "CWD", "CDUP", "PWD", "TYPE",
"NOOP", "RETR", "PASV", "PORT", "LIST", "REIN",
"QUIT", "STOR", "NLST", "RNFR", "RNTO" };
"QUIT", "STOR", "NLST", "RNFR", "RNTO", "EPSV"};
private String arg = null;
private ServerSocket pasv = null;
private int data_port = 0;
@ -91,6 +95,7 @@ public class FtpGetContent {
*/
private int parseCmd(String cmd) {
System.out.println("FTP server received command: " + cmd);
if (cmd == null || cmd.length() < 3)
return ERROR;
int blank = cmd.indexOf(' ');
@ -248,14 +253,42 @@ public class FtpGetContent {
case PWD:
out.println("257 \"" + cwd + "\" is current directory");
break;
case EPSV:
if (!extendedEnabled || !pasvEnabled) {
out.println("500 EPSV is disabled, " +
"use PORT instead.");
continue;
}
if (!(server.getInetAddress() instanceof Inet6Address)) {
// pretend EPSV is not implemented
out.println("500 '" + str + "': command not understood.");
break;
}
if ("all".equalsIgnoreCase(arg)) {
out.println("200 EPSV ALL command successful.");
continue;
}
try {
if (pasv == null)
pasv = new ServerSocket(0, 0, server.getInetAddress());
int port = pasv.getLocalPort();
out.println("229 Entering Extended" +
" Passive Mode (|||" + port + "|)");
} catch (IOException ssex) {
out.println("425 Can't build data connection:" +
" Connection refused.");
}
break;
case PASV:
if (!pasvEnabled) {
out.println("500 PASV is disabled, use PORT instead.");
continue;
}
try {
if (pasv == null)
pasv = new ServerSocket(0);
if (pasv == null) {
pasv = new ServerSocket();
pasv.bind(new InetSocketAddress("127.0.0.1", 0));
}
int port = pasv.getLocalPort();
out.println("227 Entering Passive Mode (127,0,0,1," +
(port >> 8) + "," + (port & 0xff) +")");
@ -367,10 +400,16 @@ public class FtpGetContent {
}
public FtpServer(int port) {
this(null, 0);
}
public FtpServer(InetAddress address, int port) {
this.port = port;
try {
server = new ServerSocket(port);
server = new ServerSocket();
server.bind(new InetSocketAddress(address, port));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@ -384,6 +423,16 @@ public class FtpGetContent {
return 0;
}
public String getAuthority() {
InetAddress address = server.getInetAddress();
String hostaddr = address.isAnyLocalAddress()
? "localhost" : address.getHostAddress();
if (hostaddr.indexOf(':') > -1) {
hostaddr = "[" + hostaddr +"]";
}
return hostaddr + ":" + getPort();
}
/**
* A way to tell the server that it can stop.
*/
@ -452,14 +501,16 @@ public class FtpGetContent {
public FtpGetContent() throws Exception {
FtpServer server = null;
try {
server = new FtpServer(0);
InetAddress loopback = InetAddress.getLoopbackAddress();
server = new FtpServer(loopback, 0);
server.start();
int port = server.getPort();
String authority = server.getAuthority();
// Now let's check the URL handler
URL url = new URL("ftp://localhost:" + port + "/pub/BigFile");
InputStream stream = (InputStream)url.getContent();
URL url = new URL("ftp://" + authority + "/pub/BigFile");
InputStream stream = (InputStream)url.openConnection(Proxy.NO_PROXY)
.getContent();
byte[] buffer = new byte[1024];
int totalBytes = 0;
int bytesRead = stream.read(buffer);

View File

@ -23,11 +23,16 @@
import java.io.*;
import java.net.*;
import jdk.test.lib.net.IPSupport;
/*
* @test
* @bug 4398880
* @summary FTP URL processing modified to conform to RFC 1738
* @library /test/lib
* @run main/othervm FtpURL
* @run main/othervm -Djava.net.preferIPv4Stack=true FtpURL
* @run main/othervm -Djava.net.preferIPv6Addresses=true FtpURL
*/
public class FtpURL {
@ -41,6 +46,7 @@ public class FtpURL {
private boolean done = false;
private boolean portEnabled = true;
private boolean pasvEnabled = true;
private boolean extendedEnabled = true;
private String username;
private String password;
private String cwd;
@ -75,9 +81,10 @@ public class FtpURL {
private final int NLST = 15;
private final int RNFR = 16;
private final int RNTO = 17;
private final int EPSV = 18;
String[] cmds = { "USER", "PASS", "CWD", "CDUP", "PWD", "TYPE",
"NOOP", "RETR", "PASV", "PORT", "LIST", "REIN",
"QUIT", "STOR", "NLST", "RNFR", "RNTO" };
"QUIT", "STOR", "NLST", "RNFR", "RNTO", "EPSV" };
private String arg = null;
private ServerSocket pasv = null;
private int data_port = 0;
@ -89,6 +96,7 @@ public class FtpURL {
*/
private int parseCmd(String cmd) {
System.out.println("Received command: " + cmd);
if (cmd == null || cmd.length() < 3)
return ERROR;
int blank = cmd.indexOf(' ');
@ -127,7 +135,7 @@ public class FtpURL {
/**
* Open the data socket with the client. This can be the
* result of a "PASV" or "PORT" command.
* result of a "EPSV", "PASV" or "PORT" command.
*/
protected OutputStream getOutDataStream() {
@ -247,6 +255,33 @@ public class FtpURL {
case PWD:
out.println("257 \"" + cwd + "\" is current directory");
break;
case EPSV:
if (!extendedEnabled || !pasvEnabled) {
out.println("500 EPSV is disabled, " +
"use PORT instead.");
continue;
}
if (!(server.getInetAddress() instanceof Inet6Address)) {
// pretend EPSV is not implemented
out.println("500 '" + str + "': command not understood.");
break;
}
if ("all".equalsIgnoreCase(arg)) {
out.println("200 EPSV ALL command successful.");
continue;
}
try {
if (pasv == null)
pasv = new ServerSocket(0, 0, server.getInetAddress());
int port = pasv.getLocalPort();
out.println("229 Entering Extended" +
" Passive Mode (|||" + port + "|)");
} catch (IOException ssex) {
out.println("425 Can't build data connection:" +
" Connection refused.");
}
break;
case PASV:
if (!pasvEnabled) {
out.println("500 PASV is disabled, use PORT instead.");
@ -467,6 +502,7 @@ public class FtpURL {
}
}
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
FtpURL test = new FtpURL();
}
@ -482,7 +518,7 @@ public class FtpURL {
// Now let's check the URL handler
URL url = new URL("ftp://user:password@" + authority + "/%2Fetc/motd;type=a");
URLConnection con = url.openConnection();
URLConnection con = url.openConnection(Proxy.NO_PROXY);
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String s;
do {
@ -507,7 +543,7 @@ public class FtpURL {
// Now let's check the URL handler
url = new URL("ftp://user2@" + authority + "/%2Fusr/bin;type=d");
con = url.openConnection();
con = url.openConnection(Proxy.NO_PROXY);
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
do {
s = in.readLine();
@ -523,9 +559,9 @@ public class FtpURL {
// We're done!
} catch (Exception e) {
throw new RuntimeException("FTP support error: " + e.getMessage());
throw new RuntimeException("FTP support error: " + e.getMessage(), e);
} finally {
try { in.close(); } catch (IOException unused) {}
try { in.close(); } catch (Exception unused) {}
server.terminate();
server.server.close();
}

View File

@ -34,6 +34,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.Proxy;
public class FtpURLConnectionLeak {
@ -48,7 +49,7 @@ public class FtpURLConnectionLeak {
try (server) {
for (int i = 0; i < 3; i++) {
try {
InputStream stream = url.openStream();
InputStream stream = url.openConnection(Proxy.NO_PROXY).getInputStream();
} catch (FileNotFoundException expected) {
// should always reach this point since the path does not exist
System.out.println("caught expected " + expected);