【问题标题】:Apache Commons FileUpload: problems uploading files greater than 100kb using HTTPSApache Commons FileUpload:使用 HTTPS 上传大于 100kb 的文件时出现问题
【发布时间】:2019-09-26 14:14:35
【问题描述】:

我有一个 java web 应用程序,它使用 Apache Commons FileUpload 来使用 servlet 上传文件。

我的基本代码在普通的 http 环境 (Apache Tomcat 8.5) 上完美运行多年。

我已更改我的环境以使用 HTTPS,使用通过 org.apache.coyote.http11.Http11AprProtocol 配置的连接器使用 Let's Encrypt 证书。

如果文件大于 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>

我研究过这个问题,很少有案例,没有解决方案。

谢谢

【问题讨论】:

    标签: tomcat servlets https apache-commons-fileupload


    【解决方案1】:

    使用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"/>
    

    【讨论】:

    • 这帮助我解决了生产中的客户问题,非常感谢!我没有意识到您可以将配置放在 中,而将其放在封闭的 中对我不起作用。
    【解决方案2】:

    听起来客户端已经触发了开销阈值保护。

    作为短期修复,您可能希望看到以下值的较低值: 开销数据阈值

    见:http://tomcat.apache.org/tomcat-8.5-doc/config/http2.html

    可能低至零。

    从长远来看,您最好研究一下客户端发送的原因 小的、非最终的 DATA 帧,因为那是低效的,并且一直 在某些服务器(不是 Tomcat,但我们 无论如何都要阻止它作为滥用行为)。

    根据客户正在做什么,您可能需要调整其他 也超过了头部阈值。如果您有可重现的测试用例, 在 logging.properties 中为 http2 启用调试应该会有所帮助 到底发生了什么。

    【讨论】:

    • 感谢马克的回复。目前我已经解决了我放弃升级到 http2 协议的问题,我的 web 应用程序现在正在生产中,它运行良好,我不需要其他修复。如果它没有损坏,请不要修复它:-)。任何时候,我现在都知道是哪个问题导致了问题,所以如果我在另一个环境中再次遇到它,我会进一步调查。
    【解决方案3】:

    我发现了问题。显然,这个问题是由这个指令引起的:

     <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
    

    删除它,它的工作原理。

    【讨论】:

    • 这不是一个真正的解决方案,这个指令启用了 HTTP/2,所以通过删除它,你已经降级了协议。如果您在页面加载期间提供大量文件,这会降低性能。
    【解决方案4】:

    https://bz.apache.org/bugzilla/show_bug.cgi?id=59564

    升级 tomcat 为我解决了这个问题。

    【讨论】:

    猜你喜欢
    • 2019-10-16
    • 2015-12-23
    • 1970-01-01
    • 2015-07-09
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    • 2012-06-01
    相关资源
    最近更新 更多