2010-10-06 10 views
6

Para una extensión de Emacs, me gustaría recuperar datos a través de HTTP. No me gusta mucho la idea de desembolsar cosas como wget, curl o w3m para poder hacer eso, así que estoy usando la función url-retrieve.Descodificación de cuerpos de respuesta gzip-ed con url-retrieve

Uno de los servidores HTTP con los que estoy hablando pasa a ignorar los encabezados Accept-Encoding e insiste en enviar siempre sus datos con Content-Encoding: gzip.

Como resultado de eso, y del hecho de que url-retrieve no decodifica automáticamente cuerpos de respuesta, el búfer url-retrieve me presentará contendrá datos gzip binarios.

Estoy buscando una forma de decodificar el cuerpo de la respuesta, preferiblemente trozo por fragmento, a medida que llegan los datos. ¿Hay alguna manera de ordenar url-retrieve que haga esto por mí?

Descodificar la respuesta de una sola vez, una vez que llegó por completo, también sería aceptable, pero preferiría evitar toda la fubar involucrada en la creación de un subproceso asíncrono ejecutando gzip, canalizando partes de la respuesta a eso, y leyendo los trozos decodificados de nuevo - Estaría buscando alguna función de biblioteca aquí.

+3

Emacs obviamente tiene incorporado gzip, ya que puede abrir archivos comprimidos, editarlos y guardarlos de forma transparente. La pregunta es ... ¿dónde está este gancho y la respuesta no es obvia? – jrockway

+0

Gracias, John. Si bien sabía que podía abrir archivos comprimidos gzip, realmente no se me ocurrió que esto podría estar relacionado, pero obviamente lo es. Desde la apertura de un archivo .gz en el disco, mirando '* Messages *' y buscando en mis directorios elisp lo que sea que obtuve, descubrí que el código implementado es 'jka-cmpr-hook.el' y/o' jka- compr.el'. Parece probable que este problema sea fácil de resolver con una sola de las funciones proporcionadas por aquellos. 'with-auto-compression-mode' parece más prometedor en este momento. – rafl

+0

tipo de fuera de tema, pero ¿sabes si url-retrieve puede manejar https? – sigjuice

Respuesta

4

Lo que hace auto-compression-mode es ejecutar gzip en el archivo que se va a descomprimir. Ver por ejemplo jka-compr-insert-file-contents en jka-compr.el. Entonces, si vas a usar auto-compression-mode para descomprimir, primero tendrás que escribir la respuesta a un archivo. Por ejemplo, algo como esto:

(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) 

(. Si no desea crear un archivo temporal, tendrá que hacer su propia gestión de sub-proceso, pero no es tan difícil como da a entender en su pregunta)

+0

Gracias, esto funcionó perfecto para mí – Upgradingdave

+0

si eres Usando 'url-retrieve-synchronously' puedes simplemente cambiar al buffer y luego ejecutar esa devolución de llamada, no necesitarás aceptar el argumento de estado (agregaría' y opcional') –

Cuestiones relacionadas