Emacs Lisp。当url不正确时如何处理http响应?

时间:2016-11-12 15:27:14

标签: elisp

我使用 url.el 通过 url-retrieve-synchronously 创建http请求。当网址正确时,一切都很好。 代码示例:

(with-current-buffer (url-retrieve-synchronously my-url)
  (hoge--log-debug "\n%s"(buffer-string)))

可是:

  1. 当url不正确时,我如何处理http响应。 例如“http://2222httpbin.org/xml”(未知主持人)?

  2. 我如何获得http状态响应?

2 个答案:

答案 0 :(得分:1)

显然url-retrieve-synchronously只返回有效的缓冲区或nil。我不认为你可以检索状态。您最好的选择是调用url-retrieve,它允许您传递回调函数,您可以在其中访问所有详细信息。

解决方法

查看list-processes给出的过程,似乎后台进程仍悬而未决。删除它会调用回调函数。因此,当我们现在进程失败时,我们只需要自己删除它:

(defun url-retrieve-please (url callback)
  (apply callback
         (block waiter
           (let ((process
                   (get-buffer-process
                    (url-retrieve url (lambda (&rest args)
                                        (return-from waiter args))))))
             ;; We let a chance for the connection to establish
             ;; properly.  When it succeeds, the callback will return
             ;; from the waiter block.
             ;; When it fails to connect, we exit this loop.
             (loop until (eq 'failed (process-status process))
                   ;; sitting leaves a chance for Emacs to handle
                   ;; asynchronous tasks.
                   do (sit-for 0.1))

             ;; Deleting the process forces the above lambda callback
             ;; to be called, thanks to the process sentinel being in
             ;; place. In the tests, we always exit from the above 
             ;; callback and not after the block normally exits. The
             ;; behaviour seems quite regular, so I don't sleep 
             ;; forever after this command.
             (delete-process process)))))

测试

(url-retrieve-please "http://yahoo.com" (lambda (&rest args) (message "%S" args)))

"((:redirect \"https://www.yahoo.com/\" :peer (:certificate (:version 3 :serial-number \"1c:25:43:0e:d0:a6:02:e8:cc:3a:97:7b:05:39:cc:e5\" :issuer \"C=US,O=Symantec Corporation,OU=Symantec Trust Network,CN=Symantec Class 3 Secure Server CA - G4\" :valid-from \"2015-10-31\" :valid-to \"2017-10-30\" :subject \"C=US,ST=California,L=Sunnyvale,O=Yahoo Inc.,OU=Information Technology,CN=www.yahoo.com\" :public-key-algorithm \"RSA\" :certificate-security-level \"Medium\" :signature-algorithm \"RSA-SHA256\" :public-key-id \"sha1:47:16:26:79:c6:4f:b2:0f:4b:89:ea:28:dc:0c:41:6e:80:7d:59:a9\" :certificate-id \"sha1:41:30:72:f8:03:ce:96:12:10:e9:a4:5d:10:da:14:b0:d2:d4:85:32\") :key-exchange \"ECDHE-RSA\" :protocol \"TLS1.2\" :cipher \"AES-128-GCM\" :mac \"AEAD\")))"

(url-retrieve-please "http://2222httpbin.org/xml" (lambda (&rest args) (message "%S" args)))   

"((:error (error connection-failed \"deleted
\" :host \"2222httpbin.org\" :service 80)))"

答案 1 :(得分:1)

要检索状态码,请在获得的缓冲区上使用undefined

示例:

url-http-symbol-value-in-buffer