Когда Rails отвечает "Transfer-Encoding" против "Content-Length"?

Я создаю API на Rails версии 4.1.7/Nginx, который отвечает на запрос из приложения iOS. Мы видим какое-то странное кэширование на клиенте, и мы думаем, что это связано с небольшой разницей в ответе, который Rails отправляет обратно. Мои вопросы...

1) Я хочу понять, почему для точно такого же запроса (с измененным только значением заголовка авторизации) Rails отправляет обратно transfer-encoding: chunked иногда и Content-Length: <number> иногда? Я подумал, что, возможно, это как-то связано с размером ответа, но в примерах ответов, заголовки которых я вставил ниже, данные, возвращаемые в теле, ТОЧНО одинаковы.

2) Есть ли способ заставить его использовать Content-Length? Мы думаем, что это решит наши проблемы с кэшированием в нашем приложении для iOS.

Ответ № 1

HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Date: Wed, 18 Mar 2015 00:59:31 GMT
ETag: "86f277ea63295460d4f3bed9a073eaa2"
Server: nginx/1.6.2
Status: 200 OK
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Request-Id: dd36f139-1986-4da6-9645-4438d41e74b0
X-Runtime: 0.123865
X-XSS-Protection: 1; mode=block
transfer-encoding: chunked
Connection: keep-alive

Запрос № 2

HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Date: Wed, 18 Mar 2015 00:59:36 GMT
ETag: "86f277ea63295460d4f3bed9a073eaa2"
Server: nginx/1.6.2
Status: 200 OK
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Request-Id: 0cfd7705-157b-41b5-aa36-739bc6f8302e
X-Runtime: 0.092672
X-XSS-Protection: 1; mode=block
Content-Length: 2234
Connection: keep-alive

1 ответ

Решение

Оба ответа действительны в соответствии с HTTP 1.1, поэтому вам нужно исправить свой клиентский код, чтобы он мог обрабатывать оба. Неправильно пытаться исправить сервер так, чтобы он вел себя так, чтобы не вызывать ошибку на клиенте. Следующая версия nginx может вести себя по-другому, у ваших пользователей могут даже быть прокси, которые изменяют передачу, возможно, только когда они работают в роуминге и используют другого провайдера.

Если вы хотите сделать отпечатки пальцев на заголовке, вам может помочь заголовок ETag, так как ETag должен оставаться постоянным, когда содержание ответа не изменяется, независимо от передачи.

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

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

Другие вопросы по тегам