Problème de téléchargement du fichier Spring et de réinitialisation de la connexion

Problème de téléchargement de fichiers Spring et de réinitialisation de la connexion

Un initialiseur de servlet Spring pour configurer la limite de téléchargement de fichiers, 5 Mo par fichier et 10 Mo par requête.

MyWebInitializer.java

public class MyWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    private int maxUploadSizeInMb = 5 * 1024 * 1024; // 5 MB

    //...

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {

        // upload temp file will put here
        File uploadDirectory = new File(System.getProperty("java.io.tmpdir"));

        // register a MultipartConfigElement
        MultipartConfigElement multipartConfigElement =
                new MultipartConfigElement(uploadDirectory.getAbsolutePath(),
                        maxUploadSizeInMb, maxUploadSizeInMb * 2, maxUploadSizeInMb / 2);

        registration.setMultipartConfig(multipartConfigElement);

    }

}

Si vous essayez de télécharger une taille de fichier supérieure à la limite de téléchargement, disons 20 Mo, l'erreur étrange suivante "réinitialisation de la connexion" s'affichera:

spring-file-upload-connection-reset

Même les@ControllerAdviceglobaux ne peuvent pas attraper l'exception ci-dessus!

Testé

1. Solution

Après quelques jours d'enquête et de recherche, je découvre que le problème n'était pas lié à Spring (pas de problème s'il est déployé sur Jetty), c'est le connecteur par défaut de TomcatmaxSwallowSize

Le nombre maximum d'octets du corps de la requête (hors surcharge de codage de transfert) qui seront avalés par Tomcat pour un téléchargement interrompu. Un téléchargement interrompu se produit lorsque Tomcat sait que le corps de la requête va être ignoré, mais que le client l'envoie toujours. Si Tomcat n'avale pas le corps, le client ne verra probablement pas la réponse. S'il n'est pas spécifié, la valeur par défaut de 2097152 (2 mégaoctets) sera utilisée. Une valeur inférieure à zéro indique qu'aucune limite ne doit être appliquée.

Si vous essayez de télécharger une taille de fichier dépassant la limite de taille, Tomcat le recadrera à la valeur par défaut de 2 Mo et réinitialisera la connexion. Pour le résoudre rapidement, mettez un -1 (illimité) pourmaxSwallowSize

Tomcat/conf/server.xml

    

Ce -1 est bon pour le développement, mais pas pour la production, si l'utilisateur essaie de télécharger un fichier de 100 Mo, Tomcat gaspillera des ressources pour gérer la bande passante supplémentaire.

2. Idea

2. 1 Essayez de définir une limite raisonnable pour le téléchargement du fichier, par exemple,11mb (11 x 1024 x 1024 = octets) dans cet exemple

Tomcat/conf/server.xml

    

2.2 And implement a Javascript to check the file size before the upload.

What about Jetty?
Testé avec Jetty 9, ne peut trouver aucun paramètre demaxSwallowSize et ne provoquera PAS une réinitialisation de la connexion si la taille du fichier a dépassé la limite de téléchargement.