Skip to content

Commit

Permalink
Optimize NettyHttpRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
dstepanov committed Nov 30, 2023
1 parent 5d6277c commit 40d65e8
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
* @since 1.0
*/
@Internal
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public abstract class AbstractNettyHttpRequest<B> extends DefaultAttributeMap implements HttpRequest<B>, NettyHttpRequestBuilder {

protected final io.netty.handler.codec.http.HttpRequest nettyRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ record HttpToHttpsRedirectHandler(

@Override
public void accept(ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpRequest request, PipeliningServerHandler.OutboundAccess outboundAccess) {
NettyHttpRequest<?> strippedRequest = NettyHttpRequest.createSafe(request, ctx, conversionService, serverConfiguration);
NettyHttpRequest<?> strippedRequest = new NettyHttpRequest<>(request, ctx, conversionService, serverConfiguration);

UriBuilder uriBuilder = UriBuilder.of(hostResolver.resolve(strippedRequest));
strippedRequest.release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
import io.micronaut.http.server.netty.body.ImmediateByteBody;
import io.micronaut.http.server.netty.body.ImmediateMultiObjectBody;
import io.micronaut.http.server.netty.body.ImmediateSingleObjectBody;
import io.micronaut.http.server.netty.configuration.NettyHttpServerConfiguration;
import io.micronaut.http.server.netty.multipart.NettyCompletedFileUpload;
import io.micronaut.web.router.RouteMatch;
import io.netty.buffer.ByteBuf;
Expand Down Expand Up @@ -96,6 +95,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.function.Supplier;

/**
Expand All @@ -106,6 +106,7 @@
* @since 1.0
*/
@Internal
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public class NettyHttpRequest<T> extends AbstractNettyHttpRequest<T> implements HttpRequest<T>, PushCapableHttpRequest<T>, io.micronaut.http.FullHttpRequest<T> {
private static final Logger LOG = LoggerFactory.getLogger(NettyHttpRequest.class);

Expand Down Expand Up @@ -163,16 +164,12 @@ public class NettyHttpRequest<T> extends AbstractNettyHttpRequest<T> implements
private FormRouteCompleter formRouteCompleter;
private ExecutionFlow<?> routeWaitsFor = ExecutionFlow.just(null);

/**
* Set to {@code true} when the {@link #headers} may have been mutated. If this is not the case,
* we can cache some values.
*/
private boolean headersMutated = false;
private final long contentLength;
@Nullable
private final MediaType contentType;
private OptionalLong contentLength;
@Nullable
private Optional<MediaType> contentType;
@Nullable
private final String origin;
private Optional<String> origin;

private final BodyConvertor bodyConvertor = newBodyConvertor();

Expand Down Expand Up @@ -200,34 +197,6 @@ public NettyHttpRequest(io.netty.handler.codec.http.HttpRequest nettyRequest,
this.channelHandlerContext = ctx;
this.headers = new NettyHttpHeaders(nettyRequest.headers(), conversionService);
this.body = ByteBody.of(nettyRequest);
this.contentLength = headers.contentLength().orElse(-1);
this.contentType = headers.contentType().orElse(null);
this.origin = headers.getOrigin().orElse(null);
}

public static NettyHttpRequest<?> createSafe(io.netty.handler.codec.http.HttpRequest request, ChannelHandlerContext ctx, ConversionService conversionService, NettyHttpServerConfiguration serverConfiguration) {
try {
return new NettyHttpRequest<>(
request,
ctx,
conversionService,
serverConfiguration
);
} catch (IllegalArgumentException iae) {
// invalid URI
if (request instanceof StreamedHttpRequest streamed) {
streamed.closeIfNoSubscriber();
} else {
((FullHttpRequest) request).release();
}

return new NettyHttpRequest<>(
new DefaultFullHttpRequest(request.protocolVersion(), request.method(), "/", Unpooled.EMPTY_BUFFER),
ctx,
conversionService,
serverConfiguration
);
}
}

/**
Expand Down Expand Up @@ -388,11 +357,12 @@ public boolean isSecure() {

@Override
public Optional<String> getOrigin() {
if (headersMutated) {
return getHeaders().getOrigin();
} else {
return Optional.ofNullable(origin);
Optional<String> cachedOrigin = origin;
if (cachedOrigin == null) {
cachedOrigin = headers.getOrigin();
origin = cachedOrigin;
}
return cachedOrigin;
}

@Override
Expand Down Expand Up @@ -663,12 +633,12 @@ public io.netty.handler.codec.http.HttpRequest toHttpRequestWithoutBody() {

@Override
public Optional<MediaType> getContentType() {
// this is better than the caching we can do in AbstractNettyHttpRequest
if (headersMutated) {
return headers.contentType();
} else {
return Optional.ofNullable(contentType);
Optional<MediaType> cachedContentType = contentType;
if (cachedContentType == null) {
cachedContentType = headers.contentType();
contentType = cachedContentType;
}
return cachedContentType;
}

/**
Expand Down Expand Up @@ -703,11 +673,12 @@ public Optional convert(ArgumentConversionContext conversionContext, Object valu

@Override
public long getContentLength() {
if (headersMutated) {
return super.getContentLength();
} else {
return contentLength;
OptionalLong cachedContentLength = contentLength;
if (cachedContentLength == null) {
cachedContentLength = headers.contentLength();
contentLength = cachedContentLength;
}
return cachedContentLength.orElse(-1);
}

@Override
Expand Down Expand Up @@ -778,7 +749,9 @@ public <T1> MutableHttpRequest<T1> body(T1 body) {

@Override
public MutableHttpHeaders getHeaders() {
headersMutated = true;
contentLength = null;
contentType = null;
origin = null;
return headers;
}

Expand Down

0 comments on commit 40d65e8

Please sign in to comment.