WinHTTP の Uniform Resource Locators (URL)
URL は、インターネット上にあるリソースの場所とアクセス方法のコンパクトな表現です。 各 URL は、スキーム (HTTP、HTTPS、FTP、または Gopher) とスキーム固有の文字列で構成されます。 この文字列には、ディレクトリ パス、検索文字列、またはリソースの名前の組み合わせを含めることもできます。 Microsoft Windows HTTP Services (WinHTTP) 関数は、URL の作成、結合、分割、正規化を行う機能を提供します。 詳細については、「 RFC 1738、 Uniform Resource Locators 、 RFC 2396、 Uniform Resource Identifiers (URI): Generic Syntax」を参照してください。
正規化された URL とは
URL の指定された構文とセマンティクスにより、バリエーションとエラーの余地が残ります。 正規化は、実際の URL を正しい標準の "正規" 形式に正規化するプロセスです。
これには、一部の文字を "エスケープ シーケンス" としてコーディングする必要があります。英数字 US-ASCII 文字をエンコードする必要はありません (数字 0 から 9、大文字 A ~ Z、小文字 a ~ z)。 他のほとんどの文字は、制御文字、スペース文字、パーセント記号、"unsafe characters" ( <、、 >、"、#、{、}、|、\、^、~、[、]、および ' )、および 127 より上のコード ポイントを持つすべての文字を含め、エスケープする必要があります。
WinHTTP 関数を使用した URL の処理
WinHTTP には、URL を処理するための 2 つの関数が用意されています。 WinHttpCrackUrl は URL をコンポーネントパーツに分割し、 WinHttpCreateUrl は コンポーネントから URL を作成します。
URL の分離
WinHttpCrackUrl 関数は、URL をコンポーネント部分に分割し、関数に渡されるURL_COMPONENTS構造体によって示されるコンポーネントを返します。
URL_COMPONENTS構造を構成するコンポーネントは、スキーム番号、ホスト名、ポート番号、ユーザー名、パスワード、URL パス、検索パラメーターなどの追加情報です。 スキームとポート番号を除く各コンポーネントには、情報を保持する文字列メンバーと、文字列メンバーの長さを保持するメンバーがあります。 スキームとポート番号には、対応する値を格納するメンバーのみが含まれます。スキームとポート番号の両方が、 WinHttpCrackUrl への正常な呼び出しで返されます。
URL_COMPONENTS構造体内の特定のコンポーネントの値を取得するには、そのコンポーネントの文字列長を格納するメンバーを 0 以外の値に設定する必要があります。 文字列メンバーには、バッファーへのポインターまたは NULL を指定できます。
ポインター メンバーにバッファーへのポインターが含まれている場合、文字列の長さのメンバーには、そのバッファーのサイズが含まれている必要があります。 WinHttpCrackUrl 関数は、コンポーネント情報をバッファー内の文字列として返し、文字列の長さを文字列長メンバーに格納します。
ポインター メンバーが NULL に設定されている場合、文字列長メンバーは 0 以外の値に設定できます。 WinHttpCrackUrl 関数は、コンポーネント情報を含む URL 文字列の最初の文字へのポインターを格納し、文字列の長さを、コンポーネントに関連する URL 文字列の残りの部分の文字数に設定します。
すべてのポインター メンバーが NULL に設定され、長さ 0 以外のメンバーが URL 文字列内の適切な開始点を指します。 length メンバーに格納されている長さは、個々のコンポーネントの情報の末尾を決定するために使用する必要があります。
URL_COMPONENTS構造体の初期化を正常に完了するには、dwStructSize メンバーをURL_COMPONENTS構造体のサイズに設定する必要があります。
URL の作成
WinHttpCreateUrl 関数は、前に説明した URL_COMPONENTS 構造体の情報を使用して URL を作成します。
必要なコンポーネントごとに、ポインター メンバーには、情報を保持するバッファーへのポインターが含まれている必要があります。 ポインター メンバーに 0 で終わる文字列へのポインターが含まれている場合は、長さメンバーを 0 に設定する必要があります。ポインター メンバーに 0 で終わる文字列へのポインターが含まれている場合は、長さメンバーを文字列の長さに設定する必要があります。 必須ではないコンポーネントのポインター メンバーを NULL に設定する必要があります。
サンプル コード
次のサンプル コードは、 WinHttpCrackUrl と WinHttpCreateUrl を使用して既存の URL を逆アセンブルし、そのコンポーネントの 1 つを変更し、新しい URL に再アセンブルする方法を示しています。
URL_COMPONENTS urlComp;
LPCWSTR pwszUrl1 =
L"https://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH&v=1&q=wininet";
DWORD dwUrlLen = 0;
// Initialize the URL_COMPONENTS structure.
ZeroMemory(&urlComp, sizeof(urlComp));
urlComp.dwStructSize = sizeof(urlComp);
// Set required component lengths to non-zero so that they are cracked.
urlComp.dwSchemeLength = (DWORD)-1;
urlComp.dwHostNameLength = (DWORD)-1;
urlComp.dwUrlPathLength = (DWORD)-1;
urlComp.dwExtraInfoLength = (DWORD)-1;
// Crack the URL.
if( !WinHttpCrackUrl( pwszUrl1, (DWORD)wcslen(pwszUrl1), 0, &urlComp ) )
printf( "Error %u in WinHttpCrackUrl.\n", GetLastError( ) );
else
{
// Change the search information. New info is the same length.
urlComp.lpszExtraInfo = L"?RS=CHECKED&FORM=MSNH&v=1&q=winhttp";
// Obtain the size of the new URL and allocate memory.
WinHttpCreateUrl( &urlComp, 0, NULL, &dwUrlLen );
LPWSTR pwszUrl2 = new WCHAR[dwUrlLen];
// Create a new URL.
if( !WinHttpCreateUrl( &urlComp, 0, pwszUrl2, &dwUrlLen ) )
printf( "Error %u in WinHttpCreateUrl.\n", GetLastError( ) );
else
{
// Show both URLs.
printf( "Old URL: %S\nNew URL: %S\n", pwszUrl1, pwszUrl2 );
}
// Free allocated memory.
delete [] pwszUrl2;
}