aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeder O. Klingenberg2025-07-18 00:11:57 +0200
committerEli Zaretskii2025-07-26 12:09:07 +0300
commita2d71cecaec1aa16bbbef54e5231ba203e7d2a2a (patch)
tree8b6294bfff23640d64164dda98a600463c49c176
parent44bb860796a0537bc0df2f6b603153989c7957a0 (diff)
downloademacs-a2d71cecaec1aa16bbbef54e5231ba203e7d2a2a.tar.gz
emacs-a2d71cecaec1aa16bbbef54e5231ba203e7d2a2a.zip
Emulate more dynamic bindings in request buffers
Many variables were copied from the dynamic environment to the request buffer, which allowed them to influence the handling of requests and responses. But some were not, notably some of the mime-related variables, and the user-agent and privacy variables. This made them unreliable when dynamically bound around a call to `url-retrieve'; they would have the desired effect when reusing an existing connection, but not when url-http opened a new connection. In the case of reused connections, the request construction happens in the dynamic scope of `url-http', but in the case where a fresh connection is needed, request construction happens outside that dynamic scope. This commit adds the remaining variables used in request construction to the set of buffer local variables mirroring the dynamic values from url-http, and adds a comment describing the mechanism used and how avoid the pitfall of inconsistent handling of dynamic bindings. * lisp/url/url-http.el (url-http-extensions-header): New internal-ish variable. (url-http-create-request): Use the new variable instead of the global one. (url-http-idle-sentinel): Debug-log when the connection closes. (url-http): Set up more buffer-local variants of dynamic variables in the buffer used for the request, and add comment describing why this copying is needed. (Bug#61916)
-rw-r--r--lisp/url/url-http.el51
1 files changed, 44 insertions, 7 deletions
diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el
index eb5d5c13722..a230a37e9ff 100644
--- a/lisp/url/url-http.el
+++ b/lisp/url/url-http.el
@@ -56,6 +56,7 @@
56(defvar url-http-transfer-encoding) 56(defvar url-http-transfer-encoding)
57(defvar url-show-status) 57(defvar url-show-status)
58(defvar url-http-referer) 58(defvar url-http-referer)
59(defvar url-http-extensions-header)
59 60
60(require 'url-gw) 61(require 'url-gw)
61(require 'url-parse) 62(require 'url-parse)
@@ -374,9 +375,9 @@ Use `url-http-referer' as the Referer-header (subject to `url-privacy-level')."
374 "close" "keep-alive") 375 "close" "keep-alive")
375 "\r\n" 376 "\r\n"
376 ;; HTTP extensions we support 377 ;; HTTP extensions we support
377 (if url-extensions-header 378 (if url-http-extensions-header
378 (format 379 (format
379 "Extension: %s\r\n" url-extensions-header)) 380 "Extension: %s\r\n" url-http-extensions-header))
380 ;; Who we want to talk to 381 ;; Who we want to talk to
381 (if (/= (url-port url-http-target-url) 382 (if (/= (url-port url-http-target-url)
382 (url-scheme-get-property 383 (url-scheme-get-property
@@ -1020,8 +1021,9 @@ should be shown to the user."
1020;; ) 1021;; )
1021 1022
1022;; These unfortunately cannot be macros... please ignore them! 1023;; These unfortunately cannot be macros... please ignore them!
1023(defun url-http-idle-sentinel (proc _why) 1024(defun url-http-idle-sentinel (proc why)
1024 "Remove (now defunct) process PROC from the list of open connections." 1025 "Remove (now defunct) process PROC from the list of open connections."
1026 (url-http-debug "url-http-idle-sentinel for process %S: %s" proc (string-trim why))
1025 (maphash (lambda (key val) 1027 (maphash (lambda (key val)
1026 (if (memq proc val) 1028 (if (memq proc val)
1027 (puthash key (delq proc val) url-http-open-connections))) 1029 (puthash key (delq proc val) url-http-open-connections)))
@@ -1340,9 +1342,19 @@ overriding the value of `url-gateway-method'.
1340 1342
1341The return value of this function is the retrieval buffer." 1343The return value of this function is the retrieval buffer."
1342 (cl-check-type url url "Need a pre-parsed URL.") 1344 (cl-check-type url url "Need a pre-parsed URL.")
1345 ;; The request is handled by asynchronous processes, which are outside
1346 ;; the dynamic scope of the caller of url-http (sometimes, sometimes
1347 ;; not). The caller may still desire to bind variables controlling
1348 ;; aspects of the request for the duration of this one http request.
1349 ;; The async processes operate on a buffer created in this function,
1350 ;; so the way to accomplish this goal is to set buffer local copies of
1351 ;; the relevant variables to the dynamic values in scope as we create
1352 ;; the buffer. When new variables are added that influence behaviour
1353 ;; of requests, they should be added to the handling in this function
1354 ;; to make them work reliably without changing their global values.
1343 (let* (;; (host (url-host (or url-using-proxy url))) 1355 (let* (;; (host (url-host (or url-using-proxy url)))
1344 ;; (port (url-port (or url-using-proxy url))) 1356 ;; (port (url-port (or url-using-proxy url)))
1345 (nsm-noninteractive (not (url-interactive-p))) 1357 (noninteractive-p (not (url-interactive-p)))
1346 ;; The following binding is needed in url-open-stream, which 1358 ;; The following binding is needed in url-open-stream, which
1347 ;; is called from url-http-find-free-connection. 1359 ;; is called from url-http-find-free-connection.
1348 (url-current-object url) 1360 (url-current-object url)
@@ -1350,10 +1362,17 @@ The return value of this function is the retrieval buffer."
1350 (url-port url) 1362 (url-port url)
1351 gateway-method)) 1363 gateway-method))
1352 (mime-accept-string url-mime-accept-string) 1364 (mime-accept-string url-mime-accept-string)
1365 (mime-encoding-string url-mime-encoding-string)
1366 (mime-charset-string url-mime-charset-string)
1367 (mime-language-string url-mime-language-string)
1353 (buffer (or retry-buffer 1368 (buffer (or retry-buffer
1354 (generate-new-buffer 1369 (generate-new-buffer
1355 (format " *http %s:%d*" (url-host url) (url-port url))))) 1370 (format " *http %s:%d*" (url-host url) (url-port url)))))
1356 (referer (url-http--encode-string (url-http--get-referer url)))) 1371 (referer (url-http--encode-string (url-http--get-referer url)))
1372 (httpver url-http-version)
1373 (httpkeepalive url-http-attempt-keepalives)
1374 (user-agent url-user-agent)
1375 (privacy-level url-privacy-level))
1357 (if (not connection) 1376 (if (not connection)
1358 ;; Failed to open the connection for some reason 1377 ;; Failed to open the connection for some reason
1359 (progn 1378 (progn
@@ -1389,8 +1408,17 @@ The return value of this function is the retrieval buffer."
1389 url-http-no-retry 1408 url-http-no-retry
1390 url-http-connection-opened 1409 url-http-connection-opened
1391 url-mime-accept-string 1410 url-mime-accept-string
1411 url-mime-encoding-string
1412 url-mime-charset-string
1413 url-mime-language-string
1392 url-http-proxy 1414 url-http-proxy
1393 url-http-referer)) 1415 url-http-referer
1416 url-http-version
1417 url-http-attempt-keepalives
1418 url-http-extensions-header
1419 url-user-agent
1420 url-privacy-level
1421 nsm-noninteractive))
1394 (set (make-local-variable var) nil)) 1422 (set (make-local-variable var) nil))
1395 1423
1396 (setq url-http-method (or url-request-method "GET") 1424 (setq url-http-method (or url-request-method "GET")
@@ -1409,8 +1437,17 @@ The return value of this function is the retrieval buffer."
1409 url-http-no-retry retry-buffer 1437 url-http-no-retry retry-buffer
1410 url-http-connection-opened nil 1438 url-http-connection-opened nil
1411 url-mime-accept-string mime-accept-string 1439 url-mime-accept-string mime-accept-string
1440 url-mime-encoding-string mime-encoding-string
1441 url-mime-charset-string mime-charset-string
1442 url-mime-language-string mime-language-string
1412 url-http-proxy url-using-proxy 1443 url-http-proxy url-using-proxy
1413 url-http-referer referer) 1444 url-http-referer referer
1445 url-http-version httpver
1446 url-http-attempt-keepalives httpkeepalive
1447 url-http-extensions-header url-extensions-header
1448 url-user-agent user-agent
1449 url-privacy-level privacy-level
1450 nsm-noninteractive noninteractive-p)
1414 1451
1415 (set-process-buffer connection buffer) 1452 (set-process-buffer connection buffer)
1416 (set-process-filter connection #'url-http-generic-filter) 1453 (set-process-filter connection #'url-http-generic-filter)