web-dev-qa-db-fra.com

Échec du traitement de la requête multipart / form-data. Lecture expirée

D'autres questions sur Stack Overflow ont répondu à cette question, mais aucune des réponses fournies ne m'a aidé à résoudre le problème.

J'essaie de télécharger un fichier de 10 à 16 Mo à partir d'une applet à l'aide d'Apache HTTP Commons. Tout fonctionne bien dans mon environnement local.

Je reçois l'exception suivante uniquement sur mon serveur de production (Tomcat 6.0, https://www.dailyrazor.com/ ), quelle que soit la taille du fichier:

org.Apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. Read timed out
    at org.Apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.Java:384)
    at org.Apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.Java:116)
    at com.actura.helper.UploadHelper.processUpload(UploadHelper.Java:92)
    at com.actura.voice.upload.FileUploadServlet.process(FileUploadServlet.Java:85)
    at com.actura.voice.upload.FileUploadServlet.doPost(FileUploadServlet.Java:75)
    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.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:298)
    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:769)
    at org.Apache.jk.common.ChannelSocket.processConnection(ChannelSocket.Java:698)
    at org.Apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.Java:891)
    at org.Apache.Tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.Java:690)
    at Java.lang.Thread.run(Thread.Java:662)

Voici le journal de débogage de Commons IO:

2012-Sep-18 11:26:28,446 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory constructor (listener) 
2012-Sep-18 11:26:28,794 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:26:28,800 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:26:28,800 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:26:28,802 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:26:28,803 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:26:28,804 [TP-Processor5] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
 processing folder... /home/dixieh83/public_html/ActuraVoiceRecorderDemo/temp
2012-Sep-18 11:27:47,062 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory constructor (listener) 
2012-Sep-18 11:27:47,461 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:27:47,461 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:27:47,462 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItemFactory 
  DEBUG inside MonitoredDiskFileItemFactory createItem 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside MonitoredDiskFileItem constructor 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG inside getOutputStream() 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG inside MonitoredOutputStream constructor 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredOutputStream 
  DEBUG leaving MonitoredOutputStream contructor 
2012-Sep-18 11:27:47,463 [TP-Processor4] com.actura.voice.upload.MonitoredDiskFileItem 
  DEBUG leaving getOutputStream() 

À part ce problème de téléchargement, mon applet fonctionne très bien.

Voici la configuration du serveur telle que décrite dans le fichier server.xml De mon serveur de production:

<!-- Define an AJP 1.3 Connector on port 8009 --> <Connector address="127.0.0.1" port="9609" enableLookups="false" protocol="AJP/1.3" connectionTimeout="30000" maxThreads="50" minSpareThreads="1" maxSpareThreads="3" disableUploadTimeout="true" /> 

La vitesse de ma connexion Internet est correcte (2,01 Mbps vers le bas et 0,42 Mbps vers le haut), donc cette exception me laisse perplexe. J'ai déjà défini connectionTimeOut sur 3000000, mais j'ai quand même l'exception. Dois-je définir connectionTimeOut sur -1 pour le rendre illimité?

Les autorisations de fichier sont définies sur 777 Dans le répertoire à partir duquel je télécharge et j'utilise JDK version 7 pour exécuter l'applet dans le navigateur.

Sortie console Java:

Java Plug-in 10.7.2.10
Using JRE version 1.7.0_07-b10 Java HotSpot(TM) Client VM

Lorsque le téléchargement échoue, je l'obtiens dans la console:

Java.net.SocketException: Connection reset by peer: socket write error
    at Java.net.SocketOutputStream.socketWrite0(Native Method)
    at Java.net.SocketOutputStream.socketWrite(Unknown Source)
    at Java.net.SocketOutputStream.write(Unknown Source)
    at org.Apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.Java:169)
    at org.Apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.Java:119)
    at org.Apache.http.entity.mime.content.InputStreamBody.writeTo(InputStreamBody.Java:70)
    at org.Apache.http.entity.mime.HttpMultipart.doWriteTo(HttpMultipart.Java:206)
    at org.Apache.http.entity.mime.HttpMultipart.writeTo(HttpMultipart.Java:224)
    at org.Apache.http.entity.mime.MultipartEntity.writeTo(MultipartEntity.Java:183)
    at org.Apache.http.entity.HttpEntityWrapper.writeTo(HttpEntityWrapper.Java:98)
    at org.Apache.http.impl.client.EntityEnclosingRequestWrapper$EntityWrapper.writeTo(EntityEnclosingRequestWrapper.Java:108)
    at org.Apache.http.impl.entity.EntitySerializer.serialize(EntitySerializer.Java:122)
    at org.Apache.http.impl.AbstractHttpClientConnection.sendRequestEntity(AbstractHttpClientConnection.Java:271)
    at org.Apache.http.impl.conn.ManagedClientConnectionImpl.sendRequestEntity(ManagedClientConnectionImpl.Java:197)
    at org.Apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.Java:257)
    at org.Apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.Java:125)
    at org.Apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.Java:712)
    at org.Apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.Java:517)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:906)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:1066)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:1044)
    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:1035)
    at com.actura.app.util.ApplicationUtil.uploadUsingApache(ApplicationUtil.Java:143)
    at com.actura.app.util.ApplicationUtil.saveWaveToServer(ApplicationUtil.Java:90)
    at com.actura.app.capture.RecorderUI.saveButtonActionPerformed(RecorderUI.Java:1856)
    at com.actura.app.capture.RecorderUI.access$17(RecorderUI.Java:1824)
    at com.actura.app.capture.RecorderUI$7.actionPerformed(RecorderUI.Java:1325)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at Java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at Java.awt.Component.processEvent(Unknown Source)
    at Java.awt.Container.processEvent(Unknown Source)
    at Java.awt.Component.dispatchEventImpl(Unknown Source)
    at Java.awt.Container.dispatchEventImpl(Unknown Source)
    at Java.awt.Component.dispatchEvent(Unknown Source)
    at Java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at Java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at Java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at Java.awt.Container.dispatchEventImpl(Unknown Source)
    at Java.awt.Component.dispatchEvent(Unknown Source)
    at Java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at Java.awt.EventQueue.access$200(Unknown Source)
    at Java.awt.EventQueue$3.run(Unknown Source)
    at Java.awt.EventQueue$3.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at Java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at Java.awt.EventQueue$4.run(Unknown Source)
    at Java.awt.EventQueue$4.run(Unknown Source)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at Java.awt.EventQueue.dispatchEvent(Unknown Source)
    at Java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at Java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at Java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at Java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at Java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at Java.awt.EventDispatchThread.run(Unknown Source)

j'ai appris que cela pourrait être un problème de mon FAI. Je me demande simplement si c'est le problème d'iSP pourquoi je peux facilement utiliser des logiciels comme temviewer et Skype ??

Voici le code qui effectue le téléchargement:

public static String uploadUsingApache(URL url, List<File> list,
            String userId, String accountId, String waveDuration)
            throws Exception {

        // The execution:
        DefaultHttpClient httpclient = new DefaultHttpClient();

        HttpPost method = new HttpPost(url.toString());

        MultipartEntity entity = new MultipartEntity();
        entity.addPart("userId", new StringBody(userId, Charset
                .forName("UTF-8")));
        entity.addPart(IVR_ACCOUNT_KEY, new StringBody(accountId, Charset
                .forName("UTF-8")));
        entity.addPart(IVR_MP3LEN_KEY, new StringBody(waveDuration, Charset
                .forName("UTF-8")));

        // FileBody fileBody = new FileBody(list.get(0));
        // entity.addPart("file", fileBody);

        for (File f : list) {

            byte[] imageBytes = fileToByteArray(f);
            entity.addPart("attachment_field", new InputStreamKnownSizeBody(
                    new ByteArrayInputStream(imageBytes), imageBytes.length,
                    "audio/wav", f.getName()));
            method.setEntity(entity);
        }

        ResponseHandler<String> responseHandler = new BasicResponseHandler();

        // HttpResponse response = httpclient.execute(method,responseHandler);
        String responseText = httpclient.execute(method, responseHandler);

        // error text
        if (responseText.contains("<exception>")) {
            responseText = responseText.replace("<exception>", "");
            responseText = responseText.replace("</exception>", "");
            throw new Exception(responseText);
        }

        // System.out.println(" Status " +response.getStatusLine());
        List<String> deleteList = Arrays.asList(responseText.split(","));

        StringBuffer sb = new StringBuffer();
        int cnt = 1;
        for (File f : list) {
            if (deleteList.contains(f.getName())) {
                sb.append(f.getName() + (cnt == deleteList.size() ? "" : ", "));
                f.delete();
                cnt++;
            }

        }

        if (deleteList.size() > 1) {
            sb.append(" are ");
        } else if (deleteList.size() == 1) {
            sb.append(" is ");
        } else {

        }

        sb.append(" successfully saved.");

        return sb.toString();
    }

Lorsque j'appuie sur le bouton de téléchargement sur l'interface graphique de mon applet, il appelle la méthode ci-dessus et en même temps, l'interface graphique se bloque. 10 à 50 secondes plus tard, le serveur lance le FileUploadException. La servlet informe l'applet de l'exception, mais l'applet se bloque pendant quatre ou cinq minutes avant d'avertir l'utilisateur de l'exception.

Pourquoi y a-t-il autant de retard s'il y a quelque chose qui ne va pas du côté serveur?

22
Mihir

Cela m'a beaucoup aidé: http://blog.somepixels.net/en/502-proxy-error-uploading-from-Apache-mod_proxy-to-Tomcat-7/

Fondamentalement, dans mon server.xml, je l'ai défini comme:

<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
       connectionUploadTimeout="36000000" disableUploadTimeout="false"
       connectionTimeout="60000" redirectPort="8443" />
31
Gustavo Matias

La question avec quelle configuration vous exécutez (ou ce que vous avez déjà essayé) ne précise pas clairement, mais le problème est presque par définition que le délai d'expiration du socket est dépassé pendant le téléchargement.

L'erreur est renvoyée car le fichier n'a pas été entièrement reçu avant l'expiration du délai approprié. Cela est cohérent avec les choses qui fonctionnent en test (sur un réseau local) mais pas lors de l'exécution sur Internet beaucoup plus lent (en particulier en ce qui concerne les vitesses de téléchargement).

Jetez un œil à votre server.xml pour le <Connector> définition. Vous serez intéressé par la valeur des attributs connectionTimeout ou connectionUploadTimeout (ce dernier si disableUploadTimeout est défini sur true).

En l'absence de preuves de problèmes plus néfastes, je m'attends à ce que vous puissiez résoudre ce problème simplement en augmentant le délai de connexion.

5
Andrzej Doyle