use of org.eclipse.jetty.server.HttpChannelState.Action in project jetty.project by eclipse.
the class HttpChannel method onBadMessage.
public void onBadMessage(int status, String reason) {
if (status < 400 || status > 599)
status = HttpStatus.BAD_REQUEST_400;
Action action;
try {
action = _state.handling();
} catch (IllegalStateException e) {
// The bad message cannot be handled in the current state, so throw
// to hopefull somebody that can handle
abort(e);
throw new BadMessageException(status, reason);
}
try {
if (action == Action.DISPATCH) {
ByteBuffer content = null;
HttpFields fields = new HttpFields();
ErrorHandler handler = getServer().getBean(ErrorHandler.class);
if (handler != null)
content = handler.badMessageError(status, reason, fields);
sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1, status, reason, fields, BufferUtil.length(content)), content, true);
}
} catch (IOException e) {
LOG.debug(e);
} finally {
// TODO: review whether it's the right state to check.
if (_state.unhandle() == Action.COMPLETE)
_state.onComplete();
else
// TODO: don't throw from finally blocks !
throw new IllegalStateException();
onCompleted();
}
}
use of org.eclipse.jetty.server.HttpChannelState.Action in project jetty.project by eclipse.
the class HttpChannel method handle.
/**
* @return True if the channel is ready to continue handling (ie it is not suspended)
*/
public boolean handle() {
if (LOG.isDebugEnabled())
LOG.debug("{} handle {} ", this, _request.getHttpURI());
HttpChannelState.Action action = _state.handling();
// already happened when unhandle is called.
loop: while (!getServer().isStopped()) {
try {
if (LOG.isDebugEnabled())
LOG.debug("{} action {}", this, action);
switch(action) {
case TERMINATED:
case WAIT:
break loop;
case DISPATCH:
{
if (!_request.hasMetaData())
throw new IllegalStateException("state=" + _state);
_request.setHandled(false);
_response.getHttpOutput().reopen();
try {
_request.setDispatcherType(DispatcherType.REQUEST);
List<HttpConfiguration.Customizer> customizers = _configuration.getCustomizers();
if (!customizers.isEmpty()) {
for (HttpConfiguration.Customizer customizer : customizers) {
customizer.customize(getConnector(), _configuration, _request);
if (_request.isHandled())
break;
}
}
if (!_request.isHandled())
getServer().handle(this);
} finally {
_request.setDispatcherType(null);
}
break;
}
case ASYNC_DISPATCH:
{
_request.setHandled(false);
_response.getHttpOutput().reopen();
try {
_request.setDispatcherType(DispatcherType.ASYNC);
getServer().handleAsync(this);
} finally {
_request.setDispatcherType(null);
}
break;
}
case ERROR_DISPATCH:
{
if (_response.isCommitted()) {
if (LOG.isDebugEnabled())
LOG.debug("Could not perform Error Dispatch because the response is already committed, aborting");
_transport.abort((Throwable) _request.getAttribute(ERROR_EXCEPTION));
} else {
_response.reset();
Integer icode = (Integer) _request.getAttribute(ERROR_STATUS_CODE);
int code = icode != null ? icode : HttpStatus.INTERNAL_SERVER_ERROR_500;
_response.setStatus(code);
_request.setAttribute(ERROR_STATUS_CODE, code);
if (icode == null)
_request.setAttribute(ERROR_STATUS_CODE, code);
_request.setHandled(false);
_response.getHttpOutput().reopen();
try {
_request.setDispatcherType(DispatcherType.ERROR);
getServer().handle(this);
} finally {
_request.setDispatcherType(null);
}
}
break;
}
case ASYNC_ERROR:
{
throw _state.getAsyncContextEvent().getThrowable();
}
case READ_CALLBACK:
{
ContextHandler handler = _state.getContextHandler();
if (handler != null)
handler.handle(_request, _request.getHttpInput());
else
_request.getHttpInput().run();
break;
}
case WRITE_CALLBACK:
{
ContextHandler handler = _state.getContextHandler();
if (handler != null)
handler.handle(_request, _response.getHttpOutput());
else
_response.getHttpOutput().run();
break;
}
case COMPLETE:
{
if (!_response.isCommitted() && !_request.isHandled()) {
_response.sendError(HttpStatus.NOT_FOUND_404);
} else {
// RFC 7230, section 3.3.
int status = _response.getStatus();
boolean hasContent = !(_request.isHead() || HttpMethod.CONNECT.is(_request.getMethod()) && status == HttpStatus.OK_200 || HttpStatus.isInformational(status) || status == HttpStatus.NO_CONTENT_204 || status == HttpStatus.NOT_MODIFIED_304);
if (hasContent && !_response.isContentComplete(_response.getHttpOutput().getWritten())) {
if (isCommitted())
_transport.abort(new IOException("insufficient content written"));
else
_response.sendError(HttpStatus.INTERNAL_SERVER_ERROR_500, "insufficient content written");
}
}
_response.closeOutput();
_request.setHandled(true);
_state.onComplete();
onCompleted();
break loop;
}
default:
{
throw new IllegalStateException("state=" + _state);
}
}
} catch (Throwable failure) {
if ("org.eclipse.jetty.continuation.ContinuationThrowable".equals(failure.getClass().getName()))
LOG.ignore(failure);
else
handleException(failure);
}
action = _state.unhandle();
}
if (LOG.isDebugEnabled())
LOG.debug("{} handle exit, result {}", this, action);
boolean suspended = action == Action.WAIT;
return !suspended;
}
Aggregations