Search in sources :

Example 1 with DefaultHttpContentProcessor

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

the class MultipartBodyArgumentBinder method bind.

@Override
public BindingResult<MultipartBody> bind(ArgumentConversionContext<MultipartBody> context, HttpRequest<?> source) {
    if (source instanceof NettyHttpRequest) {
        NettyHttpRequest nettyHttpRequest = (NettyHttpRequest) source;
        io.netty.handler.codec.http.HttpRequest nativeRequest = nettyHttpRequest.getNativeRequest();
        if (nativeRequest instanceof StreamedHttpRequest) {
            HttpContentProcessor<?> processor = beanLocator.findBean(HttpContentSubscriberFactory.class, new ConsumesMediaTypeQualifier<>(MediaType.MULTIPART_FORM_DATA_TYPE)).map(factory -> factory.build(nettyHttpRequest)).orElse(new DefaultHttpContentProcessor(nettyHttpRequest, httpServerConfiguration.get()));
            // noinspection unchecked
            return () -> Optional.of(subscriber -> processor.subscribe(new TypedSubscriber<Object>((Argument) context.getArgument()) {

                Subscription s;

                AtomicLong partsRequested = new AtomicLong(0);

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

                        @Override
                        public void request(long n) {
                            if (partsRequested.getAndUpdate(prev -> prev + n) == 0) {
                                s.request(n);
                            }
                        }

                        @Override
                        public void cancel() {
                            subscription.cancel();
                        }
                    });
                }

                @Override
                protected void doOnNext(Object message) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Server received streaming message for argument [{}]: {}", context.getArgument(), message);
                    }
                    if (message instanceof ByteBufHolder && ((ByteBufHolder) message).content() instanceof EmptyByteBuf) {
                        return;
                    }
                    if (message instanceof HttpData) {
                        HttpData data = (HttpData) message;
                        if (data.isCompleted()) {
                            partsRequested.decrementAndGet();
                            if (data instanceof FileUpload) {
                                subscriber.onNext(new NettyCompletedFileUpload((FileUpload) data, false));
                            } else if (data instanceof Attribute) {
                                subscriber.onNext(new NettyCompletedAttribute((Attribute) data, false));
                            }
                            // If the user didn't release the data, we should
                            if (data.refCnt() > 0) {
                                data.release();
                            }
                        }
                    }
                    if (partsRequested.get() > 0) {
                        s.request(1);
                    }
                }

                @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 : ArgumentConversionContext(io.micronaut.core.convert.ArgumentConversionContext) LoggerFactory(org.slf4j.LoggerFactory) DefaultHttpContentProcessor(io.micronaut.http.server.netty.DefaultHttpContentProcessor) Internal(io.micronaut.core.annotation.Internal) ByteBufHolder(io.netty.buffer.ByteBufHolder) HttpContentProcessor(io.micronaut.http.server.netty.HttpContentProcessor) TypedSubscriber(io.micronaut.core.async.subscriber.TypedSubscriber) NonBlockingBodyArgumentBinder(io.micronaut.http.bind.binders.NonBlockingBodyArgumentBinder) MediaType(io.micronaut.http.MediaType) HttpData(io.netty.handler.codec.http.multipart.HttpData) Argument(io.micronaut.core.type.Argument) HttpRequest(io.micronaut.http.HttpRequest) BeanLocator(io.micronaut.context.BeanLocator) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) NettyHttpServer(io.micronaut.http.server.netty.NettyHttpServer) Logger(org.slf4j.Logger) MultipartBody(io.micronaut.http.server.multipart.MultipartBody) FileUpload(io.netty.handler.codec.http.multipart.FileUpload) HttpServerConfiguration(io.micronaut.http.server.HttpServerConfiguration) HttpContentSubscriberFactory(io.micronaut.http.server.netty.HttpContentSubscriberFactory) Attribute(io.netty.handler.codec.http.multipart.Attribute) AtomicLong(java.util.concurrent.atomic.AtomicLong) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) EmptyByteBuf(io.netty.buffer.EmptyByteBuf) BeanProvider(io.micronaut.context.BeanProvider) Subscription(org.reactivestreams.Subscription) Optional(java.util.Optional) ConsumesMediaTypeQualifier(io.micronaut.web.router.qualifier.ConsumesMediaTypeQualifier) EmptyByteBuf(io.netty.buffer.EmptyByteBuf) Attribute(io.netty.handler.codec.http.multipart.Attribute) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) AtomicLong(java.util.concurrent.atomic.AtomicLong) DefaultHttpContentProcessor(io.micronaut.http.server.netty.DefaultHttpContentProcessor) HttpData(io.netty.handler.codec.http.multipart.HttpData) ByteBufHolder(io.netty.buffer.ByteBufHolder) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) Subscription(org.reactivestreams.Subscription) TypedSubscriber(io.micronaut.core.async.subscriber.TypedSubscriber) FileUpload(io.netty.handler.codec.http.multipart.FileUpload)

Aggregations

BeanLocator (io.micronaut.context.BeanLocator)1 BeanProvider (io.micronaut.context.BeanProvider)1 Internal (io.micronaut.core.annotation.Internal)1 TypedSubscriber (io.micronaut.core.async.subscriber.TypedSubscriber)1 ArgumentConversionContext (io.micronaut.core.convert.ArgumentConversionContext)1 Argument (io.micronaut.core.type.Argument)1 HttpRequest (io.micronaut.http.HttpRequest)1 MediaType (io.micronaut.http.MediaType)1 NonBlockingBodyArgumentBinder (io.micronaut.http.bind.binders.NonBlockingBodyArgumentBinder)1 StreamedHttpRequest (io.micronaut.http.netty.stream.StreamedHttpRequest)1 HttpServerConfiguration (io.micronaut.http.server.HttpServerConfiguration)1 MultipartBody (io.micronaut.http.server.multipart.MultipartBody)1 DefaultHttpContentProcessor (io.micronaut.http.server.netty.DefaultHttpContentProcessor)1 HttpContentProcessor (io.micronaut.http.server.netty.HttpContentProcessor)1 HttpContentSubscriberFactory (io.micronaut.http.server.netty.HttpContentSubscriberFactory)1 NettyHttpRequest (io.micronaut.http.server.netty.NettyHttpRequest)1 NettyHttpServer (io.micronaut.http.server.netty.NettyHttpServer)1 ConsumesMediaTypeQualifier (io.micronaut.web.router.qualifier.ConsumesMediaTypeQualifier)1 ByteBufHolder (io.netty.buffer.ByteBufHolder)1 EmptyByteBuf (io.netty.buffer.EmptyByteBuf)1