Bueno, tengo que decir que hasta ahora, esta me ha dejado perplejo. Nuestra aplicación web, que se ejecuta en Tomcat 6.0.18 está fallando durante la carga de archivos, pero solo cuando la máquina cliente es una máquina de Windows, solo para algunas máquinas y para todos los navegadores, no solo IE.Apache Commons File Upload - La transmisión terminó inesperadamente
Hay un seguimiento de pila en los registros, lo que parece indicar que el cliente cerró la conexión o que la ruta se corrompió de alguna manera. La causa raíz en el seguimiento de la pila se da de la siguiente manera:
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
El código que causa la traza parece bastante sencillo.
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 línea que nos está dando el dolor es ésta:
List<DiskFileItem> fileItems = upload.parseRequest(request);
que por alguna razón se decidió que fluye de algunas máquinas Windows son de alguna manera dañado.
Creo que he encontrado algo that may be related en StackOverflow. Parece sugerir que hay algún error en Tomcat 6 que se corrigió en la versión 6.0.20, una versión ligeramente más alta que la que estamos usando. Lamentablemente, no menciona cuál fue el problema en sí. Tengo had a look en el registro de cambios de Tomcat, pero no veo ningún posible candidato para un error que pueda causar este problema.
De todos modos, en mi pregunta real, ¿alguien ha encontrado un problema similar y, de ser así, cuál fue el problema subyacente y cómo lo resolvió?
Gracias de antemano por cualquier respuesta.
EDITAR: Esto parece ser algún tipo de problema con el equilibrio de carga y Tomcat. Si omite el equilibrador de carga y accede a Tomcat directamente a través de la dirección IP del servidor, el problema desaparece. Lo extraño es que esto aparece tanto en nuestro entorno de ensayo, en el que usamos Apache/AJP1.3, y en vivo, donde usamos Zeus.
EDIT3: Esto resultó ser un problema con el firewall de los clientes. Parece que estaban ... eh ... no siendo del todo veraces cuando dijeron que sabían definitivamente que esto no era un problema de Firewall.
¿Estaría dispuesto a detallar el problema exactamente en la respuesta a esta pregunta? – MattC
Matt, lo siento, pero no sé exactamente cuál fue el problema del Firewall. Fuimos simplemente contactados por el cliente después de la reparación de Firewall e informados de que ha sido un problema de Firewall. – Jon