Сжатие gzip / deflate с отправленными событиями на сервлете tomcat - PullRequest
0 голосов
/ 23 октября 2018

Я использую отправленные сервером события для потоковой передачи ответов (текст / событие-поток).Мы хотим сжать ответ, используя сжатие gzip или deflate, но браузер показывает: ERR_CONTENT_DECODING_FAILED.Код для того же -

response.setContentType("text/event-stream; charset=UTF-8");
response.addHeader("Connection", "keep-alive");
response.addHeader("Cache-Control", "no-cache, must-revalidate");
response.addHeader("Content-Encoding", "deflate");
PrintWriter writer = response.getWriter();
number = 10;
time = 100;
for (int i = 0; i < number; i++) {
  String resp = "data: " + "Some Response" + "\r\n";

  Deflater deflater = new Deflater(Deflater.DEFLATED);
  byte[] input = resp.getBytes("UTF-8");
  deflater.setInput(input);
  deflater.finish();
  byte[] output = new byte[1024];
  deflater.deflate(output);
  deflater.end();
  writer.write(new String(output, "UTF-8"));
  writer.flush();
  try {
    Thread.sleep(time);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
}
String resp = "data: close\r\n";
Deflater deflater = new Deflater(Deflater.DEFLATED);
byte[] input = resp.getBytes("UTF-8");
deflater.setInput(input);
deflater.finish();
byte[] output = new byte[1024];
deflater.deflate(output);
deflater.end();
writer.write(new String(output, "UTF-8"));
writer.flush();

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Добавление «text / event-stream; charset = UTF-8, ms-stream; charset = UTF-8» в качестве «compressableMimeType» в свойствах соединителя сделало свою работу!

0 голосов
/ 23 октября 2018
  1. Сжатый поток - это двоичные данные.Он не должен быть напечатан с response.getWriter().Вместо этого используйте response.getOutputStream().

ОБНОВЛЕНИЕ

Шива Бхалла: Использование response.getOutputStream () с text / event-stream не являетсяПри правильной потоковой передаче после отображения 1-го блока ответа в браузере происходит сбой запроса.

Вы должны сжать весь поток, используя один экземпляр Deflater.

В своем коде вы сжимаете каждый фрагмент отдельно.Это эквивалентно следующему:

  • Вы берете серию текстовых файлов (01.txt, 02.txt, ...).
  • Вы сжимаете каждый из них вархив gzip.(01.txt.gz, 02.txt.gz, ...)
  • Вы объединяете архивы в один файл.

Приведенное выше создает неверный архив.Gzip файлы не могут быть объединены таким образом.Правильный код должен выполнить следующее:

  • Вы берете серию текстовых файлов (01.txt, 02.txt, ...).
  • Вы объединяете текстовые файлы водин файл (text.txt).
  • Вы сжимаете файл в архив gzip.(text.txt.gz)

Я рекомендую вам использовать java.util.zip.DeflaterOutputStream (1) вместо прямого использования Deflater.Например,

new DeflaterOutputStream(response.getOutputStream(), true);

Остерегайтесь введения уязвимости BREACH .

...