publicstaticvoid test(ServerSocket socket, SSLContext context,
ProxySelector ps, String... args) throws Exception
{
System.out.println("Tests a race condition in SSLTube/SSLFlowDelegate");
System.out.println("This test will timeout if the ALPN CF is not completed" + " when a 'Connection reset by peer' exception is raised" + " during the handshake - see 8217094.");
URI uri = new URI("https", null,
socket.getInetAddress().getHostAddress(), socket.getLocalPort(), "/ReadOnlyServer/https_1_1/", null, null);
HttpRequest request1 = HttpRequest.newBuilder(uri)
.GET().build();
HttpRequest request2 = HttpRequest.newBuilder(uri)
.POST(HttpRequest.BodyPublishers.ofString("foo")).build();
ReadOnlyServer server = new ReadOnlyServer(socket); Thread serverThread = newThread(server, "ServerThread");
serverThread.start(); try { for (var arg : args) { var version = HttpClient.Version.valueOf(arg);
HttpClient.Builder builder = HttpClient.newBuilder()
.version(version); if (ps != null) builder.proxy(ps); if (context != null) builder.sslContext(context);
HttpClient client = builder.build(); for (var request : List.of(request1, request2)) {
System.out.println("Server is " + socket.getLocalSocketAddress()
+ ", Version is " + version + ", Method is " + request.method()
+ (ps == null ? ", no proxy"
: (", Proxy is " + ps.select(request.uri())))); try {
HttpResponse<String> resp =
client.send(request, HttpResponse.BodyHandlers.ofString()); thrownew AssertionError( "Client should not have received any response: " + resp);
} catch (HttpTimeoutException x) {
System.out.println("Unexpected " + x);
x.printStackTrace(); thrownew AssertionError("Unexpected exception " + x, x);
} catch (Exception x) { // We expect IOException("Connection reset by peer"), but // any exception would do: we just don't want to linger // forever.
System.err.println("Client got expected exception: " + x);
x.printStackTrace(System.out);
}
}
}
} finally {
server.close();
}
}
publicstaticclass ReadOnlyServer implements Runnable, Closeable { final ServerSocket socket; final AtomicReference<Throwable> errorRef = new AtomicReference<>(); final AtomicBoolean closing = new AtomicBoolean();
ReadOnlyServer(ServerSocket socket) { this.socket = socket;
}
@Override publicvoid run() { int count = 0; int all = 0; try {
System.out.println("Server starting"); while (!closing.get()) {
all += count;
count = 0; try (Socket client = socket.accept()) {
client.setSoTimeout(1000);
client.setOption(StandardSocketOptions.SO_LINGER, 0);
InputStream is = client.getInputStream();
OutputStream os = client.getOutputStream(); boolean drain = true; int timeouts = 0; // now read some byte from the ClientHello // and abruptly close the socket. while (drain) { try {
is.read();
count++; if (count >= 50) {
drain = false;
}
} catch (SocketTimeoutException so) { // make sure we read something if (count > 0) timeouts++; if (timeouts == 5) { // presumably the client is // waiting for us to answer... // but we should not reach here.
drain = false;
}
}
}
System.out.println("Got " + count + " bytes");
}
}
} catch (Throwable t) { if (!closing.get()) {
errorRef.set(t);
t.printStackTrace();
}
} finally {
System.out.println("Server existing after reading " + (all + count) + " bytes");
close();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.