Чтение и отображение зашифрованного PDF-файла в формате JSF

1

согласно домашней странице BalusC, я реализовал функцию downloadPDF(), которая считывает PDF файл из файловой системы и отображает его в браузере. эта функция работает по назначению.

кроме того, у меня есть класс EncryptionService, который позволяет мне шифровать и/или расшифровывать данный файл. это также работает по назначению.

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

приведенный ниже код показывает мои простые модификации обработчика BalusC PDF.

public void showDocument(String path, boolean decrypt) throws IOException, InvalidKeyException {

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();

    File file = new File(path);
    BufferedInputStream input = null;
    BufferedOutputStream output = null;

    try {
        if(!decrypt)
            input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
        else {
            // update MessageDigets, return Key
            cipher.init(Cipher.DECRYPT_MODE, genKey(passphrase));

            input = new BufferedInputStream(new CipherInputStream(new FileInputStream(file), cipher), DEFAULT_BUFFER_SIZE);
        }

        response.reset();
        response.setHeader("Content-Type", "application/pdf");
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + path + "\"");

        output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }

        output.flush();
    } finally {
        try {
            input.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    facesContext.responseComplete();
}
  • 0
    В частности, в какой момент происходит зацикливание? showDocument ли выполнение showDocument ? Что отправлено обратно в браузер? Посмотрите на вкладке сети вашего браузера, чтобы увидеть код ответа, заголовки и пакет тела ответа
  • 0
    @kolossus, showDocument завершается правильно. вкладка сети ничего не показывает, когда я загружаю что-то в новую вкладку. он показывает system.jsf (текущий сайт) при попытке загрузить в той же вкладке. через несколько секунд это приводит к ошибке net::ERR_CONTENT_LENGTH_MISMATCH .
Показать ещё 5 комментариев
Теги:
encryption
pdf
jsf
primefaces

1 ответ

1
Лучший ответ

Что происходит

Как и ошибка консоли,

нетто :: ERR_CONTENT_LENGTH_MISMATCH

Это указывает, что фактический размер содержимого, возвращаемого в тело ответа, не соответствует размеру, указанному в заголовке Content-Length ответа.

Почему это происходит

Причина несоответствия распределяется по двум факторам:

  • Шифрование обычно увеличивает размер зашифрованного контента. Процесс шифрования требует обфускации содержимого с помощью шифрования, который обычно означает бросание в материал, из-за чего содержимое неприменимо в противном случае. Расшифровка, с другой стороны, вернет содержимое оригинальному размеру

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

  • Диск-ввод-вывод не является 100% -ным шагом с ОЗУ или ЦП. Запись на диск и чтение с диска по-прежнему несет накладные расходы в виде RAM, ожидающего диск.

Исправить

  • Создайте случайное/различное имя файла для каждого из файлов, участвующих в вашей операции. Это означает отдельное имя файла для зашифрованного контента и отдельное для расшифрованной формы

  • Как следствие вышеизложенного, откройте разные выходные потоки для разных файлов, также используя разные переменные доступа к File.

Связанный:

Ещё вопросы

Сообщество Overcoder
Наверх
Меню