ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

Webページ上で動かすActiveXの中でWinInetのInternetOpen()を呼んだ場合のProxyおよび認証設定はIE側の設定が引き継がれる現象について


タイトル長くて御免なさい。
HTMLに埋め込んで動かすActiveXで、WinInetを用いてHTTP/FTP通信を行うケースに遭遇しております。
で、当初ActiveXActiveXで動くから・・・と手動でProxy設定の取得や、認証が必要なProxyから407が返されたら認証ダイアログ表示するのにInternetErrorDlg()を呼んだりとかしないと・・・で頑張ってたんですが。

いざ出来上がったので組み込んで動かしたら。なんか、IE側で一度別ページなりなんなりでProxy認証通ってしまえば、それがそのままActiveX側のInternetOpen()で取得されるHINTERNETに引き継がれるっぽい。

・InternetOpen() : MSDN
http://msdn.microsoft.com/en-us/library/aa385096(VS.85).aspx

WiresharkでHTTPを覗いてみたら、素直にIE側での認証ヘッダーがActiveX側からも送出されてるし、Proxyも特にActiveX側で取得させてないのに(InternetOpen()でINTERNET_OPEN_TYPE_PRECONFIGは指定してるけど)ちゃんとProxyのアドレス・ポート番号に発信してる・・・。しかも、WPAD使ってるのに。

・・・何だそれ・・・あんだけ苦労した(後述するけどInternetErrorDlg()のVB側のDeclareで思いっきり嵌ってた)のはいったい何だったんだ・・・と、思い切ってデバッグ用のWinInetモジュールを入手してデバッグログを取得してみた。

ちなみにWinInetのデバッグ用DLLを使ったWinInetAPIのトレースについては下記参照。

・・・IE側で使用しているのと同じハンドルがActiveX側で呼んでるInternetOpen()から返ってきてる。

気になって「WinInet HINTERNET reuse」とかでGoogle先生に訊いてみたら・・・

The InternetCloseHandle function closes handles of type HINTERNET. Note that handle values are recycled quickly; therefore, if a handle is closed and a new handle is generated immediately, there is a good chance that the new handle has the same value as the handle just closed.

HINTERNET Handles | Microsoft Docs

オーノー。普通にMSDNに書いてあったし。そうか・・・IEと同じプロセス内で動作したから、IE側でProxyやら認証やらが設定済のHINTERNETがそのまま返ってくるんだ・・・。だからか。

ちなみにInternetErrorDlg()で嵌ったというのは、第5引数がLongPointerなのにByVal指定してた為アドレス周りで落ちてしまってた。
・InternetErrorDlg() : MSDN
http://msdn.microsoft.com/en-us/library/aa384694(VS.85).aspx

多分どっかからInternetErrorDlg()のDeclare文をコピペしてきたと思うのだけれど我ながら情けないけれど、多分それがByValになってたんだと思う。ByRefで型をAnyにしたうえでvbNullを渡してあげたら直った。あと、これ関連で嵌ってた時にうっかりHINTERNETを渡す部分をIN/OUTだからってByRefに何を思ったかしてしまっていて、そのお陰で丸一日以上嵌っていた事は確かだ。

ってか、"()"がURLに認識されてない・・・。MSも変なURLにしてるなぁ。