Search in sources :

Example 6 with BadMessageException

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

the class ServerTimeoutsTest method testBlockingReadWithMinimumDataRateBelowLimit.

@Test
public void testBlockingReadWithMinimumDataRateBelowLimit() throws Exception {
    int bytesPerSecond = 20;
    httpConfig.setMinRequestDataRate(bytesPerSecond);
    CountDownLatch handlerLatch = new CountDownLatch(1);
    start(new AbstractHandler.ErrorDispatchHandler() {

        @Override
        public void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            try {
                baseRequest.setHandled(true);
                ServletInputStream input = request.getInputStream();
                while (true) {
                    int read = input.read();
                    if (read < 0)
                        break;
                }
            } catch (BadMessageException x) {
                handlerLatch.countDown();
                throw x;
            }
        }
    });
    DeferredContentProvider contentProvider = new DeferredContentProvider();
    CountDownLatch resultLatch = new CountDownLatch(1);
    client.newRequest(newURI()).content(contentProvider).send(result -> {
        if (result.getResponse().getStatus() == HttpStatus.REQUEST_TIMEOUT_408)
            resultLatch.countDown();
    });
    for (int i = 0; i < 3; ++i) {
        contentProvider.offer(ByteBuffer.allocate(bytesPerSecond / 2));
        Thread.sleep(2500);
    }
    contentProvider.close();
    // Request should timeout.
    Assert.assertTrue(handlerLatch.await(5, TimeUnit.SECONDS));
    Assert.assertTrue(resultLatch.await(5, TimeUnit.SECONDS));
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException) Request(org.eclipse.jetty.server.Request) HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) AbstractHandler(org.eclipse.jetty.server.handler.AbstractHandler) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) ServletInputStream(javax.servlet.ServletInputStream) DeferredContentProvider(org.eclipse.jetty.client.util.DeferredContentProvider) Test(org.junit.Test)

Example 7 with BadMessageException

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

the class HTTP2ServerConnection method upgrade.

public boolean upgrade(Request request) {
    if (HttpMethod.PRI.is(request.getMethod())) {
        getParser().directUpgrade();
    } else {
        HttpField settingsField = request.getFields().getField(HttpHeader.HTTP2_SETTINGS);
        if (settingsField == null)
            throw new BadMessageException("Missing " + HttpHeader.HTTP2_SETTINGS + " header");
        String value = settingsField.getValue();
        final byte[] settings = B64Code.decodeRFC4648URL(value == null ? "" : value);
        if (LOG.isDebugEnabled())
            LOG.debug("{} settings {}", this, TypeUtil.toHexString(settings));
        SettingsFrame settingsFrame = SettingsBodyParser.parseBody(BufferUtil.toBuffer(settings));
        if (settingsFrame == null) {
            LOG.warn("Invalid {} header value: {}", HttpHeader.HTTP2_SETTINGS, value);
            throw new BadMessageException();
        }
        getParser().standardUpgrade();
        upgradeFrames.add(new PrefaceFrame());
        upgradeFrames.add(settingsFrame);
        // Remember the request to send a response from onOpen().
        upgradeFrames.add(new HeadersFrame(1, new Request(request), null, true));
    }
    return true;
}
Also used : PrefaceFrame(org.eclipse.jetty.http2.frames.PrefaceFrame) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) HttpField(org.eclipse.jetty.http.HttpField) BadMessageException(org.eclipse.jetty.http.BadMessageException) Request(org.eclipse.jetty.http.MetaData.Request) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame)

Example 8 with BadMessageException

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

the class HttpChannelOverHTTP2 method onPushRequest.

public Runnable onPushRequest(MetaData.Request request) {
    try {
        onRequest(request);
        getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE);
        onContentComplete();
        onRequestComplete();
        if (LOG.isDebugEnabled()) {
            Stream stream = getStream();
            LOG.debug("HTTP2 PUSH Request #{}/{}:{}{} {} {}{}{}", stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), request.getMethod(), request.getURI(), request.getHttpVersion(), System.lineSeparator(), request.getFields());
        }
        return this;
    } catch (BadMessageException x) {
        onBadMessage(x.getCode(), x.getReason());
        return null;
    } catch (Throwable x) {
        onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null);
        return null;
    }
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException) Stream(org.eclipse.jetty.http2.api.Stream) IStream(org.eclipse.jetty.http2.IStream)

Example 9 with BadMessageException

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

the class HpackDecoder method decode.

public MetaData decode(ByteBuffer buffer) {
    if (LOG.isDebugEnabled())
        LOG.debug(String.format("CtxTbl[%x] decoding %d octets", _context.hashCode(), buffer.remaining()));
    // If the buffer is big, don't even think about decoding it
    if (buffer.remaining() > _builder.getMaxSize())
        throw new BadMessageException(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431, "Header frame size " + buffer.remaining() + ">" + _builder.getMaxSize());
    while (buffer.hasRemaining()) {
        if (LOG.isDebugEnabled() && buffer.hasArray()) {
            int l = Math.min(buffer.remaining(), 32);
            LOG.debug("decode {}{}", TypeUtil.toHexString(buffer.array(), buffer.arrayOffset() + buffer.position(), l), l < buffer.remaining() ? "..." : "");
        }
        byte b = buffer.get();
        if (b < 0) {
            // 7.1 indexed if the high bit is set
            int index = NBitInteger.decode(buffer, 7);
            Entry entry = _context.get(index);
            if (entry == null) {
                throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Unknown index " + index);
            } else if (entry.isStatic()) {
                if (LOG.isDebugEnabled())
                    LOG.debug("decode IdxStatic {}", entry);
                // emit field
                _builder.emit(entry.getHttpField());
            // TODO copy and add to reference set if there is room
            // _context.add(entry.getHttpField());
            } else {
                if (LOG.isDebugEnabled())
                    LOG.debug("decode Idx {}", entry);
                // emit
                _builder.emit(entry.getHttpField());
            }
        } else {
            // look at the first nibble in detail
            byte f = (byte) ((b & 0xF0) >> 4);
            String name;
            HttpHeader header;
            String value;
            boolean indexed;
            int name_index;
            switch(f) {
                // 7.3
                case 2:
                case // 7.3
                3:
                    // change table size
                    int size = NBitInteger.decode(buffer, 5);
                    if (LOG.isDebugEnabled())
                        LOG.debug("decode resize=" + size);
                    if (size > _localMaxDynamicTableSize)
                        throw new IllegalArgumentException();
                    _context.resize(size);
                    continue;
                // 7.2.2
                case 0:
                case // 7.2.3
                1:
                    indexed = false;
                    name_index = NBitInteger.decode(buffer, 4);
                    break;
                // 7.2.1
                case 4:
                // 7.2.1
                case 5:
                // 7.2.1
                case 6:
                case // 7.2.1
                7:
                    indexed = true;
                    name_index = NBitInteger.decode(buffer, 6);
                    break;
                default:
                    throw new IllegalStateException();
            }
            boolean huffmanName = false;
            // decode the name
            if (name_index > 0) {
                Entry name_entry = _context.get(name_index);
                name = name_entry.getHttpField().getName();
                header = name_entry.getHttpField().getHeader();
            } else {
                huffmanName = (buffer.get() & 0x80) == 0x80;
                int length = NBitInteger.decode(buffer, 7);
                _builder.checkSize(length, huffmanName);
                if (huffmanName)
                    name = Huffman.decode(buffer, length);
                else
                    name = toASCIIString(buffer, length);
                for (int i = 0; i < name.length(); i++) {
                    char c = name.charAt(i);
                    if (c >= 'A' && c <= 'Z') {
                        throw new BadMessageException(400, "Uppercase header name");
                    }
                }
                header = HttpHeader.CACHE.get(name);
            }
            // decode the value
            boolean huffmanValue = (buffer.get() & 0x80) == 0x80;
            int length = NBitInteger.decode(buffer, 7);
            _builder.checkSize(length, huffmanValue);
            if (huffmanValue)
                value = Huffman.decode(buffer, length);
            else
                value = toASCIIString(buffer, length);
            // Make the new field
            HttpField field;
            if (header == null) {
                // just make a normal field and bypass header name lookup
                field = new HttpField(null, name, value);
            } else {
                // and/or of a type that may be looked up multiple times.
                switch(header) {
                    case C_STATUS:
                        if (indexed)
                            field = new HttpField.IntValueHttpField(header, name, value);
                        else
                            field = new HttpField(header, name, value);
                        break;
                    case C_AUTHORITY:
                        field = new AuthorityHttpField(value);
                        break;
                    case CONTENT_LENGTH:
                        if ("0".equals(value))
                            field = CONTENT_LENGTH_0;
                        else
                            field = new HttpField.LongValueHttpField(header, name, value);
                        break;
                    default:
                        field = new HttpField(header, name, value);
                        break;
                }
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("decoded '{}' by {}/{}/{}", field, name_index > 0 ? "IdxName" : (huffmanName ? "HuffName" : "LitName"), huffmanValue ? "HuffVal" : "LitVal", indexed ? "Idx" : "");
            }
            // emit the field
            _builder.emit(field);
            // if indexed
            if (indexed) {
                // add to dynamic table
                if (_context.add(field) == null)
                    throw new BadMessageException(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431, "Indexed field value too large");
            }
        }
    }
    return _builder.build();
}
Also used : BadMessageException(org.eclipse.jetty.http.BadMessageException) Entry(org.eclipse.jetty.http2.hpack.HpackContext.Entry) HttpHeader(org.eclipse.jetty.http.HttpHeader) HttpField(org.eclipse.jetty.http.HttpField)

Example 10 with BadMessageException

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

the class MetaDataBuilder method emit.

public void emit(HttpField field) {
    HttpHeader header = field.getHeader();
    String name = field.getName();
    String value = field.getValue();
    int field_size = name.length() + (value == null ? 0 : value.length());
    _size += field_size + 32;
    if (_size > _maxSize)
        throw new BadMessageException(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431, "Header size " + _size + ">" + _maxSize);
    if (field instanceof StaticTableHttpField) {
        StaticTableHttpField staticField = (StaticTableHttpField) field;
        switch(header) {
            case C_STATUS:
                _status = (Integer) staticField.getStaticValue();
                break;
            case C_METHOD:
                _method = value;
                break;
            case C_SCHEME:
                _scheme = (HttpScheme) staticField.getStaticValue();
                break;
            default:
                throw new IllegalArgumentException(name);
        }
    } else if (header != null) {
        switch(header) {
            case C_STATUS:
                _status = field.getIntValue();
                break;
            case C_METHOD:
                _method = value;
                break;
            case C_SCHEME:
                if (value != null)
                    _scheme = HttpScheme.CACHE.get(value);
                break;
            case C_AUTHORITY:
                if (field instanceof HostPortHttpField)
                    _authority = (HostPortHttpField) field;
                else if (value != null)
                    _authority = new AuthorityHttpField(value);
                break;
            case HOST:
                // :authority fields must come first.  If we have one, ignore the host header as far as authority goes.
                if (_authority == null) {
                    if (field instanceof HostPortHttpField)
                        _authority = (HostPortHttpField) field;
                    else if (value != null)
                        _authority = new AuthorityHttpField(value);
                }
                _fields.add(field);
                break;
            case C_PATH:
                _path = value;
                break;
            case CONTENT_LENGTH:
                _contentLength = field.getLongValue();
                _fields.add(field);
                break;
            default:
                if (name.charAt(0) != ':')
                    _fields.add(field);
                break;
        }
    } else {
        if (name.charAt(0) != ':')
            _fields.add(field);
    }
}
Also used : HttpHeader(org.eclipse.jetty.http.HttpHeader) BadMessageException(org.eclipse.jetty.http.BadMessageException) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField)

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