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;
}
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;
}
Aggregations