Last active
June 24, 2023 17:06
-
-
Save strogiyotec/dcd896d90aab34ca4ed1fef5cfb97390 to your computer and use it in GitHub Desktop.
Try to reproduce jetty issue 9947
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.ByteBuffer; | |
import java.nio.charset.StandardCharsets; | |
import java.nio.file.Paths; | |
import org.eclipse.jetty.jmx.MBeanContainer; | |
import org.eclipse.jetty.http.HttpFields; | |
import org.eclipse.jetty.http.HttpMethod; | |
import org.eclipse.jetty.http.HttpStatus; | |
import org.eclipse.jetty.http.HttpVersion; | |
import org.eclipse.jetty.http.MetaData; | |
import org.eclipse.jetty.http3.api.Session; | |
import org.eclipse.jetty.http3.api.Stream; | |
import org.eclipse.jetty.http3.frames.DataFrame; | |
import org.eclipse.jetty.http3.frames.HeadersFrame; | |
import org.eclipse.jetty.http3.server.HTTP3ServerConnector; | |
import org.eclipse.jetty.http3.server.RawHTTP3ServerConnectionFactory; | |
import org.eclipse.jetty.server.Server; | |
import org.eclipse.jetty.util.ssl.SslContextFactory; | |
public final class Main { | |
public static void main(String[] args) throws Exception { | |
// Create a Server instance. | |
Server server = new Server(9443); | |
// HTTP/3 is always secure, so it always need a SslContextFactory. | |
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); | |
sslContextFactory.setKeyStorePath("/home/strogiyotec/IdeaProjects/archetype/my-artifactId/keystore"); | |
sslContextFactory.setKeyStorePassword("test322"); | |
// The listener for session events. | |
Session.Server.Listener sessionListener = new Session.Server.Listener() { | |
@Override | |
public Stream.Server.Listener onRequest(Stream.Server stream, HeadersFrame frame) { | |
// Send a response after reading the request. | |
MetaData.Request request = (MetaData.Request) frame.getMetaData(); | |
if (frame.isLast()) { | |
respond(stream, request); | |
return null; | |
} else { | |
// Demand to be called back when data is available. | |
stream.demand(); | |
return new Stream.Server.Listener() { | |
@Override | |
public void onDataAvailable(Stream.Server stream) { | |
Stream.Data data = stream.readData(); | |
if (data == null) { | |
stream.demand(); | |
} else { | |
// Consume the request content. | |
data.release(); | |
if (data.isLast()) | |
respond(stream, request); | |
else | |
stream.demand(); | |
} | |
} | |
}; | |
} | |
} | |
private void respond(Stream.Server stream, MetaData.Request request) { | |
// Prepare the response HEADERS frame. | |
// The response HTTP status and HTTP headers. | |
MetaData.Response response = new MetaData.Response(HttpStatus.OK_200, "Test", HttpVersion.HTTP_3, HttpFields.EMPTY); | |
if (HttpMethod.GET.is(request.getMethod())) { | |
// The response content. | |
ByteBuffer resourceBytes = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8)); | |
// Send the HEADERS frame with the response status and headers, | |
// and a DATA frame with the response content bytes. | |
stream.respond(new HeadersFrame(response, false)) | |
.thenCompose(s -> s.data(new DataFrame(resourceBytes, true))); | |
} else { | |
// Send just the HEADERS frame with the response status and headers. | |
stream.respond(new HeadersFrame(response, true)); | |
} | |
} | |
}; | |
// Create and configure the RawHTTP3ServerConnectionFactory. | |
RawHTTP3ServerConnectionFactory http3 = new RawHTTP3ServerConnectionFactory(sessionListener); | |
http3.getHTTP3Configuration().setStreamIdleTimeout(15000); | |
// Create and configure the HTTP3ServerConnector. | |
HTTP3ServerConnector connector = new HTTP3ServerConnector(server, sslContextFactory, http3); | |
// Configure the max number of requests per QUIC connection. | |
connector.getQuicConfiguration().setMaxBidirectionalRemoteStreams(1024); | |
connector.getQuicConfiguration().setPemWorkDirectory(Paths.get("/home/strogiyotec/IdeaProjects/archetype/my-artifactId")); | |
// Add the Connector to the Server. | |
server.addConnector(connector); | |
MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); | |
server.addBean(mbeanContainer); | |
// Start the Server so it starts accepting connections from clients. | |
server.start(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment