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

标签 java apache file-upload httpclient digest-authentication

我正在使用 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/

相关文章:

java - 处理声音,库未正确安装

java - java中的这些注释会抛出什么异常?

excel - Odoo 13考勤模块如何设置内部用户上传和导入excel文件的权限?

php - 上传大型 JPG 文件后,WordPress async-upload.php 返回 500(内部服务器错误)

apache - Redmine 2.3.2 svn HTTPs 服务器 SSL 证书不受信任

php - 如何在Codeigniter中使用自定义函数上传文件

java - XML 配置大小为 0

java - 所以这是代码 : But it never considers the first string i write? 即使它仅以第一个单词结尾,它也不会计算在内

apache - fatal error : Uncaught exception 'Zend_Cache_Exception' with message > 'cache_dir must be a directory'

java - 如何使用 Apache Poi 库读取 xls 和 xlsx?