I got a form belonging to a web app that contains a "file" field to upload a pdf file.( spring 3 environment, multipart file upload) Uploading file works fine in test environnement (all browsers), and only works with Firefox in production environment (file upload cause connection reset exception with low internet connection client browser especially)
The following exception is thrown a few seconds after submit button is pressed : ( browser is IE/Chrome running in windows environment but not Firefox)
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:162)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:138)
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:887)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:750)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:162)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:110)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at fr.ifma.utils.FiltreUTF8.doFilter(FiltreUTF8.java:21)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:371)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:155)
... 38 more
Caused by: java.io.IOException
at org.apache.jk.common.JkInputStream.receive(JkInputStream.java:205)
at org.apache.jk.common.JkInputStream.refillReadBuffer(JkInputStream.java:265)
at org.apache.jk.common.JkInputStream.doRead(JkInputStream.java:183)
at org.apache.coyote.Request.doRead(Request.java:427)
at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:304)
at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:419)
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:327)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:193)
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:976)
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:886)
at java.io.InputStream.read(InputStream.java:82)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:96)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:66)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:366)
... 40 more
24 oct. 2012 10:40:38 org.apache.jk.core.MsgContext action
ATTENTION: Unable to send headers
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.jk.common.ChannelSocket.send(ChannelSocket.java:539)
at org.apache.jk.common.JkInputStream.appendHead(JkInputStream.java:324)
at org.apache.jk.core.MsgContext.action(MsgContext.java:266)
at org.apache.coyote.Response.action(Response.java:183)
at org.apache.coyote.Response.sendHeaders(Response.java:379)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:314)
at org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java:274)
at org.apache.catalina.connector.CoyoteWriter.close(CoyoteWriter.java:108)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:394)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:162)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:110)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at fr.ifma.utils.FiltreUTF8.doFilter(FiltreUTF8.java:21)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:662)
24 oct. 2012 10:40:38 org.apache.jk.common.ChannelSocket processConnection
Here is the web app code and configuration :
spring multipart resolver configuration :
Controller :
/**
* this controller handles file upload and save files to dao.
* @author Christophe.Dumonet@ifma.fr
* @param request
* @param documentFormBean
* @param result
* @param file
* @return
*/
@RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView save(HttpServletRequest request,
@Valid DocumentFormBean documentFormBean,BindingResult result,
@RequestParam("file") MultipartFile file) {
ResourceBundle bundle = ResourceBundle.getBundle("messages", request.getLocale());
Map<String,Object> map = new HashMap<String, Object>();
map.put("documentFormBean", new DocumentFormBean());
map.put("documentList", documentDao.findAllForaDepot(Long.parseLong((String) request.getParameter("depot"))));
map.put("depot", depotDao.find(Long.parseLong((String) request.getParameter("depot"))));
//Handle too many documents attached : how many documents attached to this depot now ? throw an error to UI.
@SuppressWarnings("rawtypes")
List documentAttached = documentDao.findAllForaDepot(Long.parseLong((String) request.getParameter("depot")));
if (documentAttached != null && documentAttached.size() >= Integer.parseInt(SpringPropertiesUtil.getProperty("Depot.maximum.file.number.authorized"))){
map.put("MaximumFileNumberReached", bundle.getString("Depot.maximum.file.number.errormessage"));
return new ModelAndView("ajoutDocumentsRapport", map);
}
//handle file empty or not pdf
if (result.hasErrors() || (file.isEmpty()) || !file.getContentType().contains("pdf")) {
map.put("errors", result);
if (file.isEmpty()) map.put("ErrorMessageFileEmpty", bundle.getString("view.addrapport.error.fileisempty"));
if (!file.getContentType().contains("pdf")) map.put("ErrorMessageFileTypeNotPDF", bundle.getString("view.addrapport.error.filetype.onlypdf"));
return new ModelAndView("ajoutDocumentsRapport", map);
} else{
try {
//Blob blob = Hibernate.createBlob(file.getInputStream());
//cause Hibernate.createBlob is deprecated, use a LobHelper interface instead.
org.hibernate.Session se = (org.hibernate.Session)depotDao.getHibernateTemplate().getSessionFactory().getCurrentSession();
LobHelper lh = se.getLobHelper();
Blob blob = lh.createBlob(file.getBytes());
Document newDocument = new Document();
newDocument.setDescription(documentFormBean.getDescription());
newDocument.setContentType(file.getContentType());
newDocument.setFilename(file.getOriginalFilename());
newDocument.setContent(blob);
newDocument.setDepot(depotDao.find(Long.parseLong((String) request.getParameter("depot"))));
documentDao.save(newDocument);
map.put("documentList", documentDao.findAllForaDepot(Long.parseLong((String) request.getParameter("depot"))));
} catch (IOException e) {
e.printStackTrace();
}
return new ModelAndView("ajoutDocumentsRapport",map);
}
}
Tomcat 6 AJP connector connector configuration : (Original configuration was : )
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
(also tried with this one : )
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
connectionTimeout="120000" maxThreads="1000"
minSpareThreads="50" maxSpareThreads="100" enableLookups="false"
acceptCount="150" address="127.0.0.1"
useBodyEncodingForURI="true"
compression="on"
compressionMinSize="1024"
compressableMimeType="text/html,text/xml"
connectionUploadTimeout="3600000"
disableUploadTimeout="true"
/>
Apache 2 virtual host configuration :
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
Timeout 3600
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
ProxyTimeout 3600
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Directory /var/www/>
Options -Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Html form :
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@ taglib uri="http://displaytag.sf.net" prefix="display"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<base
href="<%=request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + request.getContextPath()
+ "/"%>" />
<link href="css/style1.css" rel="stylesheet" type="text/css" />
<link href="css/style.css" rel="stylesheet" type="text/css" />
<link type="text/css" rel="stylesheet" href="css/solid.css" />
<link type="text/css" rel="stylesheet" href="css/errors.css" />
<script type="text/javascript" src="script/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="script/jquery.validate.js"></script>
</head>
<body>
<form:form id="myform" method="post" action="save.html" commandName="documentFormBean" enctype="multipart/form-data">
<c:set var="depot" value="${depot.id}" scope="session" />
<input type="hidden" name="depot" value="${depot.id}" />
<table id="gradient-style">
<tr>
<th colspan="8"><h3>Fichiers joints au rapport</h3>
</th>
</tr>
<tr><td>->Ajouter un document</td>
<td><form:textarea path="description" />
<br/>
<span style="color:red">*</span>description du fichier
<form:errors path="description" cssClass="error" />
</td>
<td colspan="3">
<input type="file" name="file" />
<br/><span class="error" >${ErrorMessageFileEmpty}</span>
<br/><span class="error" >${ErrorMessageFileTypeNotPDF}</span>
<br/><span class="error" >${MaximumFileNumberReached}</span>
</td>
<td colspan="3"><input type="submit" id="upload" value="Ajouter le document" /></td>
</tr>
<tr > <td colspan="8"> <div style="color:red">Attention : le document doit comporter obligatoirement une description et un fichier PDF (taille maximum : 20Mo) </div></td></tr>
<tr > <td colspan="8"> <div >Note : Si vous le déposant n'est pas autorisé à publier son rapport pour des raisons de confidentialité, déposer simplement la page de garde en pdf du rapport </div></td></tr>
</table>
<span class="error">${msg}</span>
<c:if test="${!empty documentList}">
Liste des documents associés au rapport :
<table id="gradient-style">
<tr>
<th>Description</th>
<th>Nom du fichier</th>
<th>type de contenu</th>
<th>Télécharger</th>
<th>Supprimer</th>
</tr>
<c:forEach items="${documentList}" var="document">
<tr>
<td width="250px">${document.description}</td>
<td width="250px">${document.filename}</td>
<td width="250px">${document.contentType}</td>
<td width="20px"><a
href="${pageContext.request.contextPath}/download/${document.id}.html"
target="_blank"><img
src="${pageContext.request.contextPath}/images/save-icon.jpg"
width="20px" height="20px"
border="0" title="Download this document" />Télécharger</a>
</td>
<td width="20px"><a
href="${pageContext.request.contextPath}/remove/document/${document.id}/depot/${depot.id}.html"
onclick="return confirm('Etes vous certain de vouloir supprimer ce fichier ?')"><img
width="20px" height="20px" src="${pageContext.request.contextPath}/images/delete-icon.jpg"
border="0" title="Delete this document" />Supprimer</a></td>
</tr>
</c:forEach>
</table>
</c:if>
<script>
function disp_warning()
{
alert("Vous devez ajouter au moins un document SVP !")
}
</script>
<table id="gradient-style">
<tr>
<th colspan="6">
<c:choose>
<c:when test="${fn:length(documentList) gt 0}">
<button type="button" onclick="location.href='endAdd.html'"><spring:message code="application.add.end.title"/> </button>
</c:when>
<c:otherwise>
<button type="button" onclick="disp_warning()"><spring:message code="application.add.end.title"/></button>
</c:otherwise>
</c:choose>
</th>
</tr>
</table>
</form:form>
</body>
</html>
What could be the possible reasons for this exception?
Connection reset on file upload usually means the client aborted sending...so what ?
Any Help would be appreciate.
Christophe D.
Can you capture tcpdump between the client and server and see who is resetting the connection. We had a similar issue in our application and it was a firewall which was dropping the connection. There was another setting in apache [LimitRequestBody] which was aborting the upload after the file upload reached that limit. The logs from apache and mod-jk in these two cases were not that much clear to debug in these scenarios.