2010-10-06 3 views
6

Per un'estensione Emacs, mi piacerebbe recuperare i dati su HTTP. Non mi piace particolarmente l'idea di eseguire il bombardamento su cose come wget, curl o w3m per poterlo fare, quindi sto utilizzando la funzione url-retrieve.Decodifica corpi di risposta gzip-ed con url-retrieve

Uno dei server HTTP con cui sto parlando ignora le intestazioni Accept-Encoding e insiste per inviare sempre i suoi dati con Content-Encoding: gzip.

Di conseguenza, e del fatto che url-retrieve non decodifica automaticamente i corpi di risposta, il buffer url-retrieve mi presenterà conterrà dati gzip binari.

Sto cercando un modo per decodificare il corpo della risposta, preferibilmente pezzo per pezzo, man mano che i dati arrivano. C'è un modo per ordinare a url-retrieve di fare questo per me?

Decodificare la risposta tutto in una volta, una volta che è arrivato completamente, sarebbe anche accettabile, ma preferirei evitare tutto il fubar coinvolto nella creazione di un sottoprocesso asincrono che esegue gzip, piping le parti della risposta che ho ottenuto, e leggendo di nuovo i pezzi decodificati, cercherò qualche funzione di libreria qui.

+3

Emacs ha ovviamente integrato gzip, in quanto è possibile aprire file compressi con gzip, modificarli e salvarli in modo trasparente. La domanda è ... dov'è questo gancio, e la risposta non è ovvia. – jrockway

+0

Grazie, John. Mentre ero consapevole di essere in grado di aprire i file compressi con gzip, in realtà non mi è venuto in mente che questo potrebbe essere correlato, ma ovviamente lo è. Dall'apertura di un file .gz su disco, guardando '* Messages *', e cercando le mie directory elisp per quello che ho ottenuto, ho capito che l'implementazione del codice era 'jka-cmpr-hook.el' e/o' jka- compr.el'. Sembra probabile che questo problema sia facile da risolvere con una delle funzioni fornite da questi. 'with-auto-compression-mode' sembra molto promettente in questo momento. – rafl

+0

un po 'fuori tema, ma ti capita di sapere se url-retrieve può gestire https? – sigjuice

risposta

4

Quello che auto-compression-mode esegue gzip sul file non compresso. Vedi ad esempio jka-compr-insert-file-contents in jka-compr.el. Quindi, se hai intenzione di usare auto-compression-mode per fare la decompressione, dovrai prima scrivere la risposta a un file. Per esempio, qualcosa di simile:

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

(. Se non si desidera creare un file temporaneo, si dovrà fare la propria gestione sottoprocesso, ma non è così difficile come si implica nella domanda)

+0

Grazie, questo ha funzionato perfettamente per me – Upgradingdave

+0

se sei usando 'url-retrieve-synchronously 'puoi semplicemente passare al buffer e quindi eseguire quel callback, non dovrai accettare l'argomento status (aggiungerei' & optional') –