Search in sources :

Example 1 with NettyHttpRequest

use of io.micronaut.http.server.netty.NettyHttpRequest in project micronaut-core by micronaut-projects.

the class HttpRequestDecoder method decode.

@Override
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) {
    if (LOG.isTraceEnabled()) {
        LOG.trace("Server {}:{} Received Request: {} {}", embeddedServer.getHost(), embeddedServer.getPort(), msg.method(), msg.uri());
    }
    try {
        NettyHttpRequest<Object> request = new NettyHttpRequest<>(msg, ctx, conversionService, configuration);
        if (httpRequestReceivedEventPublisher != ApplicationEventPublisher.NO_OP) {
            try {
                ctx.executor().execute(() -> {
                    try {
                        httpRequestReceivedEventPublisher.publishEvent(new HttpRequestReceivedEvent(request));
                    } catch (Exception e) {
                        if (LOG.isErrorEnabled()) {
                            LOG.error("Error publishing Http request received event: " + e.getMessage(), e);
                        }
                    }
                });
            } catch (Exception e) {
                if (LOG.isErrorEnabled()) {
                    LOG.error("Error publishing Http request received event: " + e.getMessage(), e);
                }
            }
        }
        out.add(request);
    } catch (IllegalArgumentException e) {
        // this configured the request in the channel as an attribute
        new NettyHttpRequest<>(new DefaultHttpRequest(msg.protocolVersion(), msg.method(), "/"), ctx, conversionService, configuration);
        final Throwable cause = e.getCause();
        ctx.fireExceptionCaught(cause != null ? cause : e);
        if (msg instanceof StreamedHttpRequest) {
            // discard any data that may come in
            ((StreamedHttpRequest) msg).closeIfNoSubscriber();
        }
    }
}
Also used : StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) HttpRequestReceivedEvent(io.micronaut.http.context.event.HttpRequestReceivedEvent) DefaultHttpRequest(io.netty.handler.codec.http.DefaultHttpRequest) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest)

Example 2 with NettyHttpRequest

use of io.micronaut.http.server.netty.NettyHttpRequest in project micronaut-core by micronaut-projects.

the class CompletableFutureBodyBinder method bind.

@Override
public BindingResult<CompletableFuture> bind(ArgumentConversionContext<CompletableFuture> context, HttpRequest<?> source) {
    if (source instanceof NettyHttpRequest) {
        NettyHttpRequest nettyHttpRequest = (NettyHttpRequest) source;
        io.netty.handler.codec.http.HttpRequest nativeRequest = ((NettyHttpRequest) source).getNativeRequest();
        if (nativeRequest instanceof StreamedHttpRequest) {
            CompletableFuture future = new CompletableFuture();
            Argument<?> targetType = context.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
            HttpContentProcessor<?> processor = httpContentProcessorResolver.resolve(nettyHttpRequest, targetType);
            processor.subscribe(new CompletionAwareSubscriber<Object>() {

                @Override
                protected void doOnSubscribe(Subscription subscription) {
                    subscription.request(1);
                }

                @Override
                protected void doOnNext(Object message) {
                    if (message instanceof ByteBufHolder) {
                        nettyHttpRequest.addContent((ByteBufHolder) message);
                    } else {
                        nettyHttpRequest.setBody(message);
                    }
                    subscription.request(1);
                }

                @Override
                protected void doOnError(Throwable t) {
                    future.completeExceptionally(t);
                }

                @Override
                protected void doOnComplete() {
                    Optional<Argument<?>> firstTypeParameter = context.getFirstTypeVariable();
                    if (firstTypeParameter.isPresent()) {
                        Argument<?> arg = firstTypeParameter.get();
                        Optional converted = nettyHttpRequest.getBody(arg);
                        if (converted.isPresent()) {
                            future.complete(converted.get());
                        } else {
                            future.completeExceptionally(new IllegalArgumentException("Cannot bind body to argument type: " + arg.getType().getName()));
                        }
                    } else {
                        future.complete(nettyHttpRequest.getBody().orElse(null));
                    }
                }
            });
            return () -> Optional.of(future);
        } else {
            return BindingResult.EMPTY;
        }
    } else {
        return BindingResult.EMPTY;
    }
}
Also used : Optional(java.util.Optional) Argument(io.micronaut.core.type.Argument) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) CompletableFuture(java.util.concurrent.CompletableFuture) ByteBufHolder(io.netty.buffer.ByteBufHolder) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) Subscription(org.reactivestreams.Subscription)

Example 3 with NettyHttpRequest

use of io.micronaut.http.server.netty.NettyHttpRequest in project micronaut-core by micronaut-projects.

the class NettyStreamedCustomizableResponseType method write.

@Override
default void write(HttpRequest<?> request, MutableHttpResponse<?> response, ChannelHandlerContext context) {
    if (response instanceof NettyMutableHttpResponse) {
        NettyMutableHttpResponse nettyResponse = ((NettyMutableHttpResponse) response);
        // Write the request data
        final DefaultHttpResponse finalResponse = new DefaultHttpResponse(nettyResponse.getNettyHttpVersion(), nettyResponse.getNettyHttpStatus(), nettyResponse.getNettyHeaders());
        final io.micronaut.http.HttpVersion httpVersion = request.getHttpVersion();
        final boolean isHttp2 = httpVersion == io.micronaut.http.HttpVersion.HTTP_2_0;
        if (request instanceof NettyHttpRequest) {
            ((NettyHttpRequest<?>) request).prepareHttp2ResponseIfNecessary(finalResponse);
        }
        InputStream inputStream = getInputStream();
        // can be null if the stream was closed
        context.write(finalResponse, context.voidPromise());
        if (inputStream != null) {
            ChannelFutureListener closeListener = (future) -> {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    LOG.warn("An error occurred closing an input stream", e);
                }
            };
            final HttpChunkedInput chunkedInput = new HttpChunkedInput(new ChunkedStream(inputStream));
            context.writeAndFlush(chunkedInput).addListener(closeListener);
        } else {
            context.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        }
    } else {
        throw new IllegalArgumentException("Unsupported response type. Not a Netty response: " + response);
    }
}
Also used : NettyMutableHttpResponse(io.micronaut.http.netty.NettyMutableHttpResponse) Logger(org.slf4j.Logger) HttpHeaderValues(io.netty.handler.codec.http.HttpHeaderValues) LoggerFactory(org.slf4j.LoggerFactory) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) IOException(java.io.IOException) NettyCustomizableResponseType(io.micronaut.http.server.netty.types.NettyCustomizableResponseType) ChunkedStream(io.netty.handler.stream.ChunkedStream) Internal(io.micronaut.core.annotation.Internal) HttpChunkedInput(io.netty.handler.codec.http.HttpChunkedInput) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) ChannelFutureListener(io.netty.channel.ChannelFutureListener) HttpRequest(io.micronaut.http.HttpRequest) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) InputStream(java.io.InputStream) InputStream(java.io.InputStream) ChunkedStream(io.netty.handler.stream.ChunkedStream) IOException(java.io.IOException) ChannelFutureListener(io.netty.channel.ChannelFutureListener) NettyMutableHttpResponse(io.micronaut.http.netty.NettyMutableHttpResponse) HttpChunkedInput(io.netty.handler.codec.http.HttpChunkedInput) DefaultHttpResponse(io.netty.handler.codec.http.DefaultHttpResponse) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest)

Example 4 with NettyHttpRequest

use of io.micronaut.http.server.netty.NettyHttpRequest in project micronaut-core by micronaut-projects.

the class FileTypeHandler method handle.

@SuppressWarnings("MagicNumber")
@Override
public void handle(Object obj, HttpRequest<?> request, MutableHttpResponse<?> response, ChannelHandlerContext context) {
    NettyFileCustomizableResponseType type;
    if (obj instanceof File) {
        type = new NettySystemFileCustomizableResponseType((File) obj);
    } else if (obj instanceof NettyFileCustomizableResponseType) {
        type = (NettyFileCustomizableResponseType) obj;
    } else if (obj instanceof StreamedFile) {
        type = new NettyStreamedFileCustomizableResponseType((StreamedFile) obj);
    } else if (obj instanceof SystemFile) {
        type = new NettySystemFileCustomizableResponseType((SystemFile) obj);
    } else {
        throw new CustomizableResponseTypeException("FileTypeHandler only supports File or FileCustomizableResponseType types");
    }
    long lastModified = type.getLastModified();
    // Cache Validation
    ZonedDateTime ifModifiedSince = request.getHeaders().getDate(HttpHeaders.IF_MODIFIED_SINCE);
    if (ifModifiedSince != null) {
        // Only compare up to the second because the datetime format we send to the client
        // does not have milliseconds
        long ifModifiedSinceDateSeconds = ifModifiedSince.toEpochSecond();
        long fileLastModifiedSeconds = lastModified / 1000;
        if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
            FullHttpResponse nettyResponse = notModified(response);
            if (request instanceof NettyHttpRequest) {
                ((NettyHttpRequest<?>) request).prepareHttp2ResponseIfNecessary(nettyResponse);
            }
            context.writeAndFlush(nettyResponse);
            return;
        }
    }
    if (!response.getHeaders().contains(HttpHeaders.CONTENT_TYPE)) {
        response.header(HttpHeaders.CONTENT_TYPE, type.getMediaType().toString());
    }
    setDateAndCacheHeaders(response, lastModified);
    type.process(response);
    type.write(request, response, context);
    context.read();
}
Also used : NettyFileCustomizableResponseType(io.micronaut.http.server.netty.types.NettyFileCustomizableResponseType) ZonedDateTime(java.time.ZonedDateTime) SystemFile(io.micronaut.http.server.types.files.SystemFile) StreamedFile(io.micronaut.http.server.types.files.StreamedFile) FullHttpResponse(io.netty.handler.codec.http.FullHttpResponse) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) StreamedFile(io.micronaut.http.server.types.files.StreamedFile) SystemFile(io.micronaut.http.server.types.files.SystemFile) File(java.io.File) CustomizableResponseTypeException(io.micronaut.http.server.types.CustomizableResponseTypeException)

Example 5 with NettyHttpRequest

use of io.micronaut.http.server.netty.NettyHttpRequest in project micronaut-core by micronaut-projects.

the class HttpRequestTest method testForEach2.

public void testForEach2() {
    final DefaultFullHttpRequest nettyRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, io.netty.handler.codec.http.HttpMethod.GET, "/test");
    nettyRequest.headers().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
    nettyRequest.headers().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML);
    HttpRequest<?> request = new NettyHttpRequest(nettyRequest, new DetachedMockFactory().Mock(ChannelHandlerContext.class), ConversionService.SHARED, new HttpServerConfiguration());
    final HttpHeaders headers = request.getHeaders();
    headers.forEach((name, values) -> {
        assertEquals(HttpHeaders.CONTENT_TYPE, name);
        assertEquals(2, values.size());
        assertTrue(values.contains(MediaType.APPLICATION_JSON));
        assertTrue(values.contains(MediaType.APPLICATION_XML));
    });
    AtomicInteger integer = new AtomicInteger(0);
    headers.forEachValue((s, s2) -> integer.incrementAndGet());
    assertEquals(2, integer.get());
}
Also used : HttpHeaders(io.micronaut.http.HttpHeaders) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HttpServerConfiguration(io.micronaut.http.server.HttpServerConfiguration) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) DetachedMockFactory(spock.mock.DetachedMockFactory)

Aggregations

NettyHttpRequest (io.micronaut.http.server.netty.NettyHttpRequest)13 StreamedHttpRequest (io.micronaut.http.netty.stream.StreamedHttpRequest)5 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)5 Internal (io.micronaut.core.annotation.Internal)4 HttpRequest (io.micronaut.http.HttpRequest)4 ByteBufHolder (io.netty.buffer.ByteBufHolder)4 Optional (java.util.Optional)4 Subscription (org.reactivestreams.Subscription)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 MutableHttpResponse (io.micronaut.http.MutableHttpResponse)3 HttpServerConfiguration (io.micronaut.http.server.HttpServerConfiguration)3 EmptyByteBuf (io.netty.buffer.EmptyByteBuf)3 NonNull (io.micronaut.core.annotation.NonNull)2 TypedSubscriber (io.micronaut.core.async.subscriber.TypedSubscriber)2 StringUtils (io.micronaut.core.util.StringUtils)2 HttpAttributes (io.micronaut.http.HttpAttributes)2 HttpMethod (io.micronaut.http.HttpMethod)2 HttpResponse (io.micronaut.http.HttpResponse)2 HttpStatus (io.micronaut.http.HttpStatus)2