Расшифровка gzip-ed тел ответов с помощью url-retrieve - PullRequest
6 голосов
/ 06 октября 2010

Для расширения Emacs я хотел бы получать данные по HTTP.Мне не особенно нравится идея обстреливать такие вещи, как wget, curl или w3m, чтобы сделать это, поэтому я использую функцию url-retrieve.

Один из HTTP-серверов, с которыми я общаюсь, игнорирует Accept-Encoding заголовки и настаивает на том, чтобы всегда отправлять свои данные с Content-Encoding: gzip.

В результате этого и того факта, что url-retrieve не декодирует тела ответов автоматически, буфер url-retrieve предоставит мне данные, содержащие двоичные данные gzip.

Я ищу способ декодировать тело ответа, предпочтительно порцию за порцией, как данныеприбывает.Есть ли способ поручить url-retrieve сделать это для меня?

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

1 Ответ

4 голосов
/ 08 ноября 2010

Что делает auto-compression-mode, так это запускает gzip для распакованного файла. См. Например jka-compr-insert-file-contents в jka-compr.el. Поэтому, если вы собираетесь использовать auto-compression-mode для распаковки, вам сначала нужно написать ответ в файл. Например, что-то вроде этого:

(defun uncompress-callback (status)
  (let ((filename (make-temp-file "download" nil ".gz")))
    (search-forward "\n\n")               ; Skip response headers.
    (write-region (point) (point-max) filename)
    (with-auto-compression-mode
      (find-file filename))))

(url-retrieve "http://packages.ubuntu.com/hardy/allpackages?format=txt.gz"
              #'uncompress-callback)

(Если вы не хотите создавать временный файл, вам придется самостоятельно управлять подпроцессами, но это не так сложно, как вы предполагаете в своем вопросе.)

...