简体   繁体   English

Apache Commons文件上传 - Stream意外结束

[英]Apache Commons File Upload - Stream ended unexpectedly

Well, I have to say that so far, this one has me stumped. 好吧,我不得不说到目前为止,这个让我难过。 Our web application, which is running in Tomcat 6.0.18 is failing during file upload, but only when the client machine is a windows machine, only for some machines, and for all browsers, not just IE . 我们在Tomcat 6.0.18中运行的Web应用程序在文件上载期间失败,但仅当客户端计算机是Windows计算机时,仅适用于某些计算机,并且适用于所有浏览器,而不仅仅是IE

There is a stack trace in the logs, which seems to indicate that the client either closed the connection, or the stream was somehow corrupted. 日志中有一个堆栈跟踪,这似乎表明客户端关闭了连接,或者流以某种方式被破坏。 The root cause in the stack trace is given as follows: 堆栈跟踪的根本原因如下:

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

The code which causes the trace looks fairly straight forward. 导致跟踪的代码看起来相当直接。

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;
}

The line which is giving us the grief is this one: 让我们感到悲伤的是这一行:

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

Which for some reason is deciding that streams from some Windows machines are in some way corrupted. 由于某种原因,决定来自某些Windows机器的流在某种程度上被破坏了。

I think I have found something that may be related on StackOverflow. 我想我已经找到了可能与 StackOverflow 相关的东西。 It seems to suggest there is some bug in Tomcat 6 which was fixed in version 6.0.20, a slightly higher version than the one we're using. 它似乎表明Tomcat 6中存在一些错误,它在版本6.0.20中得到修复,比我们使用的版本略高。 Unfortunately it doesn't mention what the issue itself was. 不幸的是,它没有提到问题本身是什么。 I've had a look at the Tomcat changelog, but can't see any likely candidates for a bug which could cause this problem. 我已经看过 Tomcat更改日志了,但看不到任何可能导致此问题的bug的候选者。

Anyway, on to my actual question, has anyone encountered a similar problem, and if so, what was the underlying issue and how did you resolve it? 无论如何,就我的实际问题而言,是否有人遇到类似问题,如果是,那么根本问题是什么?你是如何解决它的?

Thank you in advance for any responses. 提前感谢您的任何回复。

EDIT: This appears to be some kind of problem with load balancing and Tomcat. 编辑:这似乎是负载平衡和Tomcat的某种问题。 If you bypass the load balancer and access Tomcat directly via the server IP address, the problem goes away. 如果绕过负载均衡器并通过服务器IP地址直接访问Tomcat,问题就会消失。 The strange thing is that this appears in both our staging environment, in which we use Apache/AJP1.3, and live, where we use Zeus. 奇怪的是,这出现在我们使用Apache / AJP1.3的暂存环境中,以及我们使用Zeus的直播环境。

EDIT3: This turned out to be an issue with the clients firewall. 编辑3:这结果是客户端防火墙的问题。 It appears that they were.. er.. not being entirely truthful when they said that the knew definitely this was not a Firewall issue. 看来他们是......呃..当他们说明确知道这不是防火墙问题时,并不是完全真实的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM