-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add fast compiled route matcher #10131
base: 4.3.x
Are you sure you want to change the base?
Changes from 23 commits
66c2acc
85e72d1
411f689
445fd26
8282299
1df33d6
6fd5290
3397bec
68cf3e6
cdd2d3c
8e1319e
fe0f885
84c7293
585cc4e
7ee51c9
82dcfab
ab9e7de
280a35a
971b300
e9eb93d
cd0c252
409c4d9
f3a3849
43c5c25
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,9 +21,11 @@ | |
import io.micronaut.core.convert.ConversionService; | ||
import io.micronaut.core.convert.value.ConvertibleValues; | ||
import io.micronaut.core.execution.ExecutionFlow; | ||
import io.micronaut.core.type.Argument; | ||
import io.micronaut.http.HttpAttributes; | ||
import io.micronaut.http.HttpRequest; | ||
import io.micronaut.http.MediaType; | ||
import io.micronaut.http.annotation.Body; | ||
import io.micronaut.http.bind.binders.DefaultBodyAnnotationBinder; | ||
import io.micronaut.http.bind.binders.PendingRequestBindingResult; | ||
import io.micronaut.http.body.MessageBodyHandlerRegistry; | ||
|
@@ -34,12 +36,14 @@ | |
import io.micronaut.http.server.netty.FormDataHttpContentProcessor; | ||
import io.micronaut.http.server.netty.NettyHttpRequest; | ||
import io.micronaut.http.server.netty.body.ImmediateByteBody; | ||
import io.micronaut.http.server.netty.shortcircuit.ShortCircuitArgumentBinder; | ||
import io.micronaut.web.router.RouteInfo; | ||
import io.micronaut.web.router.shortcircuit.MatchRule; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
final class NettyBodyAnnotationBinder<T> extends DefaultBodyAnnotationBinder<T> { | ||
final class NettyBodyAnnotationBinder<T> extends DefaultBodyAnnotationBinder<T> implements ShortCircuitArgumentBinder<T> { | ||
private static final CharSequence ATTR_CONVERTIBLE_BODY = "NettyBodyAnnotationBinder.convertibleBody"; | ||
|
||
final HttpServerConfiguration httpServerConfiguration; | ||
|
@@ -167,4 +171,38 @@ Optional<T> transform(NettyHttpRequest<?> nhr, ArgumentConversionContext<T> cont | |
.convert(conversionService, context) | ||
.map(o -> (T) o.claimForExternal()); | ||
} | ||
|
||
@Override | ||
public Optional<Prepared> prepare(Argument<T> argument, MatchRule.ContentType fixedContentType) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this is going to be an internal non-public API do we need the overhead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. either is fine but this is not a hot path. this is called once per route, so i think it's better to have a nicer api here than to overoptimize this. |
||
boolean hasBodyAnnotation = argument.getAnnotationMetadata().hasAnnotation(Body.class); | ||
Optional<String> optionalBodyComponent = argument.getAnnotationMetadata().stringValue(Body.class); | ||
if (!hasBodyAnnotation || optionalBodyComponent.isPresent()) { | ||
// only full body binding implemented | ||
return Optional.empty(); | ||
} | ||
boolean raw = DefaultHttpContentProcessorResolver.isRaw(argument); | ||
MessageBodyReader<T> reader; | ||
if (raw) { | ||
reader = null; | ||
} else { | ||
if (fixedContentType == null) { | ||
return Optional.empty(); | ||
} | ||
Optional<MessageBodyReader<T>> opt = bodyHandlerRegistry.findReader(argument, fixedContentType.expectedType() == null ? null : List.of(fixedContentType.expectedType())); | ||
if (opt.isEmpty()) { | ||
return Optional.empty(); | ||
} | ||
reader = opt.get(); | ||
} | ||
return Optional.of((mnHeaders, body) -> { | ||
if (body.empty()) { | ||
return null; | ||
} | ||
if (raw) { | ||
return body.rawContent(httpServerConfiguration).convert(conversionService, ConversionContext.of(argument)).orElse(null); | ||
} else { | ||
return body.processSingle(httpServerConfiguration, reader, argument, fixedContentType.expectedType(), mnHeaders).claimForExternal(); | ||
} | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this? Filters can now be filtered by request, eliminating the CORS filter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will profile