Apache использует тайм-аут загрузки файлов только с Firefox - PullRequest
8 голосов
/ 10 мая 2019

Я использую библиотеку Apache commons fileupload 1.4 в своем проекте Java.У меня есть HTML-часть с классической формой с вводом файла и некоторыми скрытыми полями.

У меня проблема с загрузкой файлов размером> 500ko только с Firefox> = 52

Работает хорошос файлами 10mo в Chrome или Internet Explorer.Но в Firefox у меня есть тайм-аут после ожидания нескольких минут после отправки формы.

После некоторой отладки я вижу, что код, ответственный за тайм-аут:

List<FileItem> items = (new ServletFileUpload(new DiskFileItemFactory())).parseRequest(request);

Часть спричина ожидания "parseRequest".

Я пытаюсь отладить содержимое запроса с помощью отладчика в IntelliJ, но нет способа скопировать все значение содержимого этого объекта запроса в необработанном формате.

Он работает в следующих случаях: - Firefox: версия <= 52 или размер файла <500ko (примерно, это не совсем точно) - Internet Explorer - Chrome </p>

Ограничения по размеру файла нет, похоже, это зависит отразмер запроса, потому что часть запроса на синтаксический анализ занимает слишком много времени ...

Я получаю HTTP-запрос с расширением Firefox в двух случаях.Одна генерирующая загрузка файла 3mo, которая не работает (файл запроса огромен, в 3 раза больше загруженного файла): https://code.empreintesduweb.com/13561.html

Одна генерируемая загрузка файла 200ko, который работает (файл запросаявляется небольшим): https://code.empreintesduweb.com/13560.html

На самом деле основное отличие состоит в том, что в Chrome или IE у меня нет необработанного содержимого загруженного файла в заголовках запроса:

расстаться с: obj stream .... endstream endobj

появляются только с Firefox ...

Ответы [ 4 ]

2 голосов
/ 14 мая 2019

Вы можете попробовать установить максимальный размер файла, возможно, размер файла превышает максимальный порог. Согласно документации :

  • Загруженные элементы должны храниться в памяти, если они достаточно малы.
  • Более крупные элементы должны быть записаны во временный файл на диске.
  • Запрещены очень большие запросы на загрузку.
  • Встроенные значения по умолчанию для максимального размера элемента, сохраняемого в памяти, максимально допустимого размера загрузки запрос и расположение временных файлов являются приемлемыми.

Попробуйте следующее:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            // Set factory constraints
           DiskFileItemFactory factory = new DiskFileItemFactory();
           factory.setSizeThreshold(yourMaxMemorySize);
           ServletContext servletContext = this.getServletConfig().getServletContext();
           File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
           factory.setRepository(repository);
            List<FileItem> items = new ServletFileUpload(factory).parseRequest(request);
            for (FileItem item : items) {
                if (item.isFormField()) {
                    // Process regular form field (input type="text|radio|checkbox|etc", select, etc).
                    String fieldName = item.getFieldName();
                    String fieldValue = item.getString();
                    // ... (do your job here)
                } else {
                    // Process form file field (input type="file").
                    String fieldName = item.getFieldName();
                    String fileName = FilenameUtils.getName(item.getName());
                    InputStream fileContent = item.getInputStream();
                    // ... (do your job here)
                }
            }
        } catch (FileUploadException e) {
            throw new ServletException("Cannot parse multipart request.", e);
        }

        // ...
    }

Здесь мы предоставляем временное местоположение для файла, так как файл большой.

2 голосов
/ 14 мая 2019

Несколько вещей, которые стоит попробовать здесь:

Мы также можем помочь вам лучше, если вы предоставите больше информации, например, версии apache / java / servlet, и еще немного кода (особенно определение request)

Некоторые ресурсы, которые могут быть полезны:
XMLHttpRequest
Sending_files_using_a_FormData_object
Как установить заголовок для HTTP-запроса GET и инициировать загрузку файла?

0 голосов
/ 05 июня 2019

Спасибо за ваш ответ. Наконец, я успешно решил эту проблему, но на самом деле ... не совсем. Я заметил, что в моей форме были некоторые конкретные вещи. У меня было два входа, один стандартный ввод файла, и другой, который получает содержимое файла, зашифрованное в base64 некоторыми странными js перед любой загрузкой. Так что у меня был один раз сырой контент файла, а также файл в base64. Зачем ?! Я не знаю.

Но я все это удаляю, создаю новую простую и чистую форму со стандартным входным файлом. Я использую потоковый API из ServletFileUpload, и он работает, и для больших файлов требуется всего несколько секунд.

Так что я не все понимаю (почему проблема была только в каком-то браузере, например), но я нашел решение;)

Спасибо!

0 голосов
/ 18 мая 2019

попробуйте установить тайм-аут сеанса, используя метод setMaxInactiveInterval

 request.getSession().setMaxInactiveInterval(1200);

параметр Указывает время в секундах между клиентскими запросами до Контейнер сервлета сделает этот сеанс недействительным. Значение интервала ноль или меньше означает, что время этой сессии никогда не должно превышаться.

...