[emacs-berlin] Code review for a simple HTTP async client

jman emacs-berlin at city17.xyz
Sun Oct 22 20:11:38 UTC 2023


Hello everyone!

I have adventured myself into porting into elisp the following simple
bash script:

----------s---------s----------
# Use cURL to query a remote server using a HTTP HEAD
# isolate the Location header returned
function http_head_no_redirect ()
{
    URL="${1}"
    UA="User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +google.com/bot.html)"
    location=`curl -fsS "${URL}" -H "${UA}" -I | grep location | tr -d '\n' | tr -d '\r' | sed "s/location: //"`
    print "The redirect points to location: %s" $location
}
----------e---------e----------

The following code is the solution I've found. It works but I'm sure it
can be improved while preserving readability.

The main thing I couldn't figure out is that since `url-retrieve` is
asynchronous the function returns nil because the http call completes
later, so it will not return the `Location` header. As a workaround I
set a global variable and set that ^^'

Any suggestions?

----------s---------s----------
(defvar test-302 "https://httpbin.org/status/302")
(defvar redirect-url nil)
(defvar ua-google "User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +google.com/bot.html)")

(defun http-get-no-redirect (url)
  "Send a HTTP HEAD request to URL. Don't follow redirects.
Return the URL to which the request would be redirected."
  (let ((url-user-agent ua-google)(url-request-method "HEAD")(url-max-redirections 0))
    (url-retrieve
     url
     (lambda (status)
       (when (eq (car status) :redirect)
         (message "location: %s" (cadr status))
         (setq redirect-url (cadr status)))))))

;; testing
(http-get-no-redirect test-302)
(message "Redirect location is: %s" redirect-url)
----------e---------e----------


More information about the emacs-berlin mailing list