Vertx请求未在sendFile抛出时结束



我是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字节(。

唯一有效的方法是关闭与Response#close()的连接,这至少关闭了keep-alivehttp连接,并结束浏览器请求。

我想要实现的是将一些信息发送回客户端,以告知出现了问题,可能会将状态代码设置为适当的4**错误,并可能添加一些详细信息(在状态文本或响应正文中(。

您应该将failureHandler添加到您的路由器:

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

参见https://vertx.io/docs/vertx-web/java/#_error_handling

最新更新