5/29の記事の続きです。
WinHTTPは、レスポンスのヘッダに関する細かい処理を行うことができます(HTTPライブラリとしては当たり前ですが)。
そこで細かい処理を行う例として、ステータスコードが301の場合だけリダイレクト先のURLを記録し、それ以外の場合はリダイレクト先のURLを記録せずに転送するコードを書いてみました。
オプション設定でリダイレクトをOFFにしておかないとWinHTTP内部で転送処理が行われてしまうので気をつけましょう。
#include <windows.h> #include <string> #include <iostream> #import "winhttp.dll" named_guids int main(void) { ::CoInitialize(NULL); std::string Uri = "http://www.sutosoft.com/test/redirect/301.html"; std::string Moved; WinHttp::IWinHttpRequestPtr Request; Request.CreateInstance(WinHttp::CLSID_WinHttpRequest); Request->Option[WinHttp::WinHttpRequestOption_EnableRedirects] = false; for (int i = 0; i < 10; ++i) { Request->Open("GET", Uri.c_str()); Request->Send(); long Status = Request->Status; if (Status == 301 || Status == 302 || Status == 303 || Status == 307) { Uri = Request->GetResponseHeader("Location"); if (Status == 301) { Moved = Uri; } }else { break; } } if (!Moved.empty()) { std::cout << "Moved Permanently. New URI = " << Moved; } std::cout << Request->ResponseText; ::CoUninitialize(); };
リダイレクト回数は最大10回にしました。
Option[WinHttp::WinHttpRequestOption_MaxAutomaticRedirects]のデフォルト値が10なので、それに合わせた形です。
なお、WinHTTPは、同じURLにリダイレクトするようなリダイレクトループを検出できるようです。
以下のURLはリダイレクトループテスト用のURLですが、
http://www.sutosoft.com/test/redirect/301_loop.html
WinHTTPでこのURLにアクセスすると、リダイレクト許可オプション(Option[WinHttp::WinHttpRequestOption_EnableRedirects])に関わらず、リダイレクトを行わないで終了するようです。
WinInetだと、永遠にリダイレクトし続けます。例えば上記リダイレクトループテスト用のURLにInternet Explorer 6SP2でアクセスすると終了しません。
WinHTTPはちゃんと進歩してますね。