Search in sources :

Example 1 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class RouteExecutor method onError.

/**
 * Creates a response publisher to represent the response after being handled
 * by any available error route or exception handler.
 *
 * @param t           The exception that occurred
 * @param httpRequest The request that caused the exception
 * @return A response publisher
 */
public Flux<MutableHttpResponse<?>> onError(Throwable t, HttpRequest<?> httpRequest) {
    // find the origination of of the route
    Class declaringType = httpRequest.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).map(RouteInfo::getDeclaringType).orElse(null);
    final Throwable cause;
    // top level exceptions returned by CompletableFutures. These always wrap the real exception thrown.
    if ((t instanceof CompletionException || t instanceof ExecutionException) && t.getCause() != null) {
        cause = t.getCause();
    } else {
        cause = t;
    }
    RouteMatch<?> errorRoute = findErrorRoute(cause, declaringType, httpRequest);
    if (errorRoute != null) {
        if (serverConfiguration.isLogHandledExceptions()) {
            logException(cause);
        }
        try {
            AtomicReference<HttpRequest<?>> requestReference = new AtomicReference<>(httpRequest);
            return buildRouteResponsePublisher(requestReference, Flux.just(errorRoute)).doOnNext(response -> response.setAttribute(HttpAttributes.EXCEPTION, cause)).onErrorResume(throwable -> createDefaultErrorResponsePublisher(requestReference.get(), throwable));
        } catch (Throwable e) {
            return createDefaultErrorResponsePublisher(httpRequest, e).flux();
        }
    } else {
        Optional<BeanDefinition<ExceptionHandler>> optionalDefinition = beanContext.findBeanDefinition(ExceptionHandler.class, Qualifiers.byTypeArgumentsClosest(cause.getClass(), Object.class));
        if (optionalDefinition.isPresent()) {
            BeanDefinition<ExceptionHandler> handlerDefinition = optionalDefinition.get();
            final Optional<ExecutableMethod<ExceptionHandler, Object>> optionalMethod = handlerDefinition.findPossibleMethods("handle").findFirst();
            RouteInfo<Object> routeInfo;
            if (optionalMethod.isPresent()) {
                routeInfo = new ExecutableRouteInfo(optionalMethod.get(), true);
            } else {
                routeInfo = new RouteInfo<Object>() {

                    @Override
                    public ReturnType<?> getReturnType() {
                        return ReturnType.of(Object.class);
                    }

                    @Override
                    public Class<?> getDeclaringType() {
                        return handlerDefinition.getBeanType();
                    }

                    @Override
                    public boolean isErrorRoute() {
                        return true;
                    }

                    @Override
                    public List<MediaType> getProduces() {
                        return MediaType.fromType(getDeclaringType()).map(Collections::singletonList).orElse(Collections.emptyList());
                    }
                };
            }
            Flux<MutableHttpResponse<?>> reactiveSequence = Flux.defer(() -> {
                ExceptionHandler handler = beanContext.getBean(handlerDefinition);
                try {
                    if (serverConfiguration.isLogHandledExceptions()) {
                        logException(cause);
                    }
                    Object result = handler.handle(httpRequest, cause);
                    return createResponseForBody(httpRequest, result, routeInfo);
                } catch (Throwable e) {
                    return createDefaultErrorResponsePublisher(httpRequest, e);
                }
            });
            final ExecutorService executor = findExecutor(routeInfo);
            if (executor != null) {
                reactiveSequence = applyExecutorToPublisher(reactiveSequence, executor);
            }
            return reactiveSequence.doOnNext(response -> response.setAttribute(HttpAttributes.EXCEPTION, cause)).onErrorResume(throwable -> createDefaultErrorResponsePublisher(httpRequest, throwable));
        } else {
            if (isIgnorable(cause)) {
                logIgnoredException(cause);
                return Flux.empty();
            } else {
                return createDefaultErrorResponsePublisher(httpRequest, cause).flux();
            }
        }
    }
}
Also used : Publishers(io.micronaut.core.async.publisher.Publishers) ServerFilterChain(io.micronaut.http.filter.ServerFilterChain) BeanContext(io.micronaut.context.BeanContext) KotlinExecutableMethodUtils.isKotlinFunctionReturnTypeUnit(io.micronaut.inject.util.KotlinExecutableMethodUtils.isKotlinFunctionReturnTypeUnit) LoggerFactory(org.slf4j.LoggerFactory) HttpHeaders(io.micronaut.http.HttpHeaders) Internal(io.micronaut.core.annotation.Internal) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HttpStatus(io.micronaut.http.HttpStatus) MediaType(io.micronaut.http.MediaType) ReferenceCounted(io.micronaut.core.io.buffer.ReferenceCounted) HttpResponse(io.micronaut.http.HttpResponse) MethodReference(io.micronaut.inject.MethodReference) MethodBasedRouteMatch(io.micronaut.web.router.MethodBasedRouteMatch) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Qualifiers(io.micronaut.inject.qualifiers.Qualifiers) Singleton(jakarta.inject.Singleton) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) CompletionException(java.util.concurrent.CompletionException) HttpFilter(io.micronaut.http.filter.HttpFilter) RequestArgumentSatisfier(io.micronaut.http.server.binding.RequestArgumentSatisfier) List(java.util.List) RouteInfo(io.micronaut.web.router.RouteInfo) BeanCreationException(io.micronaut.context.exceptions.BeanCreationException) Optional(java.util.Optional) HttpAttributes(io.micronaut.http.HttpAttributes) Pattern(java.util.regex.Pattern) RouteMatch(io.micronaut.web.router.RouteMatch) UnsatisfiedRouteException(io.micronaut.web.router.exceptions.UnsatisfiedRouteException) LocalDateTime(java.time.LocalDateTime) CompletableFuture(java.util.concurrent.CompletableFuture) Scheduler(reactor.core.scheduler.Scheduler) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ExceptionHandler(io.micronaut.http.server.exceptions.ExceptionHandler) ExecutableMethod(io.micronaut.inject.ExecutableMethod) ArrayList(java.util.ArrayList) ErrorContext(io.micronaut.http.server.exceptions.response.ErrorContext) Nullable(io.micronaut.core.annotation.Nullable) ReturnType(io.micronaut.core.type.ReturnType) Schedulers(reactor.core.scheduler.Schedulers) Argument(io.micronaut.core.type.Argument) HttpRequest(io.micronaut.http.HttpRequest) ServerRequestContext(io.micronaut.http.context.ServerRequestContext) ErrorResponseProcessor(io.micronaut.http.server.exceptions.response.ErrorResponseProcessor) ExecutorService(java.util.concurrent.ExecutorService) HttpStatusException(io.micronaut.http.exceptions.HttpStatusException) HttpMethod(io.micronaut.http.HttpMethod) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) ExecutorSelector(io.micronaut.scheduling.executor.ExecutorSelector) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) IOException(java.io.IOException) BeanType(io.micronaut.inject.BeanType) ExecutionException(java.util.concurrent.ExecutionException) NonNull(io.micronaut.core.annotation.NonNull) Flux(reactor.core.publisher.Flux) ContinuationArgumentBinder(io.micronaut.http.bind.binders.ContinuationArgumentBinder) KotlinUtils.isKotlinCoroutineSuspended(io.micronaut.core.util.KotlinUtils.isKotlinCoroutineSuspended) BeanDefinition(io.micronaut.inject.BeanDefinition) Router(io.micronaut.web.router.Router) Collections(java.util.Collections) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) ExecutableMethod(io.micronaut.inject.ExecutableMethod) BeanDefinition(io.micronaut.inject.BeanDefinition) ExceptionHandler(io.micronaut.http.server.exceptions.ExceptionHandler) List(java.util.List) ArrayList(java.util.ArrayList) ExecutionException(java.util.concurrent.ExecutionException) Collections(java.util.Collections) HttpRequest(io.micronaut.http.HttpRequest) AtomicReference(java.util.concurrent.atomic.AtomicReference) ReturnType(io.micronaut.core.type.ReturnType) CompletionException(java.util.concurrent.CompletionException) ExecutorService(java.util.concurrent.ExecutorService)

Example 2 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class JsonViewServerFilter method doFilter.

@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
    final RouteInfo<?> routeInfo = request.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).orElse(null);
    final Publisher<MutableHttpResponse<?>> responsePublisher = chain.proceed(request);
    if (routeInfo != null) {
        final Optional<Class<?>> viewClass = routeInfo.findAnnotation(JsonView.class).flatMap(AnnotationValue::classValue);
        if (viewClass.isPresent()) {
            return Flux.from(responsePublisher).switchMap(response -> {
                final Optional<?> optionalBody = response.getBody();
                if (optionalBody.isPresent()) {
                    Object body = optionalBody.get();
                    MediaTypeCodec codec = codecFactory.resolveJsonViewCodec(viewClass.get());
                    if (Publishers.isConvertibleToPublisher(body)) {
                        Publisher<?> pub = Publishers.convertPublisher(body, Publisher.class);
                        response.body(Flux.from(pub).map(o -> codec.encode((Argument) routeInfo.getBodyType(), o)).subscribeOn(Schedulers.fromExecutorService(executorService)));
                    } else {
                        return Mono.fromCallable(() -> {
                            @SuppressWarnings({ "unchecked", "rawtypes" }) final byte[] encoded = codec.encode((Argument) routeInfo.getBodyType(), body);
                            response.body(encoded);
                            return response;
                        }).subscribeOn(Schedulers.fromExecutorService(executorService));
                    }
                }
                return Flux.just(response);
            });
        }
    }
    return responsePublisher;
}
Also used : MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Argument(io.micronaut.core.type.Argument) JsonView(com.fasterxml.jackson.annotation.JsonView) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) RouteInfo(io.micronaut.web.router.RouteInfo) MediaTypeCodec(io.micronaut.http.codec.MediaTypeCodec)

Example 3 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class RouteExecutor method createResponseForBody.

private Flux<MutableHttpResponse<?>> createResponseForBody(HttpRequest<?> request, Object body, RouteInfo<?> routeInfo) {
    return Flux.<MutableHttpResponse<?>>defer(() -> {
        Mono<MutableHttpResponse<?>> outgoingResponse;
        if (body == null) {
            if (routeInfo.isVoid()) {
                MutableHttpResponse<Object> data = forStatus(routeInfo);
                if (HttpMethod.permitsRequestBody(request.getMethod())) {
                    data.header(HttpHeaders.CONTENT_LENGTH, "0");
                }
                outgoingResponse = Mono.just(data);
            } else {
                outgoingResponse = Mono.just(newNotFoundError(request));
            }
        } else {
            HttpStatus defaultHttpStatus = routeInfo.isErrorRoute() ? HttpStatus.INTERNAL_SERVER_ERROR : HttpStatus.OK;
            boolean isReactive = routeInfo.isAsyncOrReactive() || Publishers.isConvertibleToPublisher(body);
            if (isReactive) {
                Class<?> bodyClass = body.getClass();
                boolean isSingle = isSingle(routeInfo, bodyClass);
                boolean isCompletable = !isSingle && routeInfo.isVoid() && Publishers.isCompletable(bodyClass);
                if (isSingle || isCompletable) {
                    // full response case
                    Publisher<Object> publisher = Publishers.convertPublisher(body, Publisher.class);
                    Supplier<MutableHttpResponse<?>> emptyResponse = () -> {
                        MutableHttpResponse<?> singleResponse;
                        if (isCompletable || routeInfo.isVoid()) {
                            singleResponse = forStatus(routeInfo, HttpStatus.OK).header(HttpHeaders.CONTENT_LENGTH, "0");
                        } else {
                            singleResponse = newNotFoundError(request);
                        }
                        return singleResponse;
                    };
                    return Flux.from(publisher).flatMap(o -> {
                        MutableHttpResponse<?> singleResponse;
                        if (o instanceof Optional) {
                            Optional optional = (Optional) o;
                            if (optional.isPresent()) {
                                o = ((Optional<?>) o).get();
                            } else {
                                return Flux.just(emptyResponse.get());
                            }
                        }
                        if (o instanceof HttpResponse) {
                            singleResponse = toMutableResponse((HttpResponse<?>) o);
                            final Argument<?> bodyArgument = // Mono
                            routeInfo.getReturnType().getFirstTypeVariable().orElse(// HttpResponse
                            Argument.OBJECT_ARGUMENT).getFirstTypeVariable().orElse(// Mono
                            Argument.OBJECT_ARGUMENT);
                            if (bodyArgument.isAsyncOrReactive()) {
                                return processPublisherBody(request, singleResponse, routeInfo);
                            }
                        } else if (o instanceof HttpStatus) {
                            singleResponse = forStatus(routeInfo, (HttpStatus) o);
                        } else {
                            singleResponse = forStatus(routeInfo, defaultHttpStatus).body(o);
                        }
                        return Flux.just(singleResponse);
                    }).switchIfEmpty(Mono.fromSupplier(emptyResponse));
                } else {
                    // streaming case
                    Argument<?> typeArgument = routeInfo.getReturnType().getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
                    if (HttpResponse.class.isAssignableFrom(typeArgument.getType())) {
                        // a response stream
                        Publisher<HttpResponse<?>> bodyPublisher = Publishers.convertPublisher(body, Publisher.class);
                        Flux<MutableHttpResponse<?>> response = Flux.from(bodyPublisher).map(this::toMutableResponse);
                        Argument<?> bodyArgument = typeArgument.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
                        if (bodyArgument.isAsyncOrReactive()) {
                            return response.flatMap((resp) -> processPublisherBody(request, resp, routeInfo));
                        }
                        return response;
                    } else {
                        MutableHttpResponse<?> response = forStatus(routeInfo, defaultHttpStatus).body(body);
                        return processPublisherBody(request, response, routeInfo);
                    }
                }
            }
            // now we have the raw result, transform it as necessary
            if (body instanceof HttpStatus) {
                outgoingResponse = Mono.just(HttpResponse.status((HttpStatus) body));
            } else {
                if (routeInfo.isSuspended()) {
                    boolean isKotlinFunctionReturnTypeUnit = routeInfo instanceof MethodBasedRouteMatch && isKotlinFunctionReturnTypeUnit(((MethodBasedRouteMatch) routeInfo).getExecutableMethod());
                    final Supplier<CompletableFuture<?>> supplier = ContinuationArgumentBinder.extractContinuationCompletableFutureSupplier(request);
                    if (isKotlinCoroutineSuspended(body)) {
                        return Mono.fromCompletionStage(supplier).<MutableHttpResponse<?>>flatMap(obj -> {
                            MutableHttpResponse<?> response;
                            if (obj instanceof HttpResponse) {
                                response = toMutableResponse((HttpResponse<?>) obj);
                                final Argument<?> bodyArgument = routeInfo.getReturnType().getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
                                if (bodyArgument.isAsyncOrReactive()) {
                                    return processPublisherBody(request, response, routeInfo);
                                }
                            } else {
                                response = forStatus(routeInfo, defaultHttpStatus);
                                if (!isKotlinFunctionReturnTypeUnit) {
                                    response = response.body(obj);
                                }
                            }
                            return Mono.just(response);
                        }).switchIfEmpty(createNotFoundErrorResponsePublisher(request));
                    } else {
                        Object suspendedBody;
                        if (isKotlinFunctionReturnTypeUnit) {
                            suspendedBody = Mono.empty();
                        } else {
                            suspendedBody = body;
                        }
                        outgoingResponse = toMutableResponse(request, routeInfo, defaultHttpStatus, suspendedBody);
                    }
                } else {
                    outgoingResponse = toMutableResponse(request, routeInfo, defaultHttpStatus, body);
                }
            }
        }
        // for head request we never emit the body
        if (request != null && request.getMethod().equals(HttpMethod.HEAD)) {
            outgoingResponse = outgoingResponse.map(r -> {
                final Object o = r.getBody().orElse(null);
                if (o instanceof ReferenceCounted) {
                    ((ReferenceCounted) o).release();
                }
                r.body(null);
                return r;
            });
        }
        return outgoingResponse;
    }).doOnNext((response) -> {
        applyConfiguredHeaders(response.getHeaders());
        if (routeInfo instanceof RouteMatch) {
            response.setAttribute(HttpAttributes.ROUTE_MATCH, routeInfo);
        }
        response.setAttribute(HttpAttributes.ROUTE_INFO, routeInfo);
    });
}
Also used : Publishers(io.micronaut.core.async.publisher.Publishers) ServerFilterChain(io.micronaut.http.filter.ServerFilterChain) BeanContext(io.micronaut.context.BeanContext) KotlinExecutableMethodUtils.isKotlinFunctionReturnTypeUnit(io.micronaut.inject.util.KotlinExecutableMethodUtils.isKotlinFunctionReturnTypeUnit) LoggerFactory(org.slf4j.LoggerFactory) HttpHeaders(io.micronaut.http.HttpHeaders) Internal(io.micronaut.core.annotation.Internal) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HttpStatus(io.micronaut.http.HttpStatus) MediaType(io.micronaut.http.MediaType) ReferenceCounted(io.micronaut.core.io.buffer.ReferenceCounted) HttpResponse(io.micronaut.http.HttpResponse) MethodReference(io.micronaut.inject.MethodReference) MethodBasedRouteMatch(io.micronaut.web.router.MethodBasedRouteMatch) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Qualifiers(io.micronaut.inject.qualifiers.Qualifiers) Singleton(jakarta.inject.Singleton) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) CompletionException(java.util.concurrent.CompletionException) HttpFilter(io.micronaut.http.filter.HttpFilter) RequestArgumentSatisfier(io.micronaut.http.server.binding.RequestArgumentSatisfier) List(java.util.List) RouteInfo(io.micronaut.web.router.RouteInfo) BeanCreationException(io.micronaut.context.exceptions.BeanCreationException) Optional(java.util.Optional) HttpAttributes(io.micronaut.http.HttpAttributes) Pattern(java.util.regex.Pattern) RouteMatch(io.micronaut.web.router.RouteMatch) UnsatisfiedRouteException(io.micronaut.web.router.exceptions.UnsatisfiedRouteException) LocalDateTime(java.time.LocalDateTime) CompletableFuture(java.util.concurrent.CompletableFuture) Scheduler(reactor.core.scheduler.Scheduler) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ExceptionHandler(io.micronaut.http.server.exceptions.ExceptionHandler) ExecutableMethod(io.micronaut.inject.ExecutableMethod) ArrayList(java.util.ArrayList) ErrorContext(io.micronaut.http.server.exceptions.response.ErrorContext) Nullable(io.micronaut.core.annotation.Nullable) ReturnType(io.micronaut.core.type.ReturnType) Schedulers(reactor.core.scheduler.Schedulers) Argument(io.micronaut.core.type.Argument) HttpRequest(io.micronaut.http.HttpRequest) ServerRequestContext(io.micronaut.http.context.ServerRequestContext) ErrorResponseProcessor(io.micronaut.http.server.exceptions.response.ErrorResponseProcessor) ExecutorService(java.util.concurrent.ExecutorService) HttpStatusException(io.micronaut.http.exceptions.HttpStatusException) HttpMethod(io.micronaut.http.HttpMethod) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) ExecutorSelector(io.micronaut.scheduling.executor.ExecutorSelector) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) IOException(java.io.IOException) BeanType(io.micronaut.inject.BeanType) ExecutionException(java.util.concurrent.ExecutionException) NonNull(io.micronaut.core.annotation.NonNull) Flux(reactor.core.publisher.Flux) ContinuationArgumentBinder(io.micronaut.http.bind.binders.ContinuationArgumentBinder) KotlinUtils.isKotlinCoroutineSuspended(io.micronaut.core.util.KotlinUtils.isKotlinCoroutineSuspended) BeanDefinition(io.micronaut.inject.BeanDefinition) Router(io.micronaut.web.router.Router) Collections(java.util.Collections) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Optional(java.util.Optional) Argument(io.micronaut.core.type.Argument) HttpStatus(io.micronaut.http.HttpStatus) MethodBasedRouteMatch(io.micronaut.web.router.MethodBasedRouteMatch) Mono(reactor.core.publisher.Mono) Flux(reactor.core.publisher.Flux) HttpResponse(io.micronaut.http.HttpResponse) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Publisher(org.reactivestreams.Publisher) MethodBasedRouteMatch(io.micronaut.web.router.MethodBasedRouteMatch) RouteMatch(io.micronaut.web.router.RouteMatch) Supplier(java.util.function.Supplier) ReferenceCounted(io.micronaut.core.io.buffer.ReferenceCounted)

Example 4 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class RouteExecutor method handleStatusException.

private Publisher<MutableHttpResponse<?>> handleStatusException(HttpRequest<?> request, MutableHttpResponse<?> response) {
    HttpStatus status = response.status();
    RouteInfo<?> routeInfo = response.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).orElse(null);
    if (status.getCode() >= 400 && routeInfo != null && !routeInfo.isErrorRoute()) {
        RouteMatch<Object> statusRoute = findStatusRoute(request, status, routeInfo);
        if (statusRoute != null) {
            return executeRoute(request, false, Flux.just(statusRoute));
        }
    }
    return Flux.just(response);
}
Also used : HttpStatus(io.micronaut.http.HttpStatus) RouteInfo(io.micronaut.web.router.RouteInfo)

Example 5 with RouteInfo

use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.

the class RoutingInBoundHandler method encodeHttpResponse.

private void encodeHttpResponse(ChannelHandlerContext context, NettyHttpRequest<?> nettyRequest, MutableHttpResponse<?> response, @Nullable Argument<Object> bodyType, Object body) {
    boolean isNotHead = nettyRequest.getMethod() != HttpMethod.HEAD;
    if (isNotHead) {
        if (body instanceof Writable) {
            getIoExecutor().execute(() -> {
                ByteBuf byteBuf = context.alloc().ioBuffer(128);
                ByteBufOutputStream outputStream = new ByteBufOutputStream(byteBuf);
                try {
                    Writable writable = (Writable) body;
                    writable.writeTo(outputStream, nettyRequest.getCharacterEncoding());
                    response.body(byteBuf);
                    if (!response.getContentType().isPresent()) {
                        response.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).ifPresent((routeInfo) -> response.contentType(routeExecutor.resolveDefaultResponseContentType(nettyRequest, routeInfo)));
                    }
                    writeFinalNettyResponse(response, nettyRequest, context);
                } catch (IOException e) {
                    final MutableHttpResponse<?> errorResponse = routeExecutor.createDefaultErrorResponse(nettyRequest, e);
                    writeFinalNettyResponse(errorResponse, nettyRequest, context);
                }
            });
        } else if (body instanceof Publisher) {
            response.body(null);
            DelegateStreamedHttpResponse streamedResponse = new DelegateStreamedHttpResponse(toNettyResponse(response), mapToHttpContent(nettyRequest, response, body, context));
            nettyRequest.prepareHttp2ResponseIfNecessary(streamedResponse);
            context.writeAndFlush(streamedResponse);
            context.read();
        } else {
            encodeResponseBody(context, nettyRequest, response, bodyType, body);
            writeFinalNettyResponse(response, nettyRequest, context);
        }
    } else {
        response.body(null);
        writeFinalNettyResponse(response, nettyRequest, context);
    }
}
Also used : ByteBufOutputStream(io.netty.buffer.ByteBufOutputStream) NettyMutableHttpResponse(io.micronaut.http.netty.NettyMutableHttpResponse) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Writable(io.micronaut.core.io.Writable) IOException(java.io.IOException) Publisher(org.reactivestreams.Publisher) ApplicationEventPublisher(io.micronaut.context.event.ApplicationEventPublisher) ByteBuf(io.netty.buffer.ByteBuf) RouteInfo(io.micronaut.web.router.RouteInfo)

Aggregations

RouteInfo (io.micronaut.web.router.RouteInfo)7 MutableHttpResponse (io.micronaut.http.MutableHttpResponse)5 Argument (io.micronaut.core.type.Argument)4 HttpStatus (io.micronaut.http.HttpStatus)4 MediaType (io.micronaut.http.MediaType)4 Internal (io.micronaut.core.annotation.Internal)3 NonNull (io.micronaut.core.annotation.NonNull)3 Nullable (io.micronaut.core.annotation.Nullable)3 Publishers (io.micronaut.core.async.publisher.Publishers)3 ReferenceCounted (io.micronaut.core.io.buffer.ReferenceCounted)3 HttpAttributes (io.micronaut.http.HttpAttributes)3 HttpHeaders (io.micronaut.http.HttpHeaders)3 HttpMethod (io.micronaut.http.HttpMethod)3 HttpRequest (io.micronaut.http.HttpRequest)3 HttpResponse (io.micronaut.http.HttpResponse)3 MutableHttpHeaders (io.micronaut.http.MutableHttpHeaders)3 MediaTypeCodec (io.micronaut.http.codec.MediaTypeCodec)3 ServerRequestContext (io.micronaut.http.context.ServerRequestContext)3 RequestArgumentSatisfier (io.micronaut.http.server.binding.RequestArgumentSatisfier)3 ErrorContext (io.micronaut.http.server.exceptions.response.ErrorContext)3