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はちゃんと進歩してますね。