public Output run(RunContext runContext) throws Exception {
        Logger logger = runContext.logger();
        URI from = new URI(runContext.render(this.uri));

        File tempFile = runContext.workingDir().createTempFile(filenameFromURI(from)).toFile();

        // output
        Output.OutputBuilder builder = Output.builder();

        // do it
        try (
            ReactorStreamingHttpClient client = this.streamingClient(runContext, this.method);
            BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(tempFile));
        ) {
            @SuppressWarnings("unchecked")
            HttpRequest<String> request = this.request(runContext);

            Long size = client
                .exchangeStream(request)
                .map(throwFunction(response -> {
                    if (builder.code == null) {
                        builder
                            .code(response.code())
                            .headers(response.getHeaders().asMap());
                    }

                    if (response.getBody().isPresent()) {
                        byte[] bytes = response.getBody().get().toByteArray();
                        output.write(bytes);

                        return (long) bytes.length;
                    } else {
                        return 0L;
                    }
                }))
                .reduce(Long::sum)
                .block();

            if (size == null) {
                size = 0L;
            }

            if (builder.headers != null && builder.headers.containsKey("Content-Length")) {
                long length = Long.parseLong(builder.headers.get("Content-Length").getFirst());
                if (length != size) {
                    throw new IllegalStateException("Invalid size, got " + size + ", expected " + length);
                }
            }

            output.flush();

            runContext.metric(Counter.of("response.length", size, this.tags(request, null)));
            builder.length(size);

            if (size == 0) {
                if (this.failOnEmptyResponse) {
                    throw new HttpClientResponseException("No response from server", HttpResponse.status(HttpStatus.SERVICE_UNAVAILABLE));
                } else {
                    logger.warn("File '{}' is empty", from);
                }
            }

            String filename = null;
            if (builder.headers != null && builder.headers.containsKey("Content-Disposition")) {
                String contentDisposition = builder.headers.get("Content-Disposition").getFirst();
                filename = filenameFromHeader(runContext, contentDisposition);
            }

            builder.uri(runContext.storage().putFile(tempFile, filename));

            logger.debug("File '{}' downloaded to '{}'", from, builder.uri);

            return builder.build();
        }
    }
@Test
    void noResponse() {
        EmbeddedServer embeddedServer = applicationContext.getBean(EmbeddedServer.class);
        embeddedServer.start();

        Download task = Download.builder()
            .id(DownloadTest.class.getSimpleName())
            .type(DownloadTest.class.getName())
            .uri(embeddedServer.getURI() + "/204")
            .build();

        RunContext runContext = TestsUtils.mockRunContext(this.runContextFactory, task, ImmutableMap.of());

        HttpClientResponseException exception = assertThrows(
            HttpClientResponseException.class,
            () -> task.run(runContext)
        );

        assertThat(exception.getMessage(), is("No response from server"));
    }