Я использую отправленные сервером события для потоковой передачи ответов (текст / поток событий). Мы хотим сжать ответ, используя сжатие 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();
1
Shiva Bhalla 23 Окт 2018 в 12:59

2 ответа

Лучший ответ

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

0
Shiva Bhalla 25 Окт 2018 в 07:11
  1. Сжатый поток - это двоичные данные. Его нельзя печатать с response.getWriter(). Вместо этого используйте response.getOutputStream().

< Сильный > UPDATE

Шива Бхалла: Использование response.getOutputStream () с текстовым потоком / потоком событий не выполняет надлежащую потоковую передачу после отображения 1-го блока ответа, запрос не выполняется в браузере.

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

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

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

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

    • Вы берете серию текстовых файлов (01.txt, 02.txt, ...).
    • Вы объединяете текстовые файлы в один файл (text.txt).
    • Вы сжимаете файл в архив gzip. ( Text.txt.gz )
  2. Я рекомендую вам использовать java.util.zip.DeflaterOutputStream (1) вместо прямого использования Deflater. Например.

    new DeflaterOutputStream(response.getOutputStream(), true);
    
  3. Остерегайтесь уязвимости BREACH.

0
Konstantin Kolinko 24 Окт 2018 в 10:22
52946239