|
|
|
@ -18,20 +18,15 @@ package org.springframework.boot.web.embedded.jetty;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
|
|
|
|
import javax.servlet.ServletContext;
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
import javax.servlet.http.HttpServletRequestWrapper;
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
|
|
|
|
import org.eclipse.jetty.http.HttpMethod;
|
|
|
|
|
import org.eclipse.jetty.server.Request;
|
|
|
|
|
import org.eclipse.jetty.server.handler.ErrorHandler;
|
|
|
|
|
import org.eclipse.jetty.server.handler.ErrorHandler.ErrorPageMapper;
|
|
|
|
|
|
|
|
|
|
import org.springframework.util.ReflectionUtils;
|
|
|
|
|
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Variation of Jetty's {@link ErrorHandler} that supports all {@link HttpMethod
|
|
|
|
|
* Variation of Jetty's {@link ErrorPageErrorHandler} that supports all {@link HttpMethod
|
|
|
|
|
* HttpMethods} rather than just {@code GET}, {@code POST} and {@code HEAD}. By default
|
|
|
|
|
* Jetty <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=446039">intentionally only
|
|
|
|
|
* supports a limited set of HTTP methods</a> for error pages, however, Spring Boot
|
|
|
|
@ -40,65 +35,18 @@ import org.springframework.util.ReflectionUtils;
|
|
|
|
|
* @author Phillip Webb
|
|
|
|
|
* @author Christoph Dreis
|
|
|
|
|
*/
|
|
|
|
|
class JettyEmbeddedErrorHandler extends ErrorHandler implements ErrorPageMapper {
|
|
|
|
|
|
|
|
|
|
static final boolean ERROR_PAGE_FOR_METHOD_AVAILABLE;
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
ERROR_PAGE_FOR_METHOD_AVAILABLE = ReflectionUtils.findMethod(ErrorHandler.class, "errorPageForMethod",
|
|
|
|
|
String.class) != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private final ErrorHandler delegate;
|
|
|
|
|
|
|
|
|
|
JettyEmbeddedErrorHandler(ErrorHandler delegate) {
|
|
|
|
|
this.delegate = delegate;
|
|
|
|
|
}
|
|
|
|
|
class JettyEmbeddedErrorHandler extends ErrorPageErrorHandler {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
|
|
|
|
throws IOException {
|
|
|
|
|
if (!ERROR_PAGE_FOR_METHOD_AVAILABLE) {
|
|
|
|
|
String method = request.getMethod();
|
|
|
|
|
if (!HttpMethod.GET.is(method) && !HttpMethod.POST.is(method) && !HttpMethod.HEAD.is(method)) {
|
|
|
|
|
request = new ErrorHttpServletRequest(request);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.delegate.handle(target, baseRequest, request, response);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean errorPageForMethod(String method) { // Available in Jetty 9.4.21+
|
|
|
|
|
public boolean errorPageForMethod(String method) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getErrorPage(HttpServletRequest request) {
|
|
|
|
|
if (this.delegate instanceof ErrorPageMapper) {
|
|
|
|
|
return ((ErrorPageMapper) this.delegate).getErrorPage(request);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class ErrorHttpServletRequest extends HttpServletRequestWrapper {
|
|
|
|
|
|
|
|
|
|
private boolean simulateGetMethod = true;
|
|
|
|
|
|
|
|
|
|
ErrorHttpServletRequest(HttpServletRequest request) {
|
|
|
|
|
super(request);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getMethod() {
|
|
|
|
|
return (this.simulateGetMethod ? HttpMethod.GET.toString() : super.getMethod());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ServletContext getServletContext() {
|
|
|
|
|
this.simulateGetMethod = false;
|
|
|
|
|
return super.getServletContext();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
|
|
|
|
throws IOException {
|
|
|
|
|
baseRequest.setMethod("GET");
|
|
|
|
|
super.doError(target, baseRequest, request, response);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|