All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.helidon.webserver.http2.Http2ServerRequest Maven / Gradle / Ivy
/*
* Copyright (c) 2022, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.webserver.http2;
import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import io.helidon.common.LazyValue;
import io.helidon.common.buffers.BufferData;
import io.helidon.common.context.Context;
import io.helidon.common.context.Contexts;
import io.helidon.common.socket.PeerInfo;
import io.helidon.common.uri.UriInfo;
import io.helidon.common.uri.UriQuery;
import io.helidon.http.Header;
import io.helidon.http.HttpPrologue;
import io.helidon.http.RequestedUriDiscoveryContext;
import io.helidon.http.RoutedPath;
import io.helidon.http.ServerRequestHeaders;
import io.helidon.http.WritableHeaders;
import io.helidon.http.encoding.ContentDecoder;
import io.helidon.http.http2.Http2Headers;
import io.helidon.http.media.ReadableEntity;
import io.helidon.webserver.ConnectionContext;
import io.helidon.webserver.ListenerContext;
import io.helidon.webserver.ProxyProtocolData;
import io.helidon.webserver.http.HttpSecurity;
import io.helidon.webserver.http.RoutingRequest;
/**
* HTTP/2 server request.
*/
class Http2ServerRequest implements RoutingRequest {
private static final RequestedUriDiscoveryContext DEFAULT_REQUESTED_URI_DISCOVERY_CONTEXT =
RequestedUriDiscoveryContext.builder()
.build();
private static final Runnable NO_OP_RUNNABLE = () -> {
};
private final Http2Headers http2Headers;
private final ServerRequestHeaders headers;
private final ConnectionContext ctx;
private final HttpPrologue originalPrologue;
private final int requestId;
private final String authority;
private final LazyValue entity;
private final HttpSecurity security;
private final LazyValue uriInfo = LazyValue.create(this::createUriInfo);
private HttpPrologue prologue;
private RoutedPath path;
private WritableHeaders> writable;
private Context context;
// preparation for continue support in HTTP/2
private boolean continueSent;
private UnaryOperator streamFilter = UnaryOperator.identity();
Http2ServerRequest(ConnectionContext ctx,
HttpSecurity security,
HttpPrologue prologue,
Http2Headers headers,
ContentDecoder decoder,
int requestId,
Supplier entitySupplier) {
this.ctx = ctx;
this.security = security;
this.originalPrologue = prologue;
this.http2Headers = headers;
this.headers = ServerRequestHeaders.create(headers.httpHeaders());
this.requestId = requestId;
this.authority = headers.authority();
this.entity = LazyValue.create(() -> Http2ServerRequestEntity.create(streamFilter,
decoder,
it -> entitySupplier.get(),
NO_OP_RUNNABLE,
this.headers,
ctx.listenerContext().mediaContext()));
}
static Http2ServerRequest create(ConnectionContext ctx,
HttpSecurity security,
HttpPrologue httpPrologue,
Http2Headers headers,
ContentDecoder decoder,
int streamId,
Supplier entitySupplier) {
return new Http2ServerRequest(ctx, security, httpPrologue, headers, decoder, streamId, entitySupplier);
}
@Override
public void reset() {
}
@Override
public boolean isSecure() {
return ctx.isSecure();
}
@Override
public RoutedPath path() {
return path;
}
@Override
public ReadableEntity content() {
return entity.get();
}
@Override
public String socketId() {
return ctx.childSocketId();
}
@Override
public String serverSocketId() {
return ctx.socketId();
}
@Override
public HttpPrologue prologue() {
return prologue == null ? originalPrologue : prologue;
}
@Override
public ServerRequestHeaders headers() {
return headers;
}
@Override
public UriQuery query() {
return prologue().query();
}
@Override
public PeerInfo remotePeer() {
return ctx.remotePeer();
}
@Override
public PeerInfo localPeer() {
return ctx.localPeer();
}
@Override
public String authority() {
return authority;
}
@Override
public void header(Header header) {
if (writable == null) {
writable = WritableHeaders.create(headers);
}
writable.set(header);
}
@Override
public int id() {
return requestId;
}
@Override
public Http2ServerRequest path(RoutedPath routedPath) {
this.path = routedPath;
return this;
}
@Override
public RoutingRequest prologue(HttpPrologue newPrologue) {
this.prologue = newPrologue;
return this;
}
@Override
public ListenerContext listenerContext() {
return ctx.listenerContext();
}
@Override
public Context context() {
if (context == null) {
context = Contexts.context().orElseGet(() -> Context.builder()
.parent(ctx.listenerContext().context())
.id("[" + serverSocketId() + " " + socketId() + "] http/1.1: " + requestId)
.build());
}
return context;
}
@Override
public HttpSecurity security() {
return security;
}
@Override
public UriInfo requestedUri() {
return uriInfo.get();
}
@Override
public boolean continueSent() {
return continueSent;
}
@Override
public void streamFilter(UnaryOperator filterFunction) {
Objects.requireNonNull(filterFunction);
UnaryOperator current = this.streamFilter;
this.streamFilter = it -> filterFunction.apply(current.apply(it));
}
@Override
public Optional proxyProtocolData() {
return ctx.proxyProtocolData();
}
private UriInfo createUriInfo() {
return ctx.listenerContext().config().requestedUriDiscoveryContext()
.orElse(DEFAULT_REQUESTED_URI_DISCOVERY_CONTEXT)
.uriInfo(remotePeer().address().toString(),
localPeer().address().toString(),
path.absolute().path(),
headers,
query(),
isSecure());
}
}