Instead of using a Constraint, you can use an HttpConfiguration.Customizer
.
Bonus is that this will apply to all request, even if they don't belong to a context, and works across all context specific web apps too.
package jetty;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.EnumSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Connector;
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.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
public class RejectHttpMethodsDemo
{
public static class BanHttpMethods implements HttpConfiguration.Customizer
{
private final EnumSet<HttpMethod> bannedMethods;
public BanHttpMethods(EnumSet<HttpMethod> bannedMethods)
{
this.bannedMethods = bannedMethods;
}
@Override
public void customize(Connector connector, HttpConfiguration channelConfig, Request request)
{
HttpMethod httpMethod = HttpMethod.fromString(request.getMethod());
if (bannedMethods.contains(httpMethod))
{
request.setHandled(true);
request.getResponse().setStatus(HttpStatus.METHOD_NOT_ALLOWED_405);
}
}
}
public static void main(String[] args) throws Exception
{
Server server = new Server();
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new BanHttpMethods(EnumSet.of(HttpMethod.TRACE, HttpMethod.MOVE)));
ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
connector.setPort(9090);
server.addConnector(connector);
HandlerList handlers = new HandlerList();
handlers.addHandler(new AbstractHandler()
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain");
response.getWriter().printf("Hello, You asked to %s %s, that is all%n", baseRequest.getMethod(), baseRequest.getRequestURI());
}
});
handlers.addHandler(new DefaultHandler());
server.setHandler(handlers);
server.start();
try
{
HttpClient httpClient = HttpClient.newHttpClient();
demoRequest(httpClient, server.getURI().resolve("/apple"), "GET");
demoRequest(httpClient, server.getURI().resolve("/banana"), "TRACE");
demoRequest(httpClient, server.getURI().resolve("/cherry"), "MOVE");
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
server.stop();
}
}
private static void demoRequest(HttpClient httpClient, URI path, String method)
{
try
{
HttpRequest httpRequest = HttpRequest.newBuilder(path)
.method(method, HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
System.out.printf("HTTP %s %s Response Status: %d%n", httpRequest.method(), httpRequest.uri(), httpResponse.statusCode());
System.out.println(httpResponse.body());
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
}
}
With output ...
2022-01-21 11:23:13.718:INFO::main: Logging initialized @210ms to org.eclipse.jetty.util.log.StdErrLog
2022-01-21 11:23:13.775:INFO:oejs.Server:main: jetty-9.4.43.v20210629; built: 2021-06-30T11:07:22.254Z; git: 526006ecfa3af7f1a27ef3a288e2bef7ea9dd7e8; jvm 11.0.12+7
2022-01-21 11:23:13.809:INFO:oejs.AbstractConnector:main: Started ServerConnector@4fcd19b3{HTTP/1.1, (http/1.1)}{0.0.0.0:9090}
2022-01-21 11:23:13.812:INFO:oejs.Server:main: Started @308ms
HTTP GET http://127.0.1.1:9090/apple Response Status: 200
Hello, You asked to GET /apple, that is all
HTTP TRACE http://127.0.1.1:9090/banana Response Status: 405
HTTP MOVE http://127.0.1.1:9090/cherry Response Status: 405
2022-01-21 11:23:14.186:INFO:oejs.AbstractConnector:main: Stopped ServerConnector@4fcd19b3{HTTP/1.1, (http/1.1)}{0.0.0.0:9090}