Eh bien, je dois dire que jusqu'à présent, celui-ci m'a perplexe. Notre application Web, qui s'exécute dans Tomcat 6.0.18 est défaillante lors du téléchargement de fichiers, mais uniquement lorsque l'ordinateur client est une machine Windows, uniquement pour certaines machines, et pour tous les navigateurs, pas seulement IE.Apache Commons File Upload - Stream terminé de façon inattendue
Il existe une trace de pile dans les journaux, ce qui semble indiquer que le client a soit fermé la connexion, soit corrompu le flux. La cause première de la trace de la pile est la suivante:
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
Le code qui provoque la trace semble assez simple.
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;
}
La ligne qui nous donne la douleur est celle-ci:
List<DiskFileItem> fileItems = upload.parseRequest(request);
Ce qui pour une raison quelconque est de décider que les flux de certaines machines Windows sont en quelque sorte corrompu.
Je pense que j'ai trouvé quelque chose that may be related sur StackOverflow. Il semble suggérer qu'il y a un bug dans Tomcat 6 qui a été corrigé dans la version 6.0.20, une version légèrement supérieure à celle que nous utilisons. Malheureusement, cela ne mentionne pas le problème lui-même. J'ai had a look sur le changelog de Tomcat, mais je ne vois pas de candidats potentiels pour un bug qui pourrait causer ce problème.
De toute façon, à ma question actuelle, quelqu'un a-t-il rencontré un problème similaire, et si oui, quel était le problème sous-jacent et comment l'avez-vous résolu?
Merci d'avance pour vos réponses.
EDIT: Cela semble être une sorte de problème avec l'équilibrage de charge et Tomcat. Si vous ignorez l'équilibreur de charge et accédez directement à Tomcat via l'adresse IP du serveur, le problème disparaît. La chose étrange est que cela apparaît à la fois dans notre environnement de mise en scène, dans lequel nous utilisons Apache/AJP1.3, et en direct, où nous utilisons Zeus.
EDIT3: Cela s'est avéré être un problème avec le pare-feu des clients. Il semble qu'ils étaient .. euh .. ne pas être entièrement véridiques quand ils ont dit que le savait certainement ce n'était pas un problème de pare-feu.
Seriez-vous prêt à préciser quel était exactement le problème dans une réponse à cette question? – MattC
Matt, je suis désolé, mais je ne sais pas exactement quel était le problème du pare-feu. Nous avons simplement été contactés par le client après la correction du pare-feu et informés qu'il s'agissait d'un problème de pare-feu. – Jon