Search in sources :

Example 1 with HttpBeginExFW

use of io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpBeginExFW in project zilla by aklivity.

the class HttpServerFactory method decodeHeaders.

private int decodeHeaders(HttpServer server, long traceId, long authorization, long budgetId, int reserved, DirectBuffer buffer, int offset, int limit) {
    final HttpBeginExFW.Builder httpBeginEx = beginExRW.wrap(codecBuffer, 0, codecBuffer.capacity()).typeId(httpTypeId);
    DirectBuffer error = null;
    final int endOfStartAt = limitOfBytes(buffer, offset, limit, CRLF_BYTES);
    if (endOfStartAt != -1) {
        if (server.upgrade && endOfStartAt >= offset + 16 && CharSequence.compare("PRI * HTTP/2.0\r\n", new AsciiSequenceView(buffer, offset, 16)) == 0) {
            server.delegate = new Http2Server(server);
            signaler.signalNow(server.routeId, server.replyId, DELEGATE_SIGNAL);
            return offset;
        }
        hasAuthority.value = false;
        error = decodeStartLine(buffer, offset, endOfStartAt, httpBeginEx, hasAuthority, server.decodeScheme);
    } else if (limit - offset >= maximumHeadersSize) {
        error = ERROR_414_REQUEST_URI_TOO_LONG;
    } else {
        final int endOfMethodLimit = Math.min(limit, offset + MAXIMUM_METHOD_LENGTH);
        final int endOfMethodAt = indexOfByte(buffer, offset, endOfMethodLimit, SPACE_BYTE);
        if (endOfMethodAt != -1) {
            final CharSequence method = new AsciiSequenceView(buffer, offset, endOfMethodAt - offset);
            if (!SUPPORTED_METHODS.contains(method)) {
                error = ERROR_501_METHOD_NOT_IMPLEMENTED;
            }
        } else if (limit > endOfMethodLimit) {
            error = ERROR_400_BAD_REQUEST;
        }
    }
    final int endOfHeadersAt = limitOfBytes(buffer, offset, limit, CRLFCRLF_BYTES);
    if (error == null && endOfHeadersAt != -1) {
        server.decoder = decodeHeadersOnly;
        connectionRef.ref = null;
        final int endOfHeaderLinesAt = endOfHeadersAt - CRLF_BYTES.length;
        int startOfLineAt = endOfStartAt;
        for (int endOfLineAt = limitOfBytes(buffer, startOfLineAt, endOfHeaderLinesAt, CRLF_BYTES); endOfLineAt != -1 && error == null; startOfLineAt = endOfLineAt, endOfLineAt = limitOfBytes(buffer, startOfLineAt, endOfHeaderLinesAt, CRLF_BYTES)) {
            error = decodeHeaderLine(server, buffer, offset, startOfLineAt, endOfLineAt, httpBeginEx, hasAuthority, connectionRef);
        }
        if (error == null && !hasAuthority.value) {
            error = ERROR_400_BAD_REQUEST;
        }
        if (error == null) {
            HttpBeginExFW beginEx = httpBeginEx.build();
            final Map<String, String> headers = new LinkedHashMap<>();
            beginEx.headers().forEach(h -> headers.put(h.name().asString().toLowerCase(), h.value().asString()));
            if (isCorsPreflightRequest(headers)) {
                server.onDecodeCorsPreflight(traceId, authorization, headers);
                server.decoder = decodeEmptyLines;
            } else if (!isCorsRequestAllowed(server.binding, headers)) {
                server.onDecodeHeadersError(traceId, authorization, response403);
                server.decoder = decodeIgnore;
            } else {
                HttpBindingConfig binding = server.binding;
                HttpRouteConfig route = binding.resolve(authorization, headers::get);
                if (route != null) {
                    if (binding.options != null && binding.options.overrides != null) {
                        binding.options.overrides.forEach((k, v) -> headers.put(k.asString(), v.asString()));
                        final HttpBeginExFW.Builder newBeginEx = newBeginExRW.wrap(codecBuffer, 0, codecBuffer.capacity()).typeId(httpTypeId);
                        headers.forEach((k, v) -> newBeginEx.headersItem(i -> i.name(k).value(v)));
                        beginEx = newBeginEx.build();
                    }
                    HttpPolicyConfig policy = binding.access().effectivePolicy(headers);
                    final String origin = policy == CROSS_ORIGIN ? headers.get(HEADER_NAME_ORIGIN) : null;
                    server.onDecodeHeaders(route.id, traceId, authorization, policy, origin, beginEx);
                } else {
                    error = ERROR_404_NOT_FOUND;
                }
            }
        }
    } else if (error == null && limit - offset >= maximumHeadersSize) {
        error = ERROR_414_REQUEST_URI_TOO_LONG;
    }
    if (error != null) {
        server.onDecodeHeadersError(traceId, authorization, error);
        server.decoder = decodeIgnore;
    }
    return error == null && endOfHeadersAt != -1 ? endOfHeadersAt : offset;
}
Also used : HttpPolicyConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpAccessControlConfig.HttpPolicyConfig) NO_DEBITOR_INDEX(io.aklivity.zilla.runtime.engine.budget.BudgetDebitor.NO_DEBITOR_INDEX) HpackHeaderFieldFW(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackHeaderFieldFW) HpackStringFW(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackStringFW) LongSupplier(java.util.function.LongSupplier) BindingHandler(io.aklivity.zilla.runtime.engine.binding.BindingHandler) MessageConsumer(io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer) UnsafeBuffer(org.agrona.concurrent.UnsafeBuffer) INCREMENTAL_INDEXING(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackLiteralHeaderFieldFW.LiteralType.INCREMENTAL_INDEXING) Http2SettingsFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2SettingsFW) Matcher(java.util.regex.Matcher) Arrays.asList(java.util.Arrays.asList) HttpBinding(io.aklivity.zilla.runtime.binding.http.internal.HttpBinding) Http2ErrorCode(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2ErrorCode) Map(java.util.Map) Http2PingFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PingFW) Array32FW(io.aklivity.zilla.runtime.binding.http.internal.types.Array32FW) UNKNOWN(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackHeaderFieldFW.HeaderFieldType.UNKNOWN) ProxyInfoFW(io.aklivity.zilla.runtime.binding.http.internal.types.ProxyInfoFW) WindowFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.WindowFW) EngineContext(io.aklivity.zilla.runtime.engine.EngineContext) BufferPool(io.aklivity.zilla.runtime.engine.buffer.BufferPool) EnumMap(java.util.EnumMap) PROXY_CONNECTION(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext.PROXY_CONNECTION) Http2DataFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2DataFW) Set(java.util.Set) Signaler(io.aklivity.zilla.runtime.engine.concurrent.Signaler) EndFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.EndFW) BindingConfig(io.aklivity.zilla.runtime.engine.config.BindingConfig) BufferUtil.limitOfBytes(io.aklivity.zilla.runtime.binding.http.internal.util.BufferUtil.limitOfBytes) CONNECTION(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext.CONNECTION) Http2ContinuationFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2ContinuationFW) AsciiSequenceView(org.agrona.AsciiSequenceView) HttpDataExFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpDataExFW) LongLongConsumer(org.agrona.collections.LongLongConsumer) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Long2ObjectHashMap(org.agrona.collections.Long2ObjectHashMap) MutableReference(org.agrona.collections.MutableReference) BiConsumer(java.util.function.BiConsumer) MutableInteger(org.agrona.collections.MutableInteger) MutableBoolean(org.agrona.collections.MutableBoolean) VERSION(io.aklivity.zilla.runtime.binding.http.internal.types.ProxySecureInfoType.VERSION) HttpEndExFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpEndExFW) String16FW(io.aklivity.zilla.runtime.binding.http.internal.types.String16FW) KEEP_ALIVE(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext.KEEP_ALIVE) UPGRADE(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext.UPGRADE) ALPN(io.aklivity.zilla.runtime.binding.http.internal.types.ProxyInfoType.ALPN) HpackHuffman(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackHuffman) LongUnaryOperator(java.util.function.LongUnaryOperator) Http2PriorityFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PriorityFW) AtomicBuffer(org.agrona.concurrent.AtomicBuffer) BufferUtil.indexOfByte(io.aklivity.zilla.runtime.binding.http.internal.util.BufferUtil.indexOfByte) Http2PushPromiseFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PushPromiseFW) SortedSet(java.util.SortedSet) Http2Setting(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2Setting) BudgetCreditor(io.aklivity.zilla.runtime.engine.budget.BudgetCreditor) WITHOUT_INDEXING(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackLiteralHeaderFieldFW.LiteralType.WITHOUT_INDEXING) SECURE(io.aklivity.zilla.runtime.binding.http.internal.types.ProxyInfoType.SECURE) LongHashSet(org.agrona.collections.LongHashSet) OctetsFW(io.aklivity.zilla.runtime.binding.http.internal.types.OctetsFW) Flyweight(io.aklivity.zilla.runtime.binding.http.internal.types.Flyweight) URI(java.net.URI) Http2WindowUpdateFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2WindowUpdateFW) HttpBindingConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpBindingConfig) HttpRouteConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpRouteConfig) TRAILERS(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext.TRAILERS) Http2FrameType(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2FrameType) Int2ObjectHashMap(org.agrona.collections.Int2ObjectHashMap) SignalFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.SignalFW) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) Instant(java.time.Instant) Objects(java.util.Objects) FlushFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.FlushFW) List(java.util.List) HttpBeginExFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpBeginExFW) HpackContext(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext) MutableDirectBuffer(org.agrona.MutableDirectBuffer) Pattern(java.util.regex.Pattern) DirectBuffer(org.agrona.DirectBuffer) HttpConfiguration(io.aklivity.zilla.runtime.binding.http.internal.HttpConfiguration) Http2PrefaceFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PrefaceFW) HashMap(java.util.HashMap) BeginFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.BeginFW) HpackHeaderBlockFW(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackHeaderBlockFW) HttpAccessControlConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpAccessControlConfig) HashSet(java.util.HashSet) DataFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.DataFW) HttpUtil(io.aklivity.zilla.runtime.binding.http.internal.util.HttpUtil) Http2GoawayFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2GoawayFW) HpackLiteralHeaderFieldFW(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackLiteralHeaderFieldFW) TE(io.aklivity.zilla.runtime.binding.http.internal.hpack.HpackContext.TE) String8FW(io.aklivity.zilla.runtime.binding.http.internal.types.String8FW) ProxyBeginExFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.ProxyBeginExFW) NO_CREDITOR_INDEX(io.aklivity.zilla.runtime.engine.budget.BudgetCreditor.NO_CREDITOR_INDEX) Character.toUpperCase(java.lang.Character.toUpperCase) Http2HeadersFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2HeadersFW) Iterator(java.util.Iterator) LongFunction(java.util.function.LongFunction) Http2FrameInfoFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2FrameInfoFW) HttpVersion(io.aklivity.zilla.runtime.binding.http.internal.config.HttpVersion) UTF_8(java.nio.charset.StandardCharsets.UTF_8) AbortFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.AbortFW) HttpHeaderFW(io.aklivity.zilla.runtime.binding.http.internal.types.HttpHeaderFW) BudgetDebitor(io.aklivity.zilla.runtime.engine.budget.BudgetDebitor) Integer.parseInt(java.lang.Integer.parseInt) US_ASCII(java.nio.charset.StandardCharsets.US_ASCII) Consumer(java.util.function.Consumer) Http2RstStreamFW(io.aklivity.zilla.runtime.binding.http.internal.codec.Http2RstStreamFW) NO_SLOT(io.aklivity.zilla.runtime.engine.buffer.BufferPool.NO_SLOT) ResetFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.ResetFW) CROSS_ORIGIN(io.aklivity.zilla.runtime.binding.http.internal.config.HttpAccessControlConfig.HttpPolicyConfig.CROSS_ORIGIN) Character.toLowerCase(java.lang.Character.toLowerCase) HttpRouteConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpRouteConfig) LinkedHashMap(java.util.LinkedHashMap) MutableDirectBuffer(org.agrona.MutableDirectBuffer) DirectBuffer(org.agrona.DirectBuffer) HttpBeginExFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpBeginExFW) HttpPolicyConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpAccessControlConfig.HttpPolicyConfig) HttpBindingConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpBindingConfig) AsciiSequenceView(org.agrona.AsciiSequenceView)

Example 2 with HttpBeginExFW

use of io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpBeginExFW in project zilla by aklivity.

the class HttpClientFactory method newStream.

@Override
public MessageConsumer newStream(int msgTypeId, DirectBuffer buffer, int index, int length, MessageConsumer application) {
    final BeginFW begin = beginRO.wrap(buffer, index, index + length);
    final long routeId = begin.routeId();
    final long authorization = begin.authorization();
    final HttpBeginExFW beginEx = begin.extension().get(beginExRO::tryWrap);
    final HttpBindingConfig binding = bindings.get(routeId);
    HttpRouteConfig route = null;
    if (binding != null) {
        // TODO: avoid object creation
        final Map<String, String> headers = beginEx != null ? asHeadersMap(beginEx.headers()) : EMPTY_HEADERS;
        route = binding.resolve(authorization, headers::get);
    }
    MessageConsumer newStream = null;
    if (route != null) {
        final long resolvedId = route.id;
        final Map<String8FW, String16FW> overrides = binding.options != null && binding.options.overrides != null ? binding.options.overrides : EMPTY_OVERRIDES;
        final HttpClientPool clientPool = clientPools.computeIfAbsent(resolvedId, HttpClientPool::new);
        newStream = clientPool.newStream(application, begin, overrides);
    }
    return newStream;
}
Also used : MessageConsumer(io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer) BeginFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.BeginFW) HttpRouteConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpRouteConfig) HttpBeginExFW(io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpBeginExFW) String8FW(io.aklivity.zilla.runtime.binding.http.internal.types.String8FW) HttpBindingConfig(io.aklivity.zilla.runtime.binding.http.internal.config.HttpBindingConfig) String16FW(io.aklivity.zilla.runtime.binding.http.internal.types.String16FW)

Aggregations

HttpBindingConfig (io.aklivity.zilla.runtime.binding.http.internal.config.HttpBindingConfig)2 HttpRouteConfig (io.aklivity.zilla.runtime.binding.http.internal.config.HttpRouteConfig)2 String16FW (io.aklivity.zilla.runtime.binding.http.internal.types.String16FW)2 String8FW (io.aklivity.zilla.runtime.binding.http.internal.types.String8FW)2 BeginFW (io.aklivity.zilla.runtime.binding.http.internal.types.stream.BeginFW)2 HttpBeginExFW (io.aklivity.zilla.runtime.binding.http.internal.types.stream.HttpBeginExFW)2 MessageConsumer (io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer)2 HttpBinding (io.aklivity.zilla.runtime.binding.http.internal.HttpBinding)1 HttpConfiguration (io.aklivity.zilla.runtime.binding.http.internal.HttpConfiguration)1 Http2ContinuationFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2ContinuationFW)1 Http2DataFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2DataFW)1 Http2ErrorCode (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2ErrorCode)1 Http2FrameInfoFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2FrameInfoFW)1 Http2FrameType (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2FrameType)1 Http2GoawayFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2GoawayFW)1 Http2HeadersFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2HeadersFW)1 Http2PingFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PingFW)1 Http2PrefaceFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PrefaceFW)1 Http2PriorityFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PriorityFW)1 Http2PushPromiseFW (io.aklivity.zilla.runtime.binding.http.internal.codec.Http2PushPromiseFW)1