2010-07-16 1 views
5

Ну, я должен сказать, что до сих пор этот меня смутил. Наше веб-приложение, работающее в Tomcat 6.0.18, терпит неудачу во время загрузки файла, но только тогда, когда клиентская машина является машиной Windows, только для некоторых машин и для всех браузеров, а не только для IE.Загрузка файла Apache Commons - Поток закончился неожиданно

В журналах есть трассировка стека, которая, как представляется, указывает на то, что клиент либо закрыл соединение, либо поток был каким-то образом поврежден. Корневая причина в трассировке стека указана следующим образом:

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, в каком-то образом испорчены.

Я думаю, что нашел что-то that may be related на StackOverflow. Кажется, что в Tomcat 6 есть ошибка, которая была исправлена ​​в версии 6.0.20, чуть более высокой версии, чем та, которую мы используем. К сожалению, он не упоминает, что такое проблема. У меня есть had a look в журнале изменений Tomcat, но я не вижу потенциальных кандидатов на ошибку, которая может вызвать эту проблему.

В любом случае, по моему фактическому вопросу, кто-нибудь сталкивался с подобной проблемой, и если да, то в чем была основная проблема и как вы ее разрешили?

Заранее благодарю за любые ответы.

РЕДАКТИРОВАТЬ: Это, по-видимому, какая-то проблема с балансировкой нагрузки и Tomcat. Если вы обойдете балансировщик нагрузки и сразу подключитесь к Tomcat через IP-адрес сервера, проблема исчезнет. Странно, что это проявляется в нашей промежуточной среде, в которой мы используем Apache/AJP1.3 и live, где мы используем Zeus.

EDIT3: Это оказалось проблемой с брандмауэром клиентов. Похоже, что они были ... не совсем правдивыми, когда говорили, что они точно знают, что это не проблема с брандмауэром.

+0

Вы хотели бы подробно рассказать о том, что проблема была именно в ответе на этот вопрос? – MattC

+0

Мэтт, извините, но я точно не знаю, что такое проблема с брандмауэром. Мы просто связались с клиентом post-Firewall-fix и сообщили, что это проблема с брандмауэром. – Jon

ответ

1

Может быть, вам нужно tcpdump/wireshark плохо и правильно загружать, а затем сравнить их?

+0

Да, мы действительно пробовали это с Wireshark, что, честно говоря, у меня мало опыта в интерпретации. Это осложнилось тем, что проблема была периодической и трудно воспроизводимой. В любом случае он оказался брандмауэром. – Jon