Запрос Vertx не заканчивается на броске sendFile - PullRequest
0 голосов
/ 05 апреля 2020

Я новичок в vert.x и пытаюсь создать простой сервис загрузки.

Я использовал Request#sendFile(fileName), и он работает хорошо, но если я передам путь к каталогу Request#sendFile(fileName) он выдает исключение, что вполне нормально.

Проблема в том, что даже если я перехватываю это исключение с помощью обработчика, я не могу ни отправлять данные, ни завершать запрос, это приводит к тому, что http-клиент (браузер) застрял в бесконечном вращении.

Это пример, который воспроизводит проблему:

        VertxOptions options = new VertxOptions();
        options.setBlockedThreadCheckInterval(1000*60*60);

        Vertx vertx = Vertx.vertx(options);     
        HttpServer server = vertx.createHttpServer();
        Router router = Router.router(vertx);
        router
            .route(HttpMethod.GET,"/foo")
            .handler(ctx->{
                // this path exist but is not a file, is a directory.
                ctx.response().sendFile("docs/pdf",asr->{
                    if(asr.failed()) {
                        ctx.response()
                            .setStatusCode(404)
                            // I can't end the connection the only thing I can do is close it
                            // I've commented out this lambda because is not what I want to happen.
                            // It's just an hack to end the request all the same.
                            .end("File not found: "+"docs/pdf" /*, (x)->{ctx.response().close();}*/ );
                    }
                });
            });

        server
            .requestHandler(router)
            .listen(3000);

Я могу решить эту проблему, сначала проверив, если путь ссылки на файл, который существует и не является каталогом (что на самом деле я сделал в реальном коде), но это оставляет у меня сомнения относительно того, что произойдет, если IOException будет что-то другое (например, чтение сломанного ) файл или неавторизованный файл ...).

Когда эта ошибка происходит, данные не передаются по проводам, я одновременно проверил из браузера и перехватил пакеты TCP-пакеты (0 байтов отправлено из сервер к брату wser).

Единственное, что работает, - это закрытие соединения с Response#close(), которое как минимум закрывает соединение keep-alive http и завершает запрос браузера.

Чего я хочу добиться, так это отправить некоторую информацию обратно клиенту, чтобы сообщить, что что-то пошло не так, возможно, установив код состояния на соответствующую ошибку 4** и, возможно, добавив к ней некоторые детали (либо в тексте статуса, либо в ответе). тела).

1 Ответ

0 голосов
/ 06 апреля 2020

Вы должны добавить failureHandler к вашему роутеру:

route.failureHandler(frc-> {
  frc.response().setStatusCode( 400 ).end("Sorry! Not today");
});

см. https://vertx.io/docs/vertx-web/java/#_error_handling

...