Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Browsing w3m Anonymously With tor
;; If there are problems, shoot me an email at francisavmurillo@gmail.com.
;; As I want to make sure this works.
(with-eval-after-load 'w3m
(when (and (executable-find "polipo")
(executable-find "tor"))
(defcustom fn/w3m-polipo-cache-dir (expand-file-name "polipo-cache" user-emacs-directory)
"Polipo cache directory."
:type 'directory)
(defcustom fn/w3m-tor-cache-dir (expand-file-name "tor-cache" user-emacs-directory)
"Tor cache directory."
:type 'directory)
(make-directory fn/w3m-polipo-cache-dir t)
(make-directory fn/w3m-tor-cache-dir t)
(defcustom fn/w3m-tor-port 18050
"Tor port"
:type 'number)
(defcustom fn/w3m-polipo-port 18123
"Polipo port"
:type 'number)
(defcustom fn/w3m-polipo-conf-file (expand-file-name "polipo-w3m-conf" user-emacs-directory)
"Polipo configuration."
:type 'file)
(defcustom fn/w3m-tor-conf-file (expand-file-name "tor-w3m-conf" user-emacs-directory)
"Tor configuration."
:type 'file)
(defun fn/w3m-polipo-tor-update-conf ()
"Create/update `fn/w3m-polipo-conf-file' and `fn/w3m-tor-conf-file' with new configurations."
(interactive)
(with-temp-file fn/w3m-polipo-conf-file
(insert
(string-join
(mapcar
(lambda (pair)
(pcase-let ((`(,key . ,value) pair))
(format
"%s = %s"
key
(typecase value
(symbolp (symbol-name value))
(numberp (number-to-string value))
(stringp (format "\"%s\"" value))))))
`(("proxyAddress" . "127.0.0.1")
("allowedClients" . "127.0.0.1")
("diskCacheRoot" . ,fn/w3m-polipo-cache-dir)
("proxyPort" . ,fn/w3m-polipo-port)
("cacheIsShared" . false)
("socksParentProxy" .
,(format "%s:%s" "localhost" (number-to-string fn/w3m-tor-port)))
("socksProxyType" . socks5)))
"\n")))
(with-temp-file fn/w3m-tor-conf-file
(insert
(string-join
(mapcar
(lambda (pair)
(pcase-let ((`(,key . ,value) pair))
(format
"%s %s"
key
(typecase value
(symbolp (symbol-name value))
(numberp (number-to-string value))
(stringp value)))))
`(("SocksPort" . ,fn/w3m-tor-port)
("DataDirectory" . ,fn/w3m-tor-cache-dir)
("ControlPort" . ,(1+ fn/w3m-tor-port))
("DisableDebuggerAttachment" . 0)))
"\n")))
(setq w3m-command-arguments
(cl-reduce
(lambda (val xs)
(if (and (string= "-o" val))
(or (string-prefix-p "http_proxy=" (or (car xs) ""))
(string-prefix-p "https_proxy=" (or (car xs) ""))))
(cdr xs)
(cons val xs)))
w3m-command-arguments
:from-end t
:initial-value (list))
(setq w3m-command-arguments
(append w3m-command-arguments
(list "-o"
(format
"http_proxy=http://127.0.0.1:%s/"
(number-to-string fn/w3m-polipo-port)))
(list "-o"
(format
"https_proxy=https://127.0.0.1:%s/"
(number-to-string fn/w3m-polipo-port)))))
(defvar fn/w3m-polipo-process nil
"Polipo process.")
(defvar fn/w3m-tor-process nil
"Tor process.")
(defun fn/w3m-polipo-tor-start-process (&rest args)
"Start `fn/w3m-polipo-process'."
(interactive)
(unless (process-live-p fn/w3m-tor-process)
(message "Starting tor process.")
(fn/w3m-polipo-tor-update-conf)
(setq fn/w3m-tor-process
(start-process "w3m-tor" "*w3m-tor*" "tor" "-f" fn/w3m-tor-conf-file)))
(unless (process-live-p fn/w3m-polipo-process)
(message "Starting polipo process.")
(setq fn/w3m-polipo-process
(start-process "w3m-polipo" "*w3m-polipo*" "polipo" "-c" fn/w3m-polipo-conf-file))))
(defun fn/w3m-polipo-tor-kill-process (&rest args)
"Kill `fn/w3m-polipo-process'."
(interactive)
(when (process-live-p fn/w3m-polipo-process)
(message "Killing polipo process")
(kill-process fn/w3m-polipo-process))
(when (process-live-p fn/w3m-tor-process)
(message "Killing tor process")
(kill-process fn/w3m-tor-process))
(setq fn/w3m-polipo-process nil
fn/w3m-tor-process nil))
(add-hook 'kill-emacs-hook #'fn/w3m-polipo-tor-kill-process)
(add-to-list 'w3m-no-proxy-domains "127.0.0.1")
(add-to-list 'w3m-no-proxy-domains "localhost")
(when (yes-or-no-p "Start polipo and tor for w3m? ")
(fn/w3m-polipo-tor-start-process))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment