从Firefox 74/75发布多部分/表单数据并在服务器端使用Apache AJP连接器时出现java.io.IOException [英] java.io.IOException when posting multipart/form-data from Firefox 74 / 75 and using Apache AJP connector on server side

查看:85
本文介绍了从Firefox 74/75发布多部分/表单数据并在服务器端使用Apache AJP连接器时出现java.io.IOException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Firefox 74版本开始,使用"multipart/form-data"表单发送的文件大小超过1.8 MB的文件引发了错误.

Since version 74 of Firefox, file sent using "multipart/form-data" form with file size above about 1.8 MB are raising error.

注意:使用AJAX发送的文件运行正常.只有多部分表单提交才引起问题.

Note: file sent using AJAX are working fine. Only multipart form submit cause the issue.

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+时,文件却在中间失败了.

I can see it reads the file, but fails in the middle of it when using Firefox 74+.

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

Error stack trace can be found below this message.

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

When using Firefox 73 or lower everything works fine.

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

When connecting directly to Tomcat port (not using AJP connector), everything works fine (inlcuding with Firefox 74/75).

代码已经使用了十多年. Java编码,Apache和Tomcat最近尚未修改.

Code has been used for more than a decade. Java coding, Apache and Tomcat have not been modified recently.

Server version: Apache/2.4.43 (Linux/SUSE)

我注意到保存的临时"文件总是被切成188416字节(而上传的文件实际上更大).

I noticed that the "temporary" file saved is always cut at 188416 bytes (while the uploaded file is actually bigger).

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

问题是由生产用户报告的,但是我可以在本地复制它.

Issue was reported by a production user, but I could reproduce it locally.

仅使用 Firefox 74和75 会导致此问题(我在Firefox 71-> 75上进行了测试),因此它必须与Firefox中的某些更改链接(至少是Linux和Windows版本).在Firefox发行说明中找不到解释. 任何人都知道可能导致此问题的原因以及如何解决此问题.

Only the use of Firefox 74 and 75 causes the problem (I tested with Firefox 71 -> 75), so it must be linked to some change in Firefox (Linux and Windows versions at least). I could not find explanation looking at Firefox release notes. Anyone getting ideas of what could cause this and how this can be fixed.

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

I have already had Firefox upgrade related issues in the past, usually fixed changing some values in Firefox config via "about:config". The trick is finding the right parameter to update...

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

Error log from AJP connector log when using Firefo 74+:

[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错误堆栈跟踪:

Tomcat error stack trace when using Firefox 74+:

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:

Header Firefox version 72:

标题Firefox版本75:

Header Firefox version 75:

推荐答案

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

Was failing using com.oreilly.servlet.MultipartRequest. Was failing using org.apache.commons.fileupload.

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

Got it working using Java Servlet Technology and setting maxFileSize higher (default is 2MB).

我不明白为什么它可以与旧版本的Firefox兼容,而不能与新版本的Firefox兼容...但是我的问题已解决.

I can't understand why it works with old versions of Firefox and not with new ones... but my problem is solved.

@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发布多部分/表单数据并在服务器端使用Apache AJP连接器时出现java.io.IOException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆