Ir para o corpo após url-recuperar-de forma síncrona

7

Eu uso url-retrieve-synchronouslypara baixar um arquivo JSON de um servidor remoto. Esta função retorna um buffer que contém todo o conteúdo da resposta, incluindo os cabeçalhos HTTP. No entanto, estou apenas interessado no corpo.

Agora, além de analisar uma resposta HTTP manualmente, como posso pular para o início do corpo? Eu encontrei a variável url-http-end-of-headers, que funciona, mas não está documentada, e usá-la parece "suja". Existe uma API adequada para esse fim?


fonte

Respostas:

3

Com relação a uma "API apropriada", acho que a resposta curta, atualmente, é "não" - a menos que você esteja disposto a confiar em uma biblioteca externa. url-http-end-of-headersparece ser o melhor possível, embora não seja mencionado no Manual do Programador de URLs nem parece estar documentado no emacs source .

dat
fonte
8

Como existe uma nova linha após os cabeçalhos HTTP, a única alternativa que eu conheço é usar um re-search-forward:

(with-current-buffer
    (url-retrieve-synchronously my-url)
  (goto-char (point-min))
  (re-search-forward "^$")
  (delete-region (point) (point-min))
  (buffer-string))
mutbuerger
fonte
Bem, isso é "analisar o HTTP" para mim e acho que url-http-end-of-headersé preferível a essa abordagem. Eu realmente esperava algo como url-http-goto-body:( #
3

Uma alternativa de nível superior ao uso url-http-end-of-headers, mas igualmente indocumentada, é url-insert-file-contents:

(with-temp-buffer
  (url-insert-file-contents
   "https://api.stackexchange.com/2.2/questions/12464?site=emacs")
  (json-parse-buffer :object-type 'alist))

ou equivalente, antes do Emacs 27 compilado com suporte JSON nativo:

(require 'json)
(with-temp-buffer
  (url-insert-file-contents
   "https://api.stackexchange.com/2.2/questions/12464?site=emacs")
  (let ((json-false :false))
    (json-read)))

Isso resulta em:

((items .
  [((tags .
     ["url" "http"])
    (owner
     (reputation . 10741)
     (user_id . 227)
     (user_type . "registered")
     (accept_rate . 89)
     (profile_image . "https://i.stack.imgur.com/ebO5J.jpg?s=128&g=1")
     (display_name . "lunaryorn")
     (link . "https://emacs.stackexchange.com/users/227/lunaryorn"))
    (is_answered . t)
    (view_count . 867)
    (accepted_answer_id . 29798)
    (answer_count . 3)
    (score . 4)
    (last_activity_date . 1517363132)
    (creation_date . 1431861037)
    (question_id . 12464)
    (link . "/emacs/12464/go-to-body-after-url-retrieve-synchronously")
    (title . "Go to body after url-retrieve-synchronously"))])
 (has_more . :false)
 (quota_max . 300)
 (quota_remaining . 276))

A função url-insert-file-contentsenvolve as funções mais bem documentadas url-insert-buffer-contentse url-inserte, portanto, vem com os seguintes extras:

  1. Carregado automaticamente por padrão.
  2. Existe desde pelo menos no Emacs 21.
  3. Tratamento simples de erros de resposta HTTP via url-http-response-status.
  4. Decodifica dados.

FWIW, ele também vem com a garantia de ser usado por lisp/emacs-lisp/package.el.

Manjericão
fonte