no-op datagram connector

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2021-03-12 09:44:33 +01:00 committed by Simone Bordet
parent aba7aac3e9
commit ccfe4ec90f
6 changed files with 282 additions and 0 deletions

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty.http3</groupId>
<artifactId>http3-parent</artifactId>
<version>10.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>http3-server</artifactId>
<name>Jetty :: HTTP3 :: Server</name>
<properties>
<bundle-symbolic-name>${project.groupId}.server</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,173 @@
package org.eclipse.jetty.http3.server;
import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.EventListener;
import java.util.concurrent.Executor;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ManagedSelector;
import org.eclipse.jetty.io.SelectorManager;
import org.eclipse.jetty.server.AbstractNetworkConnector;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.thread.Scheduler;
public class ServerDatagramConnector extends AbstractNetworkConnector
{
private final SelectorManager _manager;
private volatile DatagramChannel _datagramChannel;
private volatile int _localPort = -1;
public ServerDatagramConnector(
@Name("server") Server server,
@Name("executor") Executor executor,
@Name("scheduler") Scheduler scheduler,
@Name("bufferPool") ByteBufferPool bufferPool,
@Name("selectors") int selectors,
@Name("factories") ConnectionFactory... factories)
{
super(server, executor, scheduler, bufferPool, 0, factories);
_manager = newSelectorManager(getExecutor(), getScheduler(), selectors);
addBean(_manager, true);
setAcceptorPriorityDelta(-2);
}
public ServerDatagramConnector(
@Name("server") Server server,
@Name("factories") ConnectionFactory... factories)
{
this(server, null, null, null, 1, factories);
}
protected SelectorManager newSelectorManager(Executor executor, Scheduler scheduler, int selectors)
{
return new ServerDatagramSelectorManager(executor, scheduler, selectors);
}
@Override
protected void doStart() throws Exception
{
for (EventListener l : getBeans(SelectorManager.SelectorManagerListener.class))
_manager.addEventListener(l);
super.doStart();
}
@Override
protected void doStop() throws Exception
{
super.doStop();
for (EventListener l : getBeans(EventListener.class))
_manager.removeEventListener(l);
}
@Override
public boolean isOpen()
{
DatagramChannel channel = _datagramChannel;
return channel != null && channel.isOpen();
}
@Override
public void open() throws IOException
{
if (_datagramChannel == null)
{
_datagramChannel = openDatagramChannel();
_datagramChannel.configureBlocking(false);
_localPort = _datagramChannel.socket().getLocalPort();
if (_localPort <= 0)
throw new IOException("Datagram channel not bound");
addBean(_datagramChannel);
}
}
@Override
public void close()
{
super.close();
DatagramChannel datagramChannel = _datagramChannel;
_datagramChannel = null;
if (datagramChannel != null)
{
removeBean(datagramChannel);
if (datagramChannel.isOpen())
{
try
{
datagramChannel.close();
}
catch (IOException e)
{
LOG.warn("Unable to close {}", datagramChannel, e);
}
}
}
_localPort = -2;
}
protected DatagramChannel openDatagramChannel() throws IOException
{
InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
DatagramChannel datagramChannel = DatagramChannel.open();
try
{
datagramChannel.socket().bind(bindAddress);
}
catch (Throwable e)
{
IO.close(datagramChannel);
throw new IOException("Failed to bind to " + bindAddress, e);
}
return datagramChannel;
}
@Override
public Object getTransport()
{
return _datagramChannel;
}
@Override
protected void accept(int acceptorID)
{
throw new UnsupportedOperationException(getClass().getSimpleName() + " has no accept mechanism");
}
public class ServerDatagramSelectorManager extends SelectorManager
{
protected ServerDatagramSelectorManager(Executor executor, Scheduler scheduler, int selectors)
{
super(executor, scheduler, selectors);
}
@Override
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException
{
return null;
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException
{
return null;
}
@Override
public String toString()
{
return String.format("DatagramSelectorManager@%s", ServerDatagramConnector.this);
}
}
}

View File

@ -0,0 +1,54 @@
package org.eclipse.jetty.http3.server;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpCompliance;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.jupiter.api.Test;
public class ServerDatagramConnectorTest
{
@Test
public void name() throws Exception
{
Server server = new Server();
HttpConfiguration config = new HttpConfiguration();
config.setHttpCompliance(HttpCompliance.LEGACY); // enable HTTP/0.9
HttpConnectionFactory connectionFactory = new HttpConnectionFactory(config);
ServerDatagramConnector serverDatagramConnector = new ServerDatagramConnector(server, connectionFactory);
serverDatagramConnector.setPort(8443);
server.addConnector(serverDatagramConnector);
server.setHandler(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
PrintWriter writer = response.getWriter();
writer.println("<html>\n" +
"\t<body>\n" +
"\t\tRequest served\n" +
"\t</body>\n" +
"</html>");
}
});
server.start();
System.out.println("Started.");
System.in.read();
server.stop();
}
}

View File

@ -0,0 +1,2 @@
# Jetty Logging using jetty-slf4j-impl
org.eclipse.jetty.LEVEL=DEBUG

19
jetty-http3/pom.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<version>10.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jetty.http3</groupId>
<artifactId>http3-parent</artifactId>
<packaging>pom</packaging>
<name>Jetty :: HTTP3</name>
<modules>
<module>http3-server</module>
</modules>
</project>

View File

@ -199,6 +199,7 @@
<module>jetty-io</module>
<module>jetty-http</module>
<module>jetty-http2</module>
<module>jetty-http3</module>
<module>jetty-server</module>
<module>jetty-xml</module>
<module>jetty-security</module>