【问题标题】:Apache Commons File Upload - Stream ended unexpectedlyApache Commons 文件上传 - 流意外结束
【发布时间】:2011-03-16 21:10:34
【问题描述】:

嗯,我不得不说,到目前为止,这个让我很难过。我们在 Tomcat 6.0.18 中运行的 Web 应用程序在文件上传期间失败,但仅当客户端机器是 Windows 机器时,仅适用于某些机器,适用于所有浏览器,而不仅仅是 IE

日志中有一个堆栈跟踪,这似乎表明客户端关闭了连接,或者流以某种方式损坏。堆栈跟踪中的根本原因如下:

Caused by: org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:983)
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:887)
    at java.io.InputStream.read(InputStream.java:85)
    at org.apache.commons.fileupload.util.Streams.copy(Streams.java:94)
    at org.apache.commons.fileupload.util.Streams.copy(Streams.java:64)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:362)
    ... 70 more

导致跟踪的代码看起来相当简单。

private Map<String, Object> getMap( ActionRequest request ) {

    HashMap<String, Object> parameters = new HashMap<String, Object>();
    if ( request == null ) {
        return parameters;
    }

    if ( request.getContentType() == null ) {
        return parameters;
    }

    try {
        if(PortletFileUpload.isMultipartContent(request)){
            DiskFileItemFactory factory = new DiskFileItemFactory();
            PortletFileUpload upload = new PortletFileUpload(factory);
            List<DiskFileItem> fileItems = upload.parseRequest(request);
            for( DiskFileItem fileItem : fileItems ) {
                String name = fileItem.getFieldName();
                //now set appropriate variable, populate hashtable
                if( fileItem.isFormField() ) {
                    String value = fileItem.getString( request.getCharacterEncoding() );
                    if( parameters.get( name ) == null ) {
                        String[] values = new String[1];
                        values[0] = value;
                        parameters.put( name, values );
                    } else {
                        Object prevobj = parameters.get( name );
                        if( prevobj instanceof String[] ) {
                            String[] prev = ( String[] ) prevobj;
                            String[] newStr = new String[prev.length + 1];
                            System.arraycopy(
                                    prev, 0, newStr, 0,
                                    prev.length
                            );
                            newStr[prev.length] = value;
                            parameters.put( name, newStr );
                        } else {
                            //now what? I think this breaks the standard.
                            throw new EatMyHatException(
                                    "file and input field with same name?"
                            );
                        }
                    }
                } else {
                    // Yes, we don't return FileParameter[] for multiple files of same name.  AFAIK, that's not allowed.
                    FileParameter fp = new FileParameter( fileItem );
                    parameters.put( name, fp );
                    files.add( fp );
                }
            }
        } else {
            // Not multipart
            return toObjectMap(request.getParameterMap());
        }
    } catch (FileUploadException e) {
        throw new RuntimeException(e);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    }
    return parameters;
}

让我们感到悲伤的是这一行:

List<DiskFileItem> fileItems = upload.parseRequest(request);

出于某种原因,这决定了来自某些 Windows 机器的流在某种程度上已损坏。

我想我在 StackOverflow 上找到了 that may be related 的东西。似乎表明 Tomcat 6 中存在一些错误,该错误已在版本 6.0.20 中修复,比我们使用的版本略高。不幸的是,它没有提到问题本身是什么。我在 Tomcat 更改日志中已had a look,但看不到任何可能导致此问题的错误的候选者。

无论如何,关于我的实际问题,有没有人遇到过类似的问题,如果有,根本问题是什么?您是如何解决的?

提前感谢您的任何回复。

编辑:这似乎是负载平衡和 Tomcat 的某种问题。如果您绕过负载均衡器并直接通过服务器 IP 地址访问 Tomcat,问题就会消失。奇怪的是,这出现在我们使用 Apache/AJP1.3 的暂存环境和使用 Zeus 的生活环境中。

EDIT3:这原来是客户端防火墙的问题。当他们说他们肯定知道这不是防火墙问题时,他们似乎.. er.. 并不完全真实。

【问题讨论】:

  • 您是否愿意在回答此问题时详细说明问题所在?
  • 马特,对不起,我不知道防火墙问题到底是什么。客户在防火墙修复后与我们联系并告知这是防火墙问题。

标签: java apache file-upload upload tomcat6


【解决方案1】:

可能你需要 tcpdump/wireshark 错误和正确的上传,然后比较它们?

【讨论】:

  • 是的,我们确实用 Wireshark 尝试过这个,老实说,我没有什么解释经验。由于问题是间歇性的并且难以重现,因此变得更加困难。无论如何,它原来是防火墙。
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 2014-03-19
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 2016-10-02
  • 2023-03-15
  • 1970-01-01
相关资源
最近更新 更多