gpt4 book ai didi

java - Apache HttpClient 4.x 在上传大文件时表现异常?

转载 作者:搜寻专家 更新时间:2023-11-01 02:14:34 27 4
gpt4 key购买 nike

我正在使用 java(和 scala)开发和测试一个简单的客户端-服务器应用程序。

服务器 基于 com.sun.net.httpserver.HttpServer 并允许使用 POST 和 PUT 操作通过基本的 RESTful 接口(interface)上传文件。使用 Digest authentication 限制上传操作我们自己实现的,已经过测试,可以在浏览器、curl 和 Apache HttpClient 中运行。

上传客户端 包装Apache HttpClient 4.1.2 并通过http 执行PUT 操作以上传文件实体。文件的内容类型在 header 中指定为 application/xml,一次只上传一个文件。

当上传不同大小的文件时,可以观察到一个奇怪的行为:

  • 上传小于或等于 1.076.006 字节的文件成功
  • 大小大于或等于 1.122.158 字节的文件失败并返回 java.net.SocketException: Broken pipe

(确切的临界大小未知,因为我手动创建了不同大小的文件以接近最大工作大小)

管道破裂的原因是,客户端以某种方式忽略了www-authenticate-response 上传该大小的文件,如服务器日志所记录的那样。 “忽略”意味着它只发送多 (4) 条根本不包含身份验证 header 的消息。但是 较小的文件 运行良好,并且客户端在 www-authenticate-response 之后立即正确地发送带有正确质询-响应的身份验证请求。

上传适用于各种大小的文件,因此没有问题。

所以在这一点上,可以说:“您的客户端中存在一些错误。”好的,我有点希望如此,但是我也尝试过开源 java RESTclient (还包装了 apache httpclient)并且它具有完全相同的行为!

我们通过互联网使用此客户端对其进行了尝试,它也与描述的相同。所以现在,我只是希望我错过了在 Apache HttpClient 中设置一些重要的东西,这导致了这种错误行为,开源 RESTclient 的开发人员也错过了它......任何想法什么可能会很棒!

最佳答案

很可能是多种因素共同作用导致的这种情况

(1) 您的客户端很可能在发送带有不包含身份验证 header 的请求的大型请求实体时不使用“expect-continue”握手。

(2) 服务器及早检测到请求未达到预期,而不是读取和丢弃完整的请求主体,而是提前响应 401 状态并在其端关闭连接。在我看来,这是服务器方面的 HTTP 协议(protocol)违规。

(3) 虽然一些 HTTP 代理可以处理早期响应,但 Apache HttpClient 不能,因为 Java 阻塞 I/O 的限制(执行线程可以从阻塞套接字读取或写入,但不能同时进行)。

有多种方法可以解决这个问题,“期待-继续”握手是最简单和最自然的方法。或者,可以在执行大型 POST 或 PUT 请求之前执行简单的 HEAD 或 GET 请求以强制进行 HTTP 身份验证。 HttpClient 能够为同一逻辑 HTTP session 中的后续请求重新使用身份验证数据。

关于java - Apache HttpClient 4.x 在上传大文件时表现异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9161591/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com