Search in sources :

Example 1 with Action

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();
    }
}
Also used : ErrorHandler(org.eclipse.jetty.server.handler.ErrorHandler) Action(org.eclipse.jetty.server.HttpChannelState.Action) BadMessageException(org.eclipse.jetty.http.BadMessageException) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) RuntimeIOException(org.eclipse.jetty.io.RuntimeIOException) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer)

Example 2 with Action

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;
}
Also used : RuntimeIOException(org.eclipse.jetty.io.RuntimeIOException) IOException(java.io.IOException) EndPoint(org.eclipse.jetty.io.EndPoint) ChannelEndPoint(org.eclipse.jetty.io.ChannelEndPoint) ContextHandler(org.eclipse.jetty.server.handler.ContextHandler) Action(org.eclipse.jetty.server.HttpChannelState.Action)

Aggregations

IOException (java.io.IOException)2 RuntimeIOException (org.eclipse.jetty.io.RuntimeIOException)2 Action (org.eclipse.jetty.server.HttpChannelState.Action)2 ByteBuffer (java.nio.ByteBuffer)1 BadMessageException (org.eclipse.jetty.http.BadMessageException)1 HttpFields (org.eclipse.jetty.http.HttpFields)1 MetaData (org.eclipse.jetty.http.MetaData)1 ChannelEndPoint (org.eclipse.jetty.io.ChannelEndPoint)1 EndPoint (org.eclipse.jetty.io.EndPoint)1 ContextHandler (org.eclipse.jetty.server.handler.ContextHandler)1 ErrorHandler (org.eclipse.jetty.server.handler.ErrorHandler)1