Search in sources :

Example 1 with ReceivedResponse

use of ratpack.http.client.ReceivedResponse in project ratpack by ratpack.

the class BlockingHttpClient method request.

public ReceivedResponse request(HttpClient httpClient, URI uri, ExecController execController, Duration timeout, Action<? super RequestSpec> action) throws Throwable {
    CountDownLatch latch = new CountDownLatch(1);
    AtomicReference<ExecResult<ReceivedResponse>> result = new AtomicReference<>();
    execController.fork().start(e -> httpClient.request(uri, action.prepend(s -> s.readTimeout(Duration.ofHours(1)))).map(response -> {
        TypedData responseBody = response.getBody();
        ByteBuf responseBuffer = responseBody.getBuffer();
        ByteBuf heapResponseBodyBuffer = unreleasableBuffer(responseBuffer.isDirect() ? TestByteBufAllocators.LEAKING_UNPOOLED_HEAP.heapBuffer(responseBuffer.readableBytes()).writeBytes(responseBuffer) : responseBuffer.retain());
        return new DefaultReceivedResponse(response.getStatus(), response.getHeaders(), new ByteBufBackedTypedData(heapResponseBodyBuffer, responseBody.getContentType()));
    }).connect(new Downstream<ReceivedResponse>() {

        @Override
        public void success(ReceivedResponse value) {
            result.set(ExecResult.of(Result.success(value)));
            latch.countDown();
        }

        @Override
        public void error(Throwable throwable) {
            result.set(ExecResult.of(Result.error(throwable)));
            latch.countDown();
        }

        @Override
        public void complete() {
            result.set(ExecResult.complete());
            latch.countDown();
        }
    }));
    try {
        if (!latch.await(timeout.toNanos(), TimeUnit.NANOSECONDS)) {
            TemporalUnit unit = timeout.getUnits().get(0);
            throw new IllegalStateException("Request to " + uri + " took more than " + timeout.get(unit) + " " + unit.toString() + " to complete");
        }
    } catch (InterruptedException e) {
        throw Exceptions.uncheck(e);
    }
    return result.get().getValueOrThrow();
}
Also used : TypedData(ratpack.http.TypedData) ByteBufBackedTypedData(ratpack.http.internal.ByteBufBackedTypedData) TemporalUnit(java.time.temporal.TemporalUnit) DefaultReceivedResponse(ratpack.http.client.internal.DefaultReceivedResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuf(io.netty.buffer.ByteBuf) ReceivedResponse(ratpack.http.client.ReceivedResponse) DefaultReceivedResponse(ratpack.http.client.internal.DefaultReceivedResponse) ByteBufBackedTypedData(ratpack.http.internal.ByteBufBackedTypedData) Downstream(ratpack.exec.Downstream) ExecResult(ratpack.exec.ExecResult)

Example 2 with ReceivedResponse

use of ratpack.http.client.ReceivedResponse in project ratpack by ratpack.

the class RequestActionSupport method addCommonResponseHandlers.

private void addCommonResponseHandlers(ChannelPipeline p, Downstream<? super T> downstream) throws Exception {
    if (channelKey.ssl && p.get(SSL_HANDLER_NAME) == null) {
        // this is added once because netty is not able to properly replace this handler on
        // pooled channels from request to request. Because a pool is unique to a uri,
        // doing this works, as subsequent requests would be passing in the same certs.
        p.addLast(SSL_HANDLER_NAME, createSslHandler());
    }
    p.addLast(CLIENT_CODEC_HANDLER_NAME, new HttpClientCodec(4096, 8192, requestConfig.responseMaxChunkSize, false));
    p.addLast(READ_TIMEOUT_HANDLER_NAME, new ReadTimeoutHandler(requestConfig.readTimeout.toNanos(), TimeUnit.NANOSECONDS));
    p.addLast(REDIRECT_HANDLER_NAME, new SimpleChannelInboundHandler<HttpObject>(false) {

        boolean redirected;

        HttpResponse response;

        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            ctx.fireExceptionCaught(new PrematureChannelClosureException("Server " + requestConfig.uri + " closed the connection prematurely"));
        }

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
            if (msg instanceof HttpResponse) {
                this.response = (HttpResponse) msg;
                int maxRedirects = requestConfig.maxRedirects;
                int status = response.status().code();
                String locationValue = response.headers().getAsString(HttpHeaderConstants.LOCATION);
                Action<? super RequestSpec> redirectConfigurer = RequestActionSupport.this.requestConfigurer;
                if (isRedirect(status) && redirectCount < maxRedirects && locationValue != null) {
                    final Function<? super ReceivedResponse, Action<? super RequestSpec>> onRedirect = requestConfig.onRedirect;
                    if (onRedirect != null) {
                        final Action<? super RequestSpec> onRedirectResult = onRedirect.apply(toReceivedResponse(response));
                        if (onRedirectResult == null) {
                            redirectConfigurer = null;
                        } else {
                            redirectConfigurer = redirectConfigurer.append(onRedirectResult);
                        }
                    }
                    if (redirectConfigurer != null) {
                        Action<? super RequestSpec> redirectRequestConfig = s -> {
                            if (status == 301 || status == 302) {
                                s.get();
                            }
                        };
                        redirectRequestConfig = redirectConfigurer.append(redirectRequestConfig);
                        URI locationUrl;
                        if (ABSOLUTE_PATTERN.matcher(locationValue).matches()) {
                            locationUrl = new URI(locationValue);
                        } else {
                            locationUrl = new URI(channelKey.ssl ? "https" : "http", null, channelKey.host, channelKey.port, locationValue, null, null);
                        }
                        onRedirect(locationUrl, redirectCount + 1, redirectRequestConfig).connect(downstream);
                        redirected = true;
                        dispose(ctx.pipeline(), response);
                    }
                }
            }
            if (!redirected) {
                ctx.fireChannelRead(msg);
            }
        }
    });
    if (requestConfig.decompressResponse) {
        p.addLast(DECOMPRESS_HANDLER_NAME, new HttpContentDecompressor());
    }
    addResponseHandlers(p, downstream);
}
Also used : Action(ratpack.func.Action) PrematureChannelClosureException(io.netty.handler.codec.PrematureChannelClosureException) ReceivedResponse(ratpack.http.client.ReceivedResponse) URI(java.net.URI) PrematureChannelClosureException(io.netty.handler.codec.PrematureChannelClosureException) ReadTimeoutException(io.netty.handler.timeout.ReadTimeoutException) SSLException(javax.net.ssl.SSLException) HttpClientReadTimeoutException(ratpack.http.client.HttpClientReadTimeoutException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Function(ratpack.func.Function) ReadTimeoutHandler(io.netty.handler.timeout.ReadTimeoutHandler) RequestSpec(ratpack.http.client.RequestSpec)

Aggregations

ReceivedResponse (ratpack.http.client.ReceivedResponse)2 ByteBuf (io.netty.buffer.ByteBuf)1 PrematureChannelClosureException (io.netty.handler.codec.PrematureChannelClosureException)1 ReadTimeoutException (io.netty.handler.timeout.ReadTimeoutException)1 ReadTimeoutHandler (io.netty.handler.timeout.ReadTimeoutHandler)1 URI (java.net.URI)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 TemporalUnit (java.time.temporal.TemporalUnit)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 SSLException (javax.net.ssl.SSLException)1 Downstream (ratpack.exec.Downstream)1 ExecResult (ratpack.exec.ExecResult)1 Action (ratpack.func.Action)1 Function (ratpack.func.Function)1 TypedData (ratpack.http.TypedData)1 HttpClientReadTimeoutException (ratpack.http.client.HttpClientReadTimeoutException)1 RequestSpec (ratpack.http.client.RequestSpec)1 DefaultReceivedResponse (ratpack.http.client.internal.DefaultReceivedResponse)1 ByteBufBackedTypedData (ratpack.http.internal.ByteBufBackedTypedData)1