Search in sources :

Example 1 with BadMessageException

use of org.eclipse.jetty.http.BadMessageException in project jetty.project by eclipse.

the class HttpChannelState method onError.

protected void onError(Throwable failure) {
    final List<AsyncListener> listeners;
    final AsyncContextEvent event;
    final Request baseRequest = _channel.getRequest();
    int code = HttpStatus.INTERNAL_SERVER_ERROR_500;
    String reason = null;
    if (failure instanceof BadMessageException) {
        BadMessageException bme = (BadMessageException) failure;
        code = bme.getCode();
        reason = bme.getReason();
    } else if (failure instanceof UnavailableException) {
        if (((UnavailableException) failure).isPermanent())
            code = HttpStatus.NOT_FOUND_404;
        else
            code = HttpStatus.SERVICE_UNAVAILABLE_503;
    }
    try (Locker.Lock lock = _locker.lock()) {
        if (LOG.isDebugEnabled())
            LOG.debug("onError {} {}", toStringLocked(), failure);
        // Set error on request.
        if (_event != null) {
            _event.addThrowable(failure);
            _event.getSuppliedRequest().setAttribute(ERROR_STATUS_CODE, code);
            _event.getSuppliedRequest().setAttribute(ERROR_EXCEPTION, failure);
            _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, failure == null ? null : failure.getClass());
            _event.getSuppliedRequest().setAttribute(ERROR_MESSAGE, reason);
        } else {
            Throwable error = (Throwable) baseRequest.getAttribute(ERROR_EXCEPTION);
            if (error != null)
                throw new IllegalStateException("Error already set", error);
            baseRequest.setAttribute(ERROR_STATUS_CODE, code);
            baseRequest.setAttribute(ERROR_EXCEPTION, failure);
            baseRequest.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, failure == null ? null : failure.getClass());
            baseRequest.setAttribute(ERROR_MESSAGE, reason);
        }
        // Are we blocking?
        if (_async == Async.NOT_ASYNC) {
            // Only called from within HttpChannel Handling, so much be dispatched, let's stay dispatched!
            if (_state == State.DISPATCHED) {
                _state = State.THROWN;
                return;
            }
            throw new IllegalStateException(this.getStatusStringLocked());
        }
        // We are Async
        _async = Async.ERRORING;
        listeners = _asyncListeners;
        event = _event;
    }
    if (listeners != null) {
        Runnable task = new Runnable() {

            @Override
            public void run() {
                for (AsyncListener listener : listeners) {
                    try {
                        listener.onError(event);
                    } catch (Throwable x) {
                        LOG.warn(x + " while invoking onError listener " + listener);
                        LOG.debug(x);
                    }
                }
            }

            @Override
            public String toString() {
                return "onError";
            }
        };
        runInContext(event, task);
    }
    boolean dispatch = false;
    try (Locker.Lock lock = _locker.lock()) {
        switch(_async) {
            case ERRORING:
                {
                    // Still in this state ? The listeners did not invoke API methods
                    // and the container must provide a default error dispatch.
                    _async = Async.ERRORED;
                    break;
                }
            case DISPATCH:
            case COMPLETE:
                {
                    // The listeners called dispatch() or complete().
                    break;
                }
            default:
                {
                    throw new IllegalStateException(toString());
                }
        }
        if (_state == State.ASYNC_WAIT) {
            _state = State.ASYNC_WOKEN;
            dispatch = true;
        }
    }
    if (dispatch) {
        if (LOG.isDebugEnabled())
            LOG.debug("Dispatch after error {}", this);
        scheduleDispatch();
    }
}
Also used : Locker(org.eclipse.jetty.util.thread.Locker) BadMessageException(org.eclipse.jetty.http.BadMessageException) UnavailableException(javax.servlet.UnavailableException) AsyncListener(javax.servlet.AsyncListener)

Example 2 with BadMessageException

use of org.eclipse.jetty.http.BadMessageException in project jetty.project by eclipse.

the class HpackTest method encodeDecodeTooLargeTest.

@Test
public void encodeDecodeTooLargeTest() {
    HpackEncoder encoder = new HpackEncoder();
    HpackDecoder decoder = new HpackDecoder(4096, 164);
    ByteBuffer buffer = BufferUtil.allocate(16 * 1024);
    HttpFields fields0 = new HttpFields();
    fields0.add("1234567890", "1234567890123456789012345678901234567890");
    fields0.add("Cookie", "abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR");
    MetaData original0 = new MetaData(HttpVersion.HTTP_2, fields0);
    BufferUtil.clearToFill(buffer);
    encoder.encode(buffer, original0);
    BufferUtil.flipToFlush(buffer, 0);
    MetaData decoded0 = (MetaData) decoder.decode(buffer);
    assertMetadataSame(original0, decoded0);
    HttpFields fields1 = new HttpFields();
    fields1.add("1234567890", "1234567890123456789012345678901234567890");
    fields1.add("Cookie", "abcdeffhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR");
    fields1.add("x", "y");
    MetaData original1 = new MetaData(HttpVersion.HTTP_2, fields1);
    BufferUtil.clearToFill(buffer);
    encoder.encode(buffer, original1);
    BufferUtil.flipToFlush(buffer, 0);
    try {
        decoder.decode(buffer);
        Assert.fail();
    } catch (BadMessageException e) {
        assertEquals(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431, e.getCode());
    }
}
Also used : MetaData(org.eclipse.jetty.http.MetaData) BadMessageException(org.eclipse.jetty.http.BadMessageException) HttpFields(org.eclipse.jetty.http.HttpFields) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 3 with BadMessageException

use of org.eclipse.jetty.http.BadMessageException in project jetty.project by eclipse.

the class SecureRequestCustomizer method customize.

/**
     * <p>
     * Customizes the request attributes to be set for SSL requests.
     * </p>
     * <p>
     * The requirements of the Servlet specs are:
     * </p>
     * <ul>
     * <li>an attribute named "javax.servlet.request.ssl_session_id" of type String (since Servlet Spec 3.0).</li>
     * <li>an attribute named "javax.servlet.request.cipher_suite" of type String.</li>
     * <li>an attribute named "javax.servlet.request.key_size" of type Integer.</li>
     * <li>an attribute named "javax.servlet.request.X509Certificate" of type java.security.cert.X509Certificate[]. This
     * is an array of objects of type X509Certificate, the order of this array is defined as being in ascending order of
     * trust. The first certificate in the chain is the one set by the client, the next is the one used to authenticate
     * the first, and so on.</li>
     * </ul>
     * 
     * @param sslEngine
     *            the sslEngine to be customized.
     * @param request
     *            HttpRequest to be customized.
     */
protected void customize(SSLEngine sslEngine, Request request) {
    SSLSession sslSession = sslEngine.getSession();
    if (_sniHostCheck) {
        String name = request.getServerName();
        X509 x509 = (X509) sslSession.getValue(SniX509ExtendedKeyManager.SNI_X509);
        if (x509 != null && !x509.matches(name)) {
            LOG.warn("Host {} does not match SNI {}", name, x509);
            throw new BadMessageException(400, "Host does not match SNI");
        }
        if (LOG.isDebugEnabled())
            LOG.debug("Host {} matched SNI {}", name, x509);
    }
    try {
        String cipherSuite = sslSession.getCipherSuite();
        Integer keySize;
        X509Certificate[] certs;
        String idStr;
        CachedInfo cachedInfo = (CachedInfo) sslSession.getValue(CACHED_INFO_ATTR);
        if (cachedInfo != null) {
            keySize = cachedInfo.getKeySize();
            certs = cachedInfo.getCerts();
            idStr = cachedInfo.getIdStr();
        } else {
            keySize = SslContextFactory.deduceKeyLength(cipherSuite);
            certs = SslContextFactory.getCertChain(sslSession);
            byte[] bytes = sslSession.getId();
            idStr = TypeUtil.toHexString(bytes);
            cachedInfo = new CachedInfo(keySize, certs, idStr);
            sslSession.putValue(CACHED_INFO_ATTR, cachedInfo);
        }
        if (certs != null)
            request.setAttribute("javax.servlet.request.X509Certificate", certs);
        request.setAttribute("javax.servlet.request.cipher_suite", cipherSuite);
        request.setAttribute("javax.servlet.request.key_size", keySize);
        request.setAttribute("javax.servlet.request.ssl_session_id", idStr);
        String sessionAttribute = getSslSessionAttribute();
        if (sessionAttribute != null && !sessionAttribute.isEmpty())
            request.setAttribute(sessionAttribute, sslSession);
    } catch (Exception e) {
        LOG.warn(Log.EXCEPTION, e);
    }
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException) SSLSession(javax.net.ssl.SSLSession) X509(org.eclipse.jetty.util.ssl.X509) X509Certificate(java.security.cert.X509Certificate) BadMessageException(org.eclipse.jetty.http.BadMessageException)

Example 4 with BadMessageException

use of org.eclipse.jetty.http.BadMessageException in project jetty.project by eclipse.

the class Request method setMetaData.

/* ------------------------------------------------------------ */
/**
     * @param request the Request metadata
     */
public void setMetaData(org.eclipse.jetty.http.MetaData.Request request) {
    _metaData = request;
    setMethod(request.getMethod());
    HttpURI uri = request.getURI();
    _originalURI = uri.isAbsolute() && request.getHttpVersion() != HttpVersion.HTTP_2 ? uri.toString() : uri.getPathQuery();
    String path = uri.getDecodedPath();
    String info;
    if (path == null || path.length() == 0) {
        if (uri.isAbsolute()) {
            path = "/";
            uri.setPath(path);
        } else {
            setPathInfo("");
            throw new BadMessageException(400, "Bad URI");
        }
        info = path;
    } else if (!path.startsWith("/")) {
        if (!"*".equals(path) && !HttpMethod.CONNECT.is(getMethod())) {
            setPathInfo(path);
            throw new BadMessageException(400, "Bad URI");
        }
        info = path;
    } else
        // TODO should this be done prior to decoding???
        info = URIUtil.canonicalPath(path);
    if (info == null) {
        setPathInfo(path);
        throw new BadMessageException(400, "Bad URI");
    }
    setPathInfo(info);
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException) HttpURI(org.eclipse.jetty.http.HttpURI)

Example 5 with BadMessageException

use of org.eclipse.jetty.http.BadMessageException in project jetty.project by eclipse.

the class HttpInput method read.

@Override
public int read(byte[] b, int off, int len) throws IOException {
    boolean wake = false;
    int l;
    synchronized (_inputQ) {
        // Setup blocking only if not async
        if (!isAsync()) {
            if (_blockUntil == 0) {
                long blockingTimeout = getBlockingTimeout();
                if (blockingTimeout > 0)
                    _blockUntil = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(blockingTimeout);
            }
        }
        // Calculate minimum request rate for DOS protection
        long minRequestDataRate = _channelState.getHttpChannel().getHttpConfiguration().getMinRequestDataRate();
        if (minRequestDataRate > 0 && _firstByteTimeStamp != -1) {
            long period = System.nanoTime() - _firstByteTimeStamp;
            if (period > 0) {
                long minimum_data = minRequestDataRate * TimeUnit.NANOSECONDS.toMillis(period) / TimeUnit.SECONDS.toMillis(1);
                if (_contentArrived < minimum_data)
                    throw new BadMessageException(HttpStatus.REQUEST_TIMEOUT_408, String.format("Request data rate < %d B/s", minRequestDataRate));
            }
        }
        // Consume content looking for bytes to read
        while (true) {
            Content item = nextContent();
            if (item != null) {
                l = get(item, b, off, len);
                if (LOG.isDebugEnabled())
                    LOG.debug("{} read {} from {}", this, l, item);
                // Consume any following poison pills
                if (item.isEmpty())
                    nextInterceptedContent();
                break;
            }
            // No content, so should we block?
            if (!_state.blockForContent(this)) {
                // Not blocking, so what should we return?
                l = _state.noContent();
                // If EOF do we need to wake for allDataRead callback?
                if (l < 0)
                    wake = _channelState.onReadEof();
                break;
            }
        }
    }
    if (wake)
        wake();
    return l;
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException)

Aggregations

BadMessageException (org.eclipse.jetty.http.BadMessageException)15 ByteBuffer (java.nio.ByteBuffer)4 HttpFields (org.eclipse.jetty.http.HttpFields)4 Test (org.junit.Test)4 IOException (java.io.IOException)3 MetaData (org.eclipse.jetty.http.MetaData)3 HttpField (org.eclipse.jetty.http.HttpField)2 HttpHeader (org.eclipse.jetty.http.HttpHeader)2 IStream (org.eclipse.jetty.http2.IStream)2 Stream (org.eclipse.jetty.http2.api.Stream)2 X509Certificate (java.security.cert.X509Certificate)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 SSLSession (javax.net.ssl.SSLSession)1 AsyncListener (javax.servlet.AsyncListener)1 ServletException (javax.servlet.ServletException)1 ServletInputStream (javax.servlet.ServletInputStream)1 UnavailableException (javax.servlet.UnavailableException)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 DeferredContentProvider (org.eclipse.jetty.client.util.DeferredContentProvider)1