>From 5ac2987f3085dede2e20755bb6c9631f7d47380b Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 1 Mar 2022 01:38:33 -0800 Subject: [PATCH 4/4] [POC/30.0.50] Integrate the socks and url libraries * lisp/url/url-gw.el (url-open-stream): Use presence and type of `url-using-proxy' to detect caller and massage input values according to legacy practices. * lisp/url/url-http.el: (url-http-find-free-connection): Don't call `url-open-stream' with host and port from active proxy. (url-http, url-http-async-sentinel): Only open `url-https-proxy-connect' for non-SOCKS proxies. * lisp/url/url-proxy.el (url-proxy--socks-scheme-regexp): Add new const. (url-default-find-proxy-for-url): Accommodate SOCKS entries but defy original design somewhat by requiring a URL scheme in the host value for detection. (url-find-proxy-for-url): Recognize modified host/address value for socks entries of `url-proxy-services' and deal accordingly. (url-proxy): Handle a SOCKS proxy for http(s) connections only. * lisp/url/url-vars.el (url-proxy-services): Explain that values for certain gateways may need a leading scheme:// portion. (url-using-proxy): Add warning regarding expected type. --- lisp/url/url-gw.el | 8 +++++++- lisp/url/url-http.el | 16 +++++++--------- lisp/url/url-proxy.el | 18 ++++++++++++++++-- lisp/url/url-vars.el | 13 ++++++++++--- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/lisp/url/url-gw.el b/lisp/url/url-gw.el index e4d1ca72a0..c93edc0d4e 100644 --- a/lisp/url/url-gw.el +++ b/lisp/url/url-gw.el @@ -28,7 +28,7 @@ (require 'url-vars) (require 'url-parse) -(autoload 'socks-open-network-stream "socks") +(autoload 'socks-open-network-stream "socks") ; FIXME remove this (defgroup url-gateway nil "URL gateway variables." @@ -220,6 +220,12 @@ url-open-stream Optional arg GATEWAY-METHOD specifies the gateway to be used, overriding the value of `url-gateway-method'." (unless url-gateway-unplugged + (when (url-p url-using-proxy) + (if (or (eq 'socks url-gateway-method) + (string-prefix-p "socks" (url-type url-using-proxy))) + (setq gateway-method 'socks) + (setq host (url-host url-using-proxy) + service (url-port url-using-proxy)))) (let* ((gwm (or gateway-method url-gateway-method)) (gw-method (if (and url-gateway-local-host-regexp (not (eq 'tls gwm)) diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index 94ef156108..864048a73c 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el @@ -195,12 +195,7 @@ url-http-find-free-connection ;; like authentication. But we use another buffer afterwards. (unwind-protect (let ((proc (url-open-stream host buf - (if url-using-proxy - (url-host url-using-proxy) - host) - (if url-using-proxy - (url-port url-using-proxy) - port) + host port gateway-method))) ;; url-open-stream might return nil. (when (processp proc) @@ -1396,8 +1391,9 @@ url-http (error "Could not create connection to %s:%d" (url-host url) (url-port url))) (_ - (if (and url-http-proxy (string= "https" - (url-type url-current-object))) + (if (and url-http-proxy + (not (string-prefix-p "socks" (url-type url-http-proxy))) + (string= "https" (url-type url-current-object))) (url-https-proxy-connect connection) (set-process-sentinel connection #'url-http-end-of-document-sentinel) @@ -1479,7 +1475,9 @@ url-http-async-sentinel (url-http-end-of-document-sentinel proc why)) ((string= (substring why 0 4) "open") (setq url-http-connection-opened t) - (if (and url-http-proxy (string= "https" (url-type url-current-object))) + (if (and url-http-proxy + (not (string-prefix-p "socks" (url-type url-http-proxy))) + (string= "https" (url-type url-current-object))) (url-https-proxy-connect proc) (condition-case error (process-send-string proc (url-http-create-request)) diff --git a/lisp/url/url-proxy.el b/lisp/url/url-proxy.el index c72e459a4e..f4ddd639f6 100644 --- a/lisp/url/url-proxy.el +++ b/lisp/url/url-proxy.el @@ -25,6 +25,9 @@ (require 'url-parse) +(defconst url-proxy--socks-scheme-regexp + (rx bot "socks" (? (or "4" "4a" "5" "5h")) "://")) + (defun url-default-find-proxy-for-url (urlobj host) (cond ((or (and (assoc "no_proxy" url-proxy-services) @@ -35,7 +38,12 @@ url-default-find-proxy-for-url (equal "www" (url-type urlobj))) "DIRECT") ((cdr (assoc (url-type urlobj) url-proxy-services)) - (concat "PROXY " (cdr (assoc (url-type urlobj) url-proxy-services)))) + (let ((found (alist-get (url-type urlobj) url-proxy-services + nil nil #'equal))) + (concat (if (string-match url-proxy--socks-scheme-regexp found) + "SOCKS " + "PROXY ") + found))) ;; ;; Should check for socks ;; @@ -57,7 +65,10 @@ url-find-proxy-for-url ((string-match "^PROXY +" proxy) (concat "http://" (substring proxy (match-end 0)) "/")) ((string-match "^SOCKS +" proxy) - (concat "socks://" (substring proxy (match-end 0)))) + (if-let* ((m (substring proxy (match-end 0))) + ((string-match url-proxy--socks-scheme-regexp m))) + m + (concat "socks://" m))) (t (display-warning 'url (format "Unknown proxy directive: %s" proxy) :error) nil)))) @@ -72,6 +83,9 @@ url-proxy (cond ((string= (url-type url-using-proxy) "http") (url-http url callback cbargs)) + ((and (string-prefix-p "socks" (url-type url-using-proxy)) + (string-prefix-p "http" (url-type url))) + (url-http url callback cbargs)) (t (error "Don't know how to use proxy `%s'" url-using-proxy)))) diff --git a/lisp/url/url-vars.el b/lisp/url/url-vars.el index 4cdca05554..209d387ea7 100644 --- a/lisp/url/url-vars.el +++ b/lisp/url/url-vars.el @@ -191,11 +191,16 @@ url-mail-command (defcustom url-proxy-services nil "An alist of schemes and proxy servers that gateway them. -Looks like ((\"http\" . \"hostname:portnumber\") ...). This is set up -from the ACCESS_proxy environment variables." +Looks like ((\"http\" . \"hostname:portnumber\") ...). This is +set up from the ACCESS_proxy environment variables. Depending on +the gateway type, values may instead be expected to look like +\"proxyscheme://hostname:portnumber\" where \"proxyscheme\" is +something like \"socks5\". As of Emacs 30.1, this only applies +to SOCKS servers." :type '(repeat (cons :format "%v" (string :tag "Protocol") (string :tag "Proxy"))) + :version "30.1" :group 'url) (defcustom url-standalone-mode nil @@ -310,7 +315,9 @@ url-show-status (defvar url-using-proxy nil "Either nil or the fully qualified proxy URL in use, e.g. -https://www.example.com/") +https://www.example.com/. Beware that some functions, such as +`url-proxy' and `url-http-end-of-document-sentinel', set this to +a `url' struct.") (defcustom url-news-server nil "The default news server from which to get newsgroups/articles. -- 2.38.1