Почему я не могу удалить заголовок передачи-кодирования в прокси узла?

У меня есть http-прокси-сервер Node, выполняющий переписывание тела ответа, которое в основном делает это:

  1. Клиент GET localhost:8000/api/items
  2. Прокси узла отправляет localhost:8000 -> на example.com/api
  3. Сервер отвечает json [{ id: 1234, url: http://example.com/api/items/1234 }]
  4. Прокси узла перезаписывает json в [{ id: 1234, url: http://localhost:8000/api/items/1234 }]
  5. Прокси узла вычисляет новый заголовок content-length, устанавливает его и возвращает ответ клиенту.

Это работало нормально, пока внутренний сервер не включил сжатие. Итак, теперь по умолчанию ответы сжимались. Я работал над этим, установив это в своем прокси:

req.headers['accept-encoding'] = 'deflate';

Так что после этого ответы не сжимались, я мог разобрать их и переписать тело по мере необходимости. Однако это перестало работать с IE. Я думаю, проблема в том, что ответ все еще имеет заголовок transfer-encoding=chunked, поэтому IE ожидает фрагментированный ответ. Поскольку этот заголовок transfer-encoding присутствует, заголовка content-length нет, хотя я явно устанавливаю его (эти два заголовка являются взаимоисключающими). Я пробовал все, что мог придумать, чтобы удалить заголовок transfer-encoding и вместо этого получить заголовок content-length, но ничего не работает. Я пробовал все это:

// In the context of my middleware response.writeHead function
res.setHeader('transfer-encoding', null);
res.setHeader('transfer-encoding', '');
res.removeHeader('transfer-encoding');
res.setHeader('content-length', modifiedBuffer.length); // this line alone worked before
res.originalWriteHead.call(res, statusCode, { 'Content-Length', modifiedBuffer.length });

// In the context of my middleware response.write function res.write(data, encoding)
// Here, encoding parameter is undefined
// According to docs, encoding defaults to utf8, could be 'chunked'
res.oldWrite.call(res, modifiedBuffer, 'utf8');
res.oldWrite.call(res, modifiedBuffer, '');
res.oldWrite.call(res, modifiedBuffer, null);
// tried all three previous the same for res.end

По сути, независимо от того, что я делаю, ответ не разбивается на части, а имеет установленный заголовок transfer-encoding, а не content-length. Firefox, Safari, Chrome, кажется, прекрасно справляются с этим, но IE выдает ошибку XMLHttpRequest: Network Error 0x800c0007, No data is available for the requested resource.. Это (насколько я могу судить) потому, что он ожидает куски (из-за заголовка transfer-encoding), но получает конец ответа и не имеет длины содержимого для его чтения.

Кто-нибудь знает, как я могу это решить? Я делаю что-то неправильно, пытаясь удалить заголовок transfer-encoding в пользу content-length?


person xdumaine    schedule 27.10.2014    source источник
comment
Возможно, вы только что спасли мою неделю :-)   -  person Stuart Watt    schedule 22.11.2016


Ответы (1)


Я понял это сам:

Я эффективно использовал два компонента промежуточного программного обеспечения (мой собственный, описанный в вопросе) и сжатие express.js. Мое промежуточное ПО распаковывало ответ, но сжатие гарантирует, что ответ всегда записывается с transfer-encoding=chunked, а content-length удаляется.

Удаление модуля сжатия express.js решило эту проблему для меня.

person xdumaine    schedule 27.10.2014