Search in sources :

Example 11 with NettyHttpRequest

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

the class InputStreamBodyBinder method bind.

@SuppressWarnings("unchecked")
@Override
public BindingResult<InputStream> bind(ArgumentConversionContext<InputStream> context, HttpRequest<?> source) {
    if (source instanceof NettyHttpRequest) {
        NettyHttpRequest nettyHttpRequest = (NettyHttpRequest) source;
        io.netty.handler.codec.http.HttpRequest nativeRequest = nettyHttpRequest.getNativeRequest();
        if (nativeRequest instanceof StreamedHttpRequest) {
            PipedOutputStream outputStream = new PipedOutputStream();
            try {
                PipedInputStream inputStream = new PipedInputStream(outputStream) {

                    private volatile HttpContentProcessor<ByteBufHolder> processor;

                    private synchronized void init() {
                        if (processor == null) {
                            processor = (HttpContentProcessor<ByteBufHolder>) processorResolver.resolve(nettyHttpRequest, context.getArgument());
                            Flux.from(processor).publishOn(Schedulers.fromExecutor(executorService)).subscribe(new CompletionAwareSubscriber<ByteBufHolder>() {

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

                                @Override
                                protected synchronized void doOnNext(ByteBufHolder message) {
                                    if (LOG.isTraceEnabled()) {
                                        LOG.trace("Server received streaming message for argument [{}]: {}", context.getArgument(), message);
                                    }
                                    ByteBuf content = message.content();
                                    if (!(content instanceof EmptyByteBuf)) {
                                        try {
                                            byte[] bytes = ByteBufUtil.getBytes(content);
                                            outputStream.write(bytes, 0, bytes.length);
                                        } catch (IOException e) {
                                            subscription.cancel();
                                            return;
                                        } finally {
                                            content.release();
                                        }
                                    }
                                    subscription.request(1);
                                }

                                @Override
                                protected synchronized void doOnError(Throwable t) {
                                    if (LOG.isTraceEnabled()) {
                                        LOG.trace("Server received error for argument [" + context.getArgument() + "]: " + t.getMessage(), t);
                                    }
                                    try {
                                        outputStream.close();
                                    } catch (IOException ignored) {
                                    } finally {
                                        subscription.cancel();
                                    }
                                }

                                @Override
                                protected synchronized void doOnComplete() {
                                    if (LOG.isTraceEnabled()) {
                                        LOG.trace("Done receiving messages for argument: {}", context.getArgument());
                                    }
                                    try {
                                        outputStream.close();
                                    } catch (IOException ignored) {
                                    }
                                }
                            });
                        }
                    }

                    @Override
                    public synchronized int read(byte[] b, int off, int len) throws IOException {
                        init();
                        return super.read(b, off, len);
                    }

                    @Override
                    public synchronized int read() throws IOException {
                        init();
                        return super.read();
                    }
                };
                return () -> Optional.of(inputStream);
            } catch (IOException e) {
                context.reject(e);
            }
        }
    }
    return BindingResult.EMPTY;
}
Also used : EmptyByteBuf(io.netty.buffer.EmptyByteBuf) PipedOutputStream(java.io.PipedOutputStream) PipedInputStream(java.io.PipedInputStream) IOException(java.io.IOException) ByteBuf(io.netty.buffer.ByteBuf) EmptyByteBuf(io.netty.buffer.EmptyByteBuf) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) HttpContentProcessor(io.micronaut.http.server.netty.HttpContentProcessor) ByteBufHolder(io.netty.buffer.ByteBufHolder) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) Subscription(org.reactivestreams.Subscription)

Example 12 with NettyHttpRequest

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

the class PublisherBodyBinder method bind.

@Override
public BindingResult<Publisher> bind(ArgumentConversionContext<Publisher> context, HttpRequest<?> source) {
    if (source instanceof NettyHttpRequest) {
        NettyHttpRequest nettyHttpRequest = (NettyHttpRequest) source;
        io.netty.handler.codec.http.HttpRequest nativeRequest = nettyHttpRequest.getNativeRequest();
        if (nativeRequest instanceof StreamedHttpRequest) {
            Argument<?> targetType = context.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
            HttpContentProcessor<?> processor = httpContentProcessorResolver.resolve(nettyHttpRequest, targetType);
            // noinspection unchecked
            return () -> Optional.of(subscriber -> processor.subscribe(new TypedSubscriber<Object>((Argument) context.getArgument()) {

                Subscription s;

                @Override
                protected void doOnSubscribe(Subscription subscription) {
                    this.s = subscription;
                    subscriber.onSubscribe(subscription);
                }

                @Override
                protected void doOnNext(Object message) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Server received streaming message for argument [{}]: {}", context.getArgument(), message);
                    }
                    if (message instanceof ByteBufHolder) {
                        message = ((ByteBufHolder) message).content();
                        if (message instanceof EmptyByteBuf) {
                            return;
                        }
                    }
                    ArgumentConversionContext<?> conversionContext = context.with(targetType);
                    Optional<?> converted = conversionService.convert(message, conversionContext);
                    if (converted.isPresent()) {
                        subscriber.onNext(converted.get());
                    } else {
                        try {
                            Optional<ConversionError> lastError = conversionContext.getLastError();
                            if (lastError.isPresent()) {
                                if (LOG.isDebugEnabled()) {
                                    LOG.debug("Cannot convert message for argument [" + context.getArgument() + "] and value: " + message, lastError.get());
                                }
                                subscriber.onError(new ConversionErrorException(context.getArgument(), lastError.get()));
                            } else {
                                if (LOG.isDebugEnabled()) {
                                    LOG.debug("Cannot convert message for argument [{}] and value: {}", context.getArgument(), message);
                                }
                                subscriber.onError(UnsatisfiedRouteException.create(context.getArgument()));
                            }
                        } finally {
                            s.cancel();
                        }
                    }
                    if (message instanceof ReferenceCounted) {
                        ((ReferenceCounted) message).release();
                    }
                }

                @Override
                protected void doOnError(Throwable t) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Server received error for argument [" + context.getArgument() + "]: " + t.getMessage(), t);
                    }
                    try {
                        subscriber.onError(t);
                    } finally {
                        s.cancel();
                    }
                }

                @Override
                protected void doOnComplete() {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Done receiving messages for argument: {}", context.getArgument());
                    }
                    subscriber.onComplete();
                }
            }));
        }
    }
    return BindingResult.EMPTY;
}
Also used : EmptyByteBuf(io.netty.buffer.EmptyByteBuf) ConversionError(io.micronaut.core.convert.ConversionError) ConversionErrorException(io.micronaut.core.convert.exceptions.ConversionErrorException) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) ByteBufHolder(io.netty.buffer.ByteBufHolder) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) Subscription(org.reactivestreams.Subscription) TypedSubscriber(io.micronaut.core.async.subscriber.TypedSubscriber) ReferenceCounted(io.netty.util.ReferenceCounted)

Example 13 with NettyHttpRequest

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

the class SessionLogElement method onResponseHeaders.

@SuppressWarnings("rawtypes")
@Override
public String onResponseHeaders(ChannelHandlerContext ctx, HttpHeaders headers, String status) {
    final Attribute<NettyHttpRequest> attr = ctx.channel().attr(KEY);
    NettyHttpRequest request = attr.get();
    if (request == null) {
        return ConstantElement.UNKNOWN_VALUE;
    }
    return SessionForRequest.find(request).map(this::value).orElse(ConstantElement.UNKNOWN_VALUE);
}
Also used : NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest)

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