Как сжать JSON с gzip в Rails для Android?

Я запускаю Rails 3.2.7 с Ruby 1.9.3p194 для вывода данных JSON из базы данных SQLite.

render :json => result.to_json 

Приложение Android использует файл JSON, который загружается через HTTP-GET :

 HttpClient httpclient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(urlPath); HttpResponse response = httpclient.execute(httpGet); HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity, HTTP.UTF_8); JSONObject jsonObject = new JSONObject(result); 

Поддержка платформы:

Я прочитал в API, что Rails предлагает поддержку gzip следующим образом:

 ActiveSupport::Gzip.compress(result) 

Я также предполагаю из HTTP / 1.1, RFC2626, раздел 14.3, что я могу настроить заголовок HTTP-запроса:

 httpPost.setHeader("Accept-Encoding", "gzip"); 

Я также нашел информацию довольно интересную, которая содержится в разделе 3.5 «Content Codings» :

  • Все значения кодирования содержимого не зависят от регистра .
  • HTTP / 1.1 использует значения кодирования контента в полях заголовка Accept-Encoding (раздел 14.3) и Content-Encoding (раздел 14.11).
  • Орган присвоенных номеров Интернета (IANA) действует как реестр для токенов значения содержимого. Первоначально реестр содержит следующие токены:
    • Gzip Формат кодирования, созданный программой сжатия файлов «gzip» (GNU zip), как описано в RFC 1952 [25].

В этом сообщении также объясняется, как обрабатывать кодированный контент GZIP с помощью Android .

Тестирование сервера:

Таким образом, я понятия не имею, как я могу узнать, если данные были сжаты сервером. Чтобы проверить, выводит ли Rails gzip, я попытался использовать завиток, как предлагается здесь :

 $ curl --head -H "Accept-Encoding: gzip" http://localhost:3000/posts.json 

Однако вывод не показывает мне, поддерживается ли gzip или нет:

 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 X-Ua-Compatible: IE=Edge Etag: "f6f6732c747466f75052f88b1eff393b" Cache-Control: max-age=0, private, must-revalidate X-Request-Id: 74ee0562c05adea679deb701f1b8fd88 X-Runtime: 0.004205 Content-Length: 0 Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20) Date: Thu, 16 Aug 2012 23:33:25 GMT Connection: Keep-Alive 

Я также попробовал – --compressed параметр curl

 $ curl --compressed --head -H "Accept-Encoding: gzip" http://localhost:3000/posts.json 

Который выводит ту же информацию заголовка, что и предыдущая команда. Когда я бегу …

 $ curl --compressed -H "Accept-Encoding: gzip" http://localhost:3000/posts.json 

Данные JSON печатаются на консоль как читаемый текст. Я не вижу, произошло ли сжатие. Может быть, потому что curl уже распаковывает ответ ?!

Онлайн-тестирование

Я также попробовал онлайн-тест HTTP Compression Test, упомянутый здесь . Он подтвердил, что контент JSON «не gzipped». Второй связанный здесь сайт GIDZipTest признал отрицательный результат теста.

Вопросов:

  1. Как вывести gzip сжатый JSON из Rails?
  2. Как настроить HTTP-клиент для запроса сжатых данных gzip?
  3. Одинаковая конфигурация все еще работает, когда я запускаю сервер Rails на Heroku (PostgreSQL), …?

Уроки выучены

Поскольку я узнал все, что мне нужно настроить для сервера REST, use Rack::Deflater . Чтобы быть ясным: я не использую ActiveSupport::Gzip.compress() в моем коде. В случае, если кто-то заинтересован, это то, что заголовок выглядит, когда включен сжатие GZIP.

 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 X-Ua-Compatible: IE=Edge Etag: "8170a04be41673bf25824256740a9460" Cache-Control: max-age=0, private, must-revalidate X-Request-Id: 700b9536f6a20164d31b8528bde423af X-Runtime: 0.369337 Vary: Accept-Encoding Content-Encoding: gzip Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20) Date: Tue, 21 Aug 2012 12:10:48 GMT Content-Length: 20 Connection: Keep-Alive 

Теперь, когда я знаю ключевое слово magic, легко найти и найти статьи по use Rack::Deflater .

Возможно, вы должны использовать Rack :: Deflater? Вставить в config.ru:

 require ::File.expand_path('../config/environment', __FILE__) use Rack::Deflater run MyAppName::Application 

И настройте заголовки запросов HTTP:

Я могу настроить заголовок HTTP-запроса:

HttpPost.setHeader («Accept-Encoding», «gzip»);

PS такая же конфигурация работает на Heroku