8220663: Incorrect handling of IPv6 addresses in Socket(Proxy.HTTP)
Reviewed-by: alanb, michaelm
This commit is contained in:
parent
3b0ae8082a
commit
5ee0711360
@ -114,7 +114,7 @@ import java.util.Set;
|
|||||||
if (endpoint == null || !(endpoint instanceof InetSocketAddress))
|
if (endpoint == null || !(endpoint instanceof InetSocketAddress))
|
||||||
throw new IllegalArgumentException("Unsupported address type");
|
throw new IllegalArgumentException("Unsupported address type");
|
||||||
final InetSocketAddress epoint = (InetSocketAddress)endpoint;
|
final InetSocketAddress epoint = (InetSocketAddress)endpoint;
|
||||||
final String destHost = epoint.isUnresolved() ? epoint.getHostName()
|
String destHost = epoint.isUnresolved() ? epoint.getHostName()
|
||||||
: epoint.getAddress().getHostAddress();
|
: epoint.getAddress().getHostAddress();
|
||||||
final int destPort = epoint.getPort();
|
final int destPort = epoint.getPort();
|
||||||
|
|
||||||
@ -122,6 +122,9 @@ import java.util.Set;
|
|||||||
if (security != null)
|
if (security != null)
|
||||||
security.checkConnect(destHost, destPort);
|
security.checkConnect(destHost, destPort);
|
||||||
|
|
||||||
|
if (destHost.contains(":"))
|
||||||
|
destHost = "[" + destHost + "]";
|
||||||
|
|
||||||
// Connect to the HTTP proxy server
|
// Connect to the HTTP proxy server
|
||||||
String urlString = "http://" + destHost + ":" + destPort;
|
String urlString = "http://" + destHost + ":" + destPort;
|
||||||
Socket httpSocket = privilegedDoTunnel(urlString, timeout);
|
Socket httpSocket = privilegedDoTunnel(urlString, timeout);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,11 +23,12 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 6370908
|
* @bug 6370908 8220663
|
||||||
* @summary Add support for HTTP_CONNECT proxy in Socket class
|
* @summary Add support for HTTP_CONNECT proxy in Socket class
|
||||||
* @modules java.base/sun.net.www
|
* @modules java.base/sun.net.www
|
||||||
* @run main HttpProxy
|
* @run main HttpProxy
|
||||||
* @run main/othervm -Djava.net.preferIPv4Stack=true HttpProxy
|
* @run main/othervm -Djava.net.preferIPv4Stack=true HttpProxy
|
||||||
|
* @run main/othervm -Djava.net.preferIPv6Addresses=true HttpProxy
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -40,6 +41,9 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import sun.net.www.MessageHeader;
|
import sun.net.www.MessageHeader;
|
||||||
|
|
||||||
public class HttpProxy {
|
public class HttpProxy {
|
||||||
@ -50,9 +54,10 @@ public class HttpProxy {
|
|||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
String host;
|
String host;
|
||||||
int port;
|
int port;
|
||||||
|
ConnectProxyTunnelServer proxy = null;
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
// Start internal proxy
|
// Start internal proxy
|
||||||
ConnectProxyTunnelServer proxy = new ConnectProxyTunnelServer();
|
proxy = new ConnectProxyTunnelServer();
|
||||||
proxy.start();
|
proxy.start();
|
||||||
host = "localhost";
|
host = "localhost";
|
||||||
port = proxy.getLocalPort();
|
port = proxy.getLocalPort();
|
||||||
@ -66,8 +71,13 @@ public class HttpProxy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
HttpProxy p = new HttpProxy(host, port);
|
HttpProxy p = new HttpProxy(host, port);
|
||||||
p.test();
|
p.test();
|
||||||
|
} finally {
|
||||||
|
if (proxy != null)
|
||||||
|
proxy.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpProxy(String proxyHost, int proxyPort) {
|
public HttpProxy(String proxyHost, int proxyPort) {
|
||||||
@ -79,14 +89,23 @@ public class HttpProxy {
|
|||||||
InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
|
InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
|
||||||
Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
|
Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
|
||||||
|
|
||||||
try (ServerSocket ss = new ServerSocket(0);
|
try (ServerSocket ss = new ServerSocket(0)) {
|
||||||
Socket sock = new Socket(httpProxy)) {
|
List<InetSocketAddress> externalAddresses = new ArrayList<>();
|
||||||
|
externalAddresses.add(
|
||||||
|
new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort()));
|
||||||
|
|
||||||
|
if (!"true".equals(System.getProperty("java.net.preferIPv4Stack"))) {
|
||||||
|
byte[] bytes = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
|
||||||
|
var address = InetAddress.getByAddress(bytes);
|
||||||
|
externalAddresses.add(
|
||||||
|
new InetSocketAddress(address, ss.getLocalPort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SocketAddress externalAddress : externalAddresses) {
|
||||||
|
try (Socket sock = new Socket(httpProxy)) {
|
||||||
sock.setSoTimeout(SO_TIMEOUT);
|
sock.setSoTimeout(SO_TIMEOUT);
|
||||||
sock.setTcpNoDelay(false);
|
sock.setTcpNoDelay(false);
|
||||||
|
|
||||||
InetSocketAddress externalAddress =
|
|
||||||
new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort());
|
|
||||||
|
|
||||||
out.println("Trying to connect to server socket on " + externalAddress);
|
out.println("Trying to connect to server socket on " + externalAddress);
|
||||||
sock.connect(externalAddress);
|
sock.connect(externalAddress);
|
||||||
try (Socket externalSock = ss.accept()) {
|
try (Socket externalSock = ss.accept()) {
|
||||||
@ -102,13 +121,15 @@ public class HttpProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void check(boolean condition, String message) {
|
static void check(boolean condition, String message) {
|
||||||
if (!condition) out.println(message);
|
if (!condition) out.println(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Exception unexpected(Exception e) {
|
static Exception unexpected(Exception e) {
|
||||||
out.println("Unexcepted Exception: " + e);
|
out.println("Unexpected Exception: " + e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -164,9 +185,10 @@ public class HttpProxy {
|
|||||||
return i1 * 256 + i2;
|
return i1 * 256 + i2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ConnectProxyTunnelServer extends Thread {
|
static class ConnectProxyTunnelServer extends Thread implements AutoCloseable {
|
||||||
|
|
||||||
private final ServerSocket ss;
|
private final ServerSocket ss;
|
||||||
|
private volatile boolean closed;
|
||||||
|
|
||||||
public ConnectProxyTunnelServer() throws IOException {
|
public ConnectProxyTunnelServer() throws IOException {
|
||||||
ss = new ServerSocket(0);
|
ss = new ServerSocket(0);
|
||||||
@ -174,12 +196,19 @@ public class HttpProxy {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (!closed) {
|
||||||
try (Socket clientSocket = ss.accept()) {
|
try (Socket clientSocket = ss.accept()) {
|
||||||
processRequest(clientSocket);
|
processRequest(clientSocket);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
if (!closed) {
|
||||||
out.println("Proxy Failed: " + e);
|
out.println("Proxy Failed: " + e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
if (!closed)
|
||||||
try { ss.close(); } catch (IOException x) { unexpected(x); }
|
try { ss.close(); } catch (IOException x) { unexpected(x); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,6 +220,12 @@ public class HttpProxy {
|
|||||||
return ss.getLocalPort();
|
return ss.getLocalPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
closed = true;
|
||||||
|
ss.close();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Processes the CONNECT request
|
* Processes the CONNECT request
|
||||||
*/
|
*/
|
||||||
@ -200,7 +235,7 @@ public class HttpProxy {
|
|||||||
|
|
||||||
if (!statusLine.startsWith("CONNECT")) {
|
if (!statusLine.startsWith("CONNECT")) {
|
||||||
out.println("proxy server: processes only "
|
out.println("proxy server: processes only "
|
||||||
+ "CONNECT method requests, recieved: "
|
+ "CONNECT method requests, received: "
|
||||||
+ statusLine);
|
+ statusLine);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -246,12 +281,19 @@ public class HttpProxy {
|
|||||||
int endi = connectStr.lastIndexOf(' ');
|
int endi = connectStr.lastIndexOf(' ');
|
||||||
String connectInfo = connectStr.substring(starti+1, endi).trim();
|
String connectInfo = connectStr.substring(starti+1, endi).trim();
|
||||||
// retrieve server name and port
|
// retrieve server name and port
|
||||||
endi = connectInfo.indexOf(':');
|
endi = connectInfo.lastIndexOf(':');
|
||||||
String name = connectInfo.substring(0, endi);
|
String name = connectInfo.substring(0, endi);
|
||||||
|
|
||||||
|
if (name.contains(":")) {
|
||||||
|
if (!(name.startsWith("[") && name.endsWith("]"))) {
|
||||||
|
throw new IOException("Invalid host:" + name);
|
||||||
|
}
|
||||||
|
name = name.substring(1, name.length() - 1);
|
||||||
|
}
|
||||||
int port = Integer.parseInt(connectInfo.substring(endi+1));
|
int port = Integer.parseInt(connectInfo.substring(endi+1));
|
||||||
return new InetSocketAddress(name, port);
|
return new InetSocketAddress(name, port);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
out.println("Proxy recieved a request: " + connectStr);
|
out.println("Proxy received a request: " + connectStr);
|
||||||
throw unexpected(e);
|
throw unexpected(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user