我有一个java的Web应用程序,它使用Apache Commons FileUpload使用servlet上传文件。
我的基本代码在普通超文本传输协议环境(Apache Tomcat 8.5)上完美运行了多年。
我已经更改了我的环境以使用HTTPS,使用使用org. apache.coyote.http11配置的连接器的Let's Encrypt证书。Http11AprProtocol。
如果文件大于100kb,我的上传现在突然失败。使用普通HTTP环境成功上传相同的文件。
这是记录的异常:
org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. java.io.IOException: The socket [925,024,592] associated with this connection has been closed.
这是我用于管理请求的代码片段:
DiskFileItemFactory factory = new DiskFileItemFactory();
File repository = (File)
request.getServletContext().getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding(encoding);
multipartItems = upload.parseRequest(request);
Tomcat设置:
<Connector
port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"
/>
<Connector
port="443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true"
>
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate
certificateKeyFile="D:/prj/certificati/private.key"
certificateFile="D:/prj/certificati/certificate.crt"
certificateChainFile="D:/prj/certificati/ca_bundle.crt"
type="RSA"
/>
</SSLHostConfig>
</Connector>
我研究过这个问题,很少有案例,没有解决方案。
谢啦
使用http2时上传的时间太短
尝试更改升级协议
<UpgradeProtocol overheadWindowUpdateThreshold="-1" overheadDataThreshold="-1" writeTimeout="-1" streamWriteTimeout="-1" streamReadTimeout="-1" maxHeaderSize="8192" maxConcurrentStreams="300" readTimeout="-1" className="org.apache.coyote.http2.Http2Protocol" compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json" compression="on" compressionMinSize="1024"/>
这听起来像是客户端触发了开销阈值保护。
作为短期修复,您可能希望看到以下值较低:overhead DataThreshold
参见:http://tomcat.apache.org/tomcat-8.5-doc/config/http2.html
可能低至零。
从长远来看,您最好研究一下为什么客户端发送小的、非最终的数据帧,因为这是低效的,并且在某些服务器中已被确定为潜在的DoS向量(不是Tomcat,但我们无论如何都会将其阻止为滥用行为)。
根据客户端正在做的事情,您可能还需要调整其他的超头阈值。如果您有一个可重复的测试用例,在logging.properties中启用http2的调试应该会让您了解到底发生了什么。
我发现了问题。显然,这个问题是由这个指令引起的:
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
删除它,它起作用了。