IE7 以降で HttpOpenRequest() API が エラーコード 12006 で失敗する件
プログラム上からインターネットに接続して直接ファイルをダウンロードしたい場合などに、InternetOpen/InternetConnect/HttpOpenRequest API を使って下記のようなコードを使用すると思うが、このコードは IE6 以前では問題なく動作するが、IE7 以降では失敗する。
HINTERNET hSession = ::InternetOpen( _T( "UserAgent" ), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
HINTERNET hConnect = ::InternetConnect( hSession, _T( "www.example.com" ), 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
HINTERNET hRequest = ::HttpOpenRequest( hConnect, _T( "GET" ), _T( "/~user/path/file.txt" ), NULL, _T( "Referrer" ), NULL, INTERNET_FLAG_DONT_CACHE, 0 );
if ( hRequest == NULL ) {
DWORD dwError = ::GetLastError();
if ( dwError == ERROR_INTERNET_UNRECOGNIZED_SCHEME /*12006*/ ) {
ATLTRACE( _T( "スキームが認識できないエラー\n" ) );
}
}
// (snip)
::InternetCloseHandle( hRequest );
::InternetCloseHandle( hConnect );
::InternetCloseHandle( hSession );
原因は、HttpOpenRequest() でリファラに「Referrer」と記述しているがこの形式が「スキーム:識別子」の形式になっていないことによるものらしい。これをたとえば「myscheme:Referrer」に変更することで上記コードは IE7 以降でも正常に動作する。
なぜ IE7 以降で動作しなくなったかは不明だが、これにはかなりハマったので記事にして残しておくことにした。