Fungsi Proksi Otomatis WinHTTP
WinHTTP menerapkan protokol WPAD menggunakan fungsi WinHttpGetProxyForUrl bersama dengan dua fungsi utilitas pendukung, WinHttpDetectAutoProxyConfigUrl dan WinHttpGetIEProxyConfigForCurrentUser.
Dukungan AutoProxy tidak sepenuhnya terintegrasi ke dalam tumpukan HTTP di WinHTTP. Sebelum mengirim permintaan, aplikasi harus memanggil WinHttpGetProxyForUrl untuk mendapatkan nama server proksi lalu memanggil WinHttpSetOption menggunakan WINHTTP_OPTION_PROXY untuk mengatur konfigurasi proksi pada handel permintaan WinHTTP yang dibuat oleh WinHttpOpenRequest.
Fungsi WinHttpGetProxyForUrl dapat menjalankan ketiga langkah protokol WPAD yang dijelaskan dalam gambaran umum sebelumnya: (1) menemukan URL PAC, (2) mengunduh file skrip PAC, (3) menjalankan kode skrip dan mengembalikan konfigurasi proksi dalam struktur WINHTTP_PROXY_INFO . Secara opsional, jika aplikasi tahu terlebih dahulu URL PAC, aplikasi dapat menentukan ini ke WinHttpGetProxyForUrl.
Contoh kode berikut menggunakan proksi otomatis. Ini menyiapkan permintaan HTTP GET dengan terlebih dahulu membuat penyabungan sesi WinHTTP dan handel permintaan. Panggilan WinHttpOpen menentukan WINHTTP_ACCESS_TYPE_NO_PROXY untuk konfigurasi proksi awal, untuk menunjukkan bahwa permintaan dikirim langsung ke server target secara default. Menggunakan autoproxy, kemudian mengatur konfigurasi proksi langsung pada handel permintaan.
HINTERNET hHttpSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
WINHTTP_AUTOPROXY_OPTIONS AutoProxyOptions;
WINHTTP_PROXY_INFO ProxyInfo;
DWORD cbProxyInfoSize = sizeof(ProxyInfo);
ZeroMemory( &AutoProxyOptions, sizeof(AutoProxyOptions) );
ZeroMemory( &ProxyInfo, sizeof(ProxyInfo) );
//
// Create the WinHTTP session.
//
hHttpSession = WinHttpOpen( L"WinHTTP AutoProxy Sample/1.0",
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0 );
// Exit if WinHttpOpen failed.
if( !hHttpSession )
goto Exit;
//
// Create the WinHTTP connect handle.
//
hConnect = WinHttpConnect( hHttpSession,
L"www.microsoft.com",
INTERNET_DEFAULT_HTTP_PORT,
0 );
// Exit if WinHttpConnect failed.
if( !hConnect )
goto Exit;
//
// Create the HTTP request handle.
//
hRequest = WinHttpOpenRequest( hConnect,
L"GET",
L"ms.htm",
L"HTTP/1.1",
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0 );
// Exit if WinHttpOpenRequest failed.
if( !hRequest )
goto Exit;
//
// Set up the autoproxy call.
//
// Use auto-detection because the Proxy
// Auto-Config URL is not known.
AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
// Use DHCP and DNS-based auto-detection.
AutoProxyOptions.dwAutoDetectFlags =
WINHTTP_AUTO_DETECT_TYPE_DHCP |
WINHTTP_AUTO_DETECT_TYPE_DNS_A;
// If obtaining the PAC script requires NTLM/Negotiate
// authentication, then automatically supply the client
// domain credentials.
AutoProxyOptions.fAutoLogonIfChallenged = TRUE;
//
// Call WinHttpGetProxyForUrl with our target URL. If
// auto-proxy succeeds, then set the proxy info on the
// request handle. If auto-proxy fails, ignore the error
// and attempt to send the HTTP request directly to the
// target server (using the default WINHTTP_ACCESS_TYPE_NO_PROXY
// configuration, which the requesthandle will inherit
// from the session).
//
if( WinHttpGetProxyForUrl( hHttpSession,
L"https://www.microsoft.com/ms.htm",
&AutoProxyOptions,
&ProxyInfo))
{
// A proxy configuration was found, set it on the
// request handle.
if( !WinHttpSetOption( hRequest,
WINHTTP_OPTION_PROXY,
&ProxyInfo,
cbProxyInfoSize ) )
{
// Exit if setting the proxy info failed.
goto Exit;
}
}
//
// Send the request.
//
if( !WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
WINHTTP_NO_REQUEST_DATA,
0,
0,
NULL ) )
{
// Exit if WinHttpSendRequest failed.
goto Exit;
}
//
// Wait for the response.
//
if( !WinHttpReceiveResponse( hRequest, NULL ) )
goto Exit;
//
// A response has been received, then process it.
// (omitted)
//
Exit:
//
// Clean up the WINHTTP_PROXY_INFO structure.
//
if( ProxyInfo.lpszProxy != NULL )
GlobalFree(ProxyInfo.lpszProxy);
if( ProxyInfo.lpszProxyBypass != NULL )
GlobalFree( ProxyInfo.lpszProxyBypass );
//
// Close the WinHTTP handles.
//
if( hRequest != NULL )
WinHttpCloseHandle( hRequest );
if( hConnect != NULL )
WinHttpCloseHandle( hConnect );
if( hHttpSession != NULL )
WinHttpCloseHandle( hHttpSession );
Dalam kode contoh yang disediakan, panggilan ke WinHttpGetProxyForUrl menginstruksikan fungsi untuk menemukan file konfigurasi otomatis proksi secara otomatis dengan menentukan bendera WINHTTP_AUTOPROXY_AUTO_DETECT dalam struktur WINHTTP_AUTOPROXY_OPTIONS . Penggunaan bendera WINHTTP_AUTOPROXY_AUTO_DETECT memerlukan kode untuk menentukan salah satu atau kedua bendera deteksi otomatis (WINHTTP_AUTO_DETECT_TYPE_DHCP, WINHTTP_AUTO_DETECT_TYPE_DNS_A). Kode contoh menggunakan fitur deteksi otomatis WinHttpGetProxyForUrl karena URL PAC tidak diketahui sebelumnya. Jika URL PAC tidak dapat ditemukan di jaringan dalam skenario ini, WinHttpGetProxyForUrl gagal (GetLastError mengembalikan ERROR_WINHTTP_AUTODETECTION_FAILED).
Jika URL PAC Diketahui sebelumnya
Jika aplikasi mengetahui URL PAC, aplikasi dapat menentukannya dalam struktur WINHTTP_AUTOPROXY_OPTIONS dan mengonfigurasi WinHttpGetProxyForUrl untuk melewati fase deteksi otomatis.
Misalnya, jika file PAC tersedia di jaringan lokal di URL, "https://InternalSite/proxy-config.pac", panggilan ke WinHttpGetProxyForUrl akan terlihat seperti berikut ini.
//
// Set up the autoproxy call.
//
// The proxy auto-config URL is known. Auto-detection
// is not required.
AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
// Set the proxy auto-config URL.
AutoProxyOptions. lpszAutoConfigUrl = L"https://InternalSite/proxy-config.pac";
// If obtaining the PAC script requires NTLM/Negotiate
// authentication, then automatically supply the client
// domain credentials.
AutoProxyOptions.fAutoLogonIfChallenged = TRUE;
//
// Call WinHttpGetProxyForUrl with our target URL. If auto-proxy
// succeeds, then set the proxy info on the request handle.
// If auto-proxy fails, ignore the error and attempt to send the
// HTTP request directly to the target server (using the default
// WINHTTP_ACCESS_TYPE_NO_PROXY configuration, which the request
// handle will inherit from the session).
//
if( WinHttpGetProxyForUrl( hHttpSession,
L"https://www.microsoft.com/ms.htm",
&AutoProxyOptions,
&ProxyInfo ) )
{
//...
Jika struktur WINHTTP_AUTOPROXY_OPTIONS menentukan bendera WINHTTP_AUTOPROXY_AUTO_DETECT dan WINHTTP_AUTOPROXY_CONFIG_URL (dan menentukan bendera detksi otomatis dan URL konfigurasi otomatis), WinHttpGetProxyForUrl terlebih dahulu mencoba deteksi otomatis, lalu, jika deteksi otomatis gagal menemukan URL PAC, "mundur" ke URL konfigurasi otomatis yang disediakan oleh aplikasi.
Fungsi WinHttpDetectAutoProxyConfigUrl
Fungsi WinHttpDetectAutoProxyConfigUrl mengimplementasikan subset protokol WPAD: ia mencoba mendeteksi secara otomatis URL untuk file konfigurasi otomatis proksi, tanpa mengunduh atau menjalankan file PAC. Fungsi ini berguna dalam situasi khusus di mana aplikasi klien Web harus menangani pengunduhan dan eksekusi file PAC itu sendiri.
Fungsi WinHttpGetIEProxyConfigForCurrentUser
Fungsi WinHttpGetIEProxyConfigForCurrentUser mengembalikan pengaturan proksi Internet Explorer pengguna saat ini untuk koneksi jaringan aktif saat ini, tanpa memanggil "WinInet.dll". Fungsi ini hanya berguna ketika dipanggil dalam proses yang berjalan di bawah identitas akun pengguna interaktif, karena tidak ada konfigurasi proksi Internet Explorer yang kemungkinan tersedia sebaliknya. Misalnya, tidak akan berguna untuk memanggil fungsi ini dari ISAPI DLL yang berjalan dalam proses layanan IIS. Untuk informasi selengkapnya dan skenario di mana aplikasi berbasis WinHTTP akan menggunakan WinHttpGetIEProxyConfigForCurrentUser, lihat Penemuan Tanpa File Konfigurasi Otomatis.