8220493: Prepare Socket/ServerSocket for alternative platform SocketImpl

Co-authored-by: Michael McMahon <michael.x.mcmahon@oracle.com>
Reviewed-by: chegar
This commit is contained in:
Alan Bateman 2019-03-16 19:44:12 +00:00
parent c306e3f059
commit 8743be63c4
12 changed files with 1525 additions and 188 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2013, 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.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,14 +34,13 @@ import java.util.Set;
/**
* Basic SocketImpl that relies on the internal HTTP protocol handler
* implementation to perform the HTTP tunneling and authentication. The
* sockets impl is swapped out and replaced with the socket from the HTTP
* handler after the tunnel is successfully setup.
* implementation to perform the HTTP tunneling and authentication. Once
* connected, all socket operations delegate to a platform SocketImpl.
*
* @since 1.8
*/
/*package*/ class HttpConnectSocketImpl extends PlainSocketImpl {
/*package*/ class HttpConnectSocketImpl extends DelegatingSocketImpl {
private static final String httpURLClazzStr =
"sun.net.www.protocol.http.HttpURLConnection";
@ -76,12 +75,8 @@ import java.util.Set;
}
}
HttpConnectSocketImpl(String server, int port) {
this.server = server;
this.port = port;
}
HttpConnectSocketImpl(Proxy proxy) {
HttpConnectSocketImpl(Proxy proxy, SocketImpl delegate) {
super(delegate);
SocketAddress a = proxy.address();
if ( !(a instanceof InetSocketAddress) )
throw new IllegalArgumentException("Unsupported address type");
@ -91,6 +86,27 @@ import java.util.Set;
port = ad.getPort();
}
@Override
protected void connect(String host, int port) throws IOException {
connect(new InetSocketAddress(host, port), 0);
}
@Override
protected void connect(InetAddress address, int port) throws IOException {
connect(new InetSocketAddress(address, port), 0);
}
@Override
void setSocket(Socket socket) {
delegate.socket = socket;
super.setSocket(socket);
}
@Override
void setServerSocket(ServerSocket socket) {
throw new InternalError("should not get here");
}
@Override
protected void connect(SocketAddress endpoint, int timeout)
throws IOException
@ -117,21 +133,37 @@ import java.util.Set;
close();
// update the Sockets impl to the impl from the http Socket
AbstractPlainSocketImpl psi = (AbstractPlainSocketImpl) httpSocket.impl;
this.getSocket().impl = psi;
SocketImpl si = httpSocket.impl;
getSocket().setImpl(si);
// best effort is made to try and reset options previously set
Set<Map.Entry<Integer,Object>> options = optionsMap.entrySet();
try {
for(Map.Entry<Integer,Object> entry : options) {
psi.setOption(entry.getKey(), entry.getValue());
si.setOption(entry.getKey(), entry.getValue());
}
} catch (IOException x) { /* gulp! */ }
}
@Override
protected void listen(int backlog) {
throw new InternalError("should not get here");
}
@Override
protected void accept(SocketImpl s) {
throw new InternalError("should not get here");
}
@Override
void reset() {
throw new InternalError("should not get here");
}
@Override
public void setOption(int opt, Object val) throws SocketException {
super.setOption(opt, val);
delegate.setOption(opt, val);
if (external_address != null)
return; // we're connected, just return
@ -163,7 +195,10 @@ import java.util.Set;
URL destURL = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) destURL.openConnection(proxy);
conn.setConnectTimeout(connectTimeout);
conn.setReadTimeout(this.timeout);
int timeout = (int) getOption(SocketOptions.SO_TIMEOUT);
if (timeout > 0) {
conn.setReadTimeout(timeout);
}
conn.connect();
doTunneling(conn);
try {
@ -174,10 +209,14 @@ import java.util.Set;
}
}
private void doTunneling(HttpURLConnection conn) {
private void doTunneling(HttpURLConnection conn) throws IOException {
try {
doTunneling.invoke(conn);
} catch (ReflectiveOperationException x) {
Throwable cause = x.getCause();
if (cause instanceof IOException) {
throw (IOException) cause;
}
throw new InternalError("Should not reach here", x);
}
}
@ -187,7 +226,7 @@ import java.util.Set;
if (external_address != null)
return external_address.getAddress();
else
return super.getInetAddress();
return delegate.getInetAddress();
}
@Override
@ -195,6 +234,6 @@ import java.util.Set;
if (external_address != null)
return external_address.getPort();
else
return super.getPort();
return delegate.getPort();
}
}