424180 extensible bad message content

This commit is contained in:
Greg Wilkins 2013-12-19 11:47:48 +11:00
parent 5643e588e2
commit 892127ca62
3 changed files with 41 additions and 4 deletions

View File

@ -50,6 +50,7 @@ import org.eclipse.jetty.server.HttpChannelState.Action;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.util.BlockingCallback; import org.eclipse.jetty.util.BlockingCallback;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
@ -672,7 +673,16 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
try try
{ {
if (_state.handling()==Action.REQUEST_DISPATCH) if (_state.handling()==Action.REQUEST_DISPATCH)
sendResponse(new ResponseInfo(HttpVersion.HTTP_1_1,new HttpFields(),0,status,reason,false),null,true); {
ByteBuffer content=null;
HttpFields fields=new HttpFields();
ErrorHandler handler=getServer().getBean(ErrorHandler.class);
if (handler!=null)
content=handler.badMessageError(status,reason,fields);
sendResponse(new ResponseInfo(HttpVersion.HTTP_1_1,fields,0,status,reason,false),content ,true);
}
} }
catch (IOException e) catch (IOException e)
{ {

View File

@ -22,18 +22,22 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.nio.ByteBuffer;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.ByteArrayISO8859Writer; import org.eclipse.jetty.util.ByteArrayISO8859Writer;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -42,7 +46,8 @@ import org.eclipse.jetty.util.log.Logger;
/** Handler for Error pages /** Handler for Error pages
* An ErrorHandler is registered with {@link ContextHandler#setErrorHandler(ErrorHandler)} or * An ErrorHandler is registered with {@link ContextHandler#setErrorHandler(ErrorHandler)} or
* {@link org.eclipse.jetty.server.Server#addBean(Object)}. * {@link org.eclipse.jetty.server.Server#addBean(Object)}.
* It is called by the HttpResponse.sendError method to write a error page. * It is called by the HttpResponse.sendError method to write a error page via {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)}
* or via {@link #badMessageError(int, String, HttpFields)} for bad requests for which a dispatch cannot be done.
* *
*/ */
public class ErrorHandler extends AbstractHandler public class ErrorHandler extends AbstractHandler
@ -191,6 +196,25 @@ public class ErrorHandler extends AbstractHandler
} }
} }
/* ------------------------------------------------------------ */
/** Bad Message Error body
* <p>Generate a error response body to be sent for a bad message.
* In this case there is something wrong with the request, so either
* a request cannot be built, or it is not safe to build a request.
* This method allows for a simple error page body to be returned
* and some response headers to be set.
* @param status The error code that will be sent
* @param reason The reason for the error code (may be null)
* @param fields The header fields that will be sent with the response.
* @return The content as a ByteBuffer, or null for no body.
*/
public ByteBuffer badMessageError(int status, String reason, HttpFields fields)
{
if (reason==null)
reason=HttpStatus.getMessage(status);
fields.put(HttpHeader.CONTENT_TYPE,MimeTypes.Type.TEXT_HTML_8859_1.asString());
return BufferUtil.toBuffer("<h1>Bad Message "+status+"</h1><pre>reason: "+reason+"</pre>");
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get the cacheControl. /** Get the cacheControl.

View File

@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.util.log.StdErrLog;
@ -71,6 +72,7 @@ public class HttpConnectionTest
connector.setIdleTimeout(500); connector.setIdleTimeout(500);
server.addConnector(connector); server.addConnector(connector);
server.setHandler(new DumpHandler()); server.setHandler(new DumpHandler());
server.addBean(new ErrorHandler());
server.start(); server.start();
} }
@ -640,7 +642,8 @@ public class HttpConnectionTest
request.append("\015\012"); request.append("\015\012");
response = connector.getResponses(request.toString()); response = connector.getResponses(request.toString());
checkContains(response, offset, "HTTP/1.1 413"); offset = checkContains(response, offset, "HTTP/1.1 413");
checkContains(response, offset, "<h1>Bad Message 413</h1><pre>reason: Request Entity Too Large</pre>");
} }
@Test @Test