从 Firefox 74/75 发布 multipart/form-data 并在服务器端使用 Apache AJP 连接器时出现 java.io.IOException

标签 java apache jsp tomcat firefox

自 Firefox 74 版本以来,使用“multipart/form-data”表单发送的文件大小超过约 1.8 MB 的文件会引发错误。

注意:使用 AJAX 发送的文件工作正常。只有多部分表单提交会导致问题。

HTML 代码:

<form name="formUpload" action="AdminImportInssAseg" method="POST"
            enctype="multipart/form-data" onsubmit="return validate_form(this);">
    <table class="centrado green">
        <tr>
            <td><input type="File" name="miadjuntoSolvenciaX" class="mdt">&nbsp;
            </td>
        </tr>
        <tr>
            <td align="center" colspan="2"><a href="#"
                onClick="if(validate_form(formUpload)) formUpload.submit();"
                title="Importar el archivo"><img alt='' border="0"
                    src="./images/add.gif" height="30"></a></td>
        </tr>
    </table>
</form>

Java代码:

            FileItemIterator iter = upload.getItemIterator(request);
            while (iter.hasNext()) {
                FileItemStream item = iter.next();
                if (item.isFormField()) {
                    continue;
                } else {
                        filename = item.getName();
                        contentType = item.getContentType();
                        String inputLine;
                        InputStream fis = item.openStream();
                        BufferedReader in = null;
                        in = new BufferedReader(new InputStreamReader(fis,"ISO-8859-1"));
                        while ((inputLine = in.readLine()) != null) {
                            try{
                                out.println("*"+inputLine+"*<br>");
                            }
                            catch (Exception e){
                                out.println("<p>Error: <b>"+e.getMessage() + "</b></p>");
                            }
                        }
                        fis.close();
                }
            }

我可以看到它读取文件,但在使用 Firefox 74+ 时失败。

可以在此消息下方找到错误堆栈跟踪。

使用 Firefox 73 或更低版本时,一切正常。

直接连接到 Tomcat 端口(不使用 AJP 连接器)时,一切正常(包括使用 Firefox 74/75)。

代码已经使用了十多年。 Java编码、Apache和Tomcat最近没有修改过。

Server version: Apache/2.4.43 (Linux/SUSE)

我注意到保存的“临时”文件总是被剪切为 188416 字节(而上传的文件实际上更大)。

csimon@linux-069t:/tomcat/temp> l
total 376
drwxr-xr-x 2 csimon users   4096 may  1 10:53 ./
drwxr-xr-x 9 csimon users   4096 ago 29  2018 ../
-rw-r--r-- 1 csimon users 188416 may  1 10:45 EMP59_AF_GA_202005011.CSV
-rw-r--r-- 1 csimon users 188416 may  1 10:37 EMP59_AF_GA_20200501.CSV

生产用户报告了问题,但我可以在本地重现它。

只有使用 Firefox 74 和 75 才会出现此问题(我使用 Firefox 71 -> 75 进行测试),因此它一定与 Firefox 中的某些更改有关(至少 Linux 和 Windows 版本)。我在 Firefox 发行说明中找不到解释。 任何人都知道可能导致此问题的原因以及如何解决此问题。

我过去已经遇到过 Firefox 升级相关的问题,通常是通过“about:config”更改 Firefox 配置中的某些值来修复。诀窍是找到正确的参数来更新...

使用 Firefo 74+ 时来自 AJP 连接器日志的错误日志:

[Sat May 02 18:27:55.801 2020] [15619:139986498496512] [info] init_jk::mod_jk.c (3591): mod_jk/1.2.46 initialized
[Sat May 02 18:27:55.805 2020] [15619:139986498496512] [info] init_jk::mod_jk.c (3591): mod_jk/1.2.46 initialized
[Sat May 02 18:28:02.669 2020] [15641:139986189342464] [info] ajp_process_callback::jk_ajp_common.c (2074): (ajp13) Writing to client aborted or client network problems
[Sat May 02 18:28:02.669 2020] [15641:139986189342464] [info] ajp_service::jk_ajp_common.c (2775): (ajp13) sending request to tomcat failed (unrecoverable), because of client write error (attempt=1)
[Sat May 02 18:28:02.670 2020] [15641:139986189342464] [info] jk_handler::mod_jk.c (2984): Aborting connection for worker=ajp13
[Sat May 02 18:28:15.289 2020] [15641:139986189342464] [info] ajp_read_into_msg_buff::jk_ajp_common.c (1550): (ajp13) receiving data from client failed. Connection aborted or network problems
[Sat May 02 18:28:15.289 2020] [15641:139986189342464] [info] ajp_process_callback::jk_ajp_common.c (2102): (ajp13) Reading from client aborted or client network problems
[Sat May 02 18:28:15.289 2020] [15641:139986189342464] [info] ajp_service::jk_ajp_common.c (2775): (ajp13) sending request to tomcat failed (unrecoverable), because of client read error (attempt=1)
[Sat May 02 18:28:15.310 2020] [15641:139986189342464] [info] jk_handler::mod_jk.c (2984): Aborting connection for worker=ajp13

使用 Firefox 74+ 时 Tomcat 错误堆栈跟踪:

java.io.IOException: Fallo en lectura de Conector
    at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:313)
    at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:364)
    at org.apache.coyote.ajp.AjpProcessor.receive(AjpProcessor.java:331)
    at org.apache.coyote.ajp.AbstractAjpProcessor.refillReadBuffer(AbstractAjpProcessor.java:662)
    at org.apache.coyote.ajp.AbstractAjpProcessor$SocketInputBuffer.doRead(AbstractAjpProcessor.java:1140)
    at org.apache.coyote.Request.doRead(Request.java:422)
    at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290)
    at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:449)
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
    at com.oreilly.servlet.multipart.BufferedServletInputStream.fill(BufferedServletInputStream.java:64)
    at com.oreilly.servlet.multipart.BufferedServletInputStream.readLine(BufferedServletInputStream.java:108)
    at com.oreilly.servlet.multipart.LimitedServletInputStream.readLine(LimitedServletInputStream.java:60)
    at com.oreilly.servlet.multipart.PartInputStream.fill(PartInputStream.java:97)
    at com.oreilly.servlet.multipart.PartInputStream.read(PartInputStream.java:195)
    at com.oreilly.servlet.multipart.PartInputStream.read(PartInputStream.java:156)
    at com.oreilly.servlet.multipart.FilePart.write(FilePart.java:208)
    at com.oreilly.servlet.multipart.FilePart.writeTo(FilePart.java:167)
    at com.oreilly.servlet.MultipartRequest.<init>(MultipartRequest.java:271)
    at servlet.presentacion.admin.AdminImportInssAseg.doPost(AdminImportInssAseg.java:101)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:193)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

标题 Firefox 版本 72: enter image description here

标题 Firefox 版本 75: enter image description here

最佳答案

使用 com.oreilly.servlet.MultipartRequest 失败。 使用 org.apache.commons.fileupload 失败。

使用 Java Servlet 技术使其工作将 maxFileSize 设置得更高(默认值为 2MB)。

我不明白为什么它适用于旧版本的 Firefox 而不适用于新版本......但我的问题已经解决了。

@WebServlet("/AdminImportInssAseg")
@MultipartConfig (fileSizeThreshold=1024*1024*10,   // 1 MB 
     maxFileSize=1024*1024*50,          // 50 MB
     maxRequestSize=1024*1024*100)      // 100 MB
public class AdminImportInssAseg extends HttpServlet {

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException,
        IOException {
        Part filePart = request.getPart("miadjuntoSolvenciaX"); // Retrieves <input type="file" name="file">
        filename = filePart.getName();
        fileSize = filePart.getSize();
        contentType = filePart.getContentType();
        InputStream fis = filePart.getInputStream();
        BufferedReader in = null;
        in = new BufferedReader(new InputStreamReader(fis,"ISO-8859-1"));
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
        ...
        }           
        fis.close();
        filePart.delete();
  }
}

关于从 Firefox 74/75 发布 multipart/form-data 并在服务器端使用 Apache AJP 连接器时出现 java.io.IOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61547312/

相关文章:

java - Spring bean 的单例实现

linux - Apache错误“服务器似乎很忙”

javascript - Bootstrap : How to set a viewport to lg even if real screen is smaller ("Classic View")

apache - Coldfusion 11 REST 服务适用于 HTTP 但不适用于 HTTPS (404)

java - 升级到 struts 2.3.15.1 不会在操作类上设置 HashMap 值

javascript - 为什么 Eclipse 提示我的 javascript 中缺少分号?

java - 重写 BeforeClass 方法正在停止整个测试执行

java - setElevation 不显示阴影

java - DateTimeFormatter 的最后一位年份

apache - Ajax 和管理请求通过输入 mod-rewrite 规则停止运行