proxy 環境下で auto-install を使う

修正情報 (2011/4/13 追記)

proxy 関係の不具合は auto-install v1.53 で修正されました。
最新版の auto-install.el をダウンロードしましょう。

v1.53 以降では wget に対して proxy の設定を行っておけば, .emacs 内では proxy の設定を行わなくても正常に動作します。

変数 auto-install-use-wgetnil に設定して, 明示的に wget の使用を避けている場合は, EmacsWiki の記述通り

; If you want to use proxy server, set ‘url-proxy-services’. For example: 
  (setq url-proxy-services '(("http" . "localhost:8339")))

のように設定すれば, 正常に動作します。


auto-install.el は v1.53 で proxyに対応したため、以下の記述は古くなりました。

概要

auto-install.el は elisp をインストールするときに非常に便利なのだが, proxy にちゃんと対応していないらしく, proxy 環境下で使うとハングしてしまう.
この問題をなんとかするための設定を書いたのでメモしておく.

  • 設定を少し修正 (2011/03/18)
注意

EmacsWiki には

; If you want to use proxy server, set ‘url-proxy-services’. For example: 
  (setq url-proxy-services '(("http" . "localhost:8339")))

と書いてあるが, この記述は誤りか古いバージョンへの言及なので, 気にしてはいけない.
ソースを少し読んだ感じでは現行の auto-install.el はデフォルトではこの設定を使ってない.

設定

auto-install がコケけるのは, ネットワークの疎通確認の関数 auto-install-network-available-p が proxy に対応していないのが問題. なので, auto-install-available-p が proxy 環境下でも動くように書き換えてやれば後は問題ない.
以下に, .emacs の設定を書いておく.
auto-install-update-emacswiki-package-name 関数で, auto-install-network-available-p が呼ばれるので, その前に関数定義を書くことに注意.

(require 'auto-install)

; wget を使わない場合
;(setq auto-install-use-wget nil)
;(setq url-proxy-services '(("http" . "proxy.hoge.net:8080")))
;(url-scheme-register-proxy "http")  ; 環境変数 http_proxy から読み込む場合

; proxy 対応関数
(defun auto-install-network-available-p (host)
  (if auto-install-use-wget
      (eq (call-process auto-install-wget-command nil nil nil "-q" "--spider" host) 0)
    (let* ((proxy (cdr (assoc "http" url-proxy-services)))
	   (host-port (if proxy (split-string proxy ":")))
	   (host (or (car host-port) host))
	   (port (or (cadr host-port) "80")))
      (ignore-errors (ffap-machine-p host port)))))

(setq auto-install-directory "~/.emacs.d/elisp/")
(auto-install-update-emacswiki-package-name t)
(auto-install-compatibility-setup) 

proxy の設定は

  • wget を使う場合は, 環境変数 http_proxy もしくは, .wgetrc で行う. つまり, wget の proxy だけ設定すればよい
  • wget を使わない場合は, url-proxy-services で行う. つまり, emacs に対して設定する.

url-method.el で定義されている関数 url-scheme-register-proxy を使うと, 環境変数 http_proxy の値を url-proxy-services に読み込むことも可能なので, wget を使わない場合はこの関数を使って設定してもよい.

説明および注意

上記の設定で修正した関数 auto-install-network-available-p は wget を使う場合は, wget の spider オプションを使って, 疎通確認を行っている.
spider オプションは, ダウンロードを行わずに疎通確認のみ行うためのオプション.

wget を使わない場合は, ほとんど元々 auto-install.el 内で定義されている関数とほとんど同じで, ネットワーク疎通確認用の関数 ffap-machine-p を単にラップしただけの関数になる.
この ffap-machine-p は通常の host に対しては, host と直接TCP接続を繋ぎにいって, 成功すれば t を返す仕様になっている.
ただし, proxy 環境下での TCP接続は proxy サーバと繋ぐべきなので, その点を修正してある. もともとの auto-install-network-available-p は ffap-machine-p に対して, 直接 host を渡していたので, proxy 環境下でも 直接 host とTCP接続を確立しようとして, うまくいかずにハングしていた.
上記の修正版では, proxy が設定されている場合は, host の値にかかわらず, proxy サーバとTCP接続できれば, t を返すようにラップしてある. 本当は, proxy サーバに TCP 接続を繋いだ上で, host に対して HTTP リクエストを出して, host との疎通確認まですべきかもしれないが, 少しレスポンスが遅くなるのでやめた.

もともとの auto-install-network-available-p は wget を使う場合も使わない場合も ffap-machine-p を使って, emacs 内からネットワークの疎通確認を行っていたが, ダウンロードに wget を使うなら疎通確認にも wget を使う方が妥当なので, 上記の修正版ではそのように修正してある.

余談

url パッケージについて

url-proxy-services は proxy の設定でよく見かけるけれど, これは lisp/url あたりに入っている url*.el 系のファイルで使われる設定. url パッケージはもともと elisp で書かれたブラウザ W3 の一部だったものが独立したものらしい. これらは emacs 内から直接ネットワーク通信を行うために使われる.

auto-install.el でも, wget を使わない場合は url.el 内にある関数 url-retrieve を使って, ダウンロードを行っている. なので, wget を使わない場合は必ず url-proxy-services の設定をしなければならない. 逆に, wget を使う場合は, emacs から直接はネットワーク通信をしないので, wget の proxy の設定さえしておけば, emacs 内で proxy の設定をする必要はない. EmacsWiki の記述はこのあたりがごっちゃになっているんだと思う.