Bagikan melalui


Porting Aplikasi WinINet ke WinHTTP

Microsoft Windows HTTP Services (WinHTTP) ditargetkan pada aplikasi server tingkat menengah dan back-end yang memerlukan akses ke tumpukan klien HTTP. Microsoft Windows Internet (WinINet) menyediakan tumpukan klien HTTP untuk aplikasi klien, serta akses ke protokol File Transfer Protocol (FTP), SOCKSv4, dan Gopher. Gambaran umum ini dapat membantu menentukan apakah porting aplikasi WinINet Anda ke WinHTTP akan bermanfaat. Ini juga menjelaskan persyaratan konversi tertentu.

Hal-hal yang Perlu Dipertimbangkan Sebelum Porting Aplikasi WinINet Anda

Pertimbangkan untuk memindahkan aplikasi WinINet Anda ke WinHTTP jika aplikasi Anda akan mendapat manfaat dari:

  • Tumpukan klien HTTP yang aman untuk server.
  • Penggunaan tumpukan yang diminimalkan.
  • Skalabilitas aplikasi server.
  • Lebih sedikit dependensi pada API terkait platform.
  • Dukungan untuk penggandaan identitas utas.
  • Tumpukan HTTP yang ramah terhadap layanan.
  • Akses ke objekWinHttpRequestyang dapat ditulis.

Jangan pertimbangkan untuk memindahkan aplikasi WinINet Anda ke WinHTTP jika harus mendukung satu atau beberapa hal berikut:

  • Protokol FTP atau Gopher yang merupakan bagian dari stack HTTP.
  • Dukungan untuk protokol SOCKSv4 untuk berkomunikasi dengan proksi SOCKS.
  • Layanan sambungan internet otomatis.

Jika Anda memutuskan untuk memindahkan aplikasi Anda ke WinHTTP, bagian berikut memandu Anda melalui proses konversi.

Untuk aplikasi sampel untuk WinINet dan WinHTTP, bandingkan sampel AsyncDemo untuk WinINet dengan sampel AsyncDemo untuk WinHTTP.

WinHTTP Setara dengan Fungsi WinINet

Tabel berikut mencantumkan fungsi WinINet yang terkait dengan tumpukan klien HTTP bersama dengan setara WinHTTP.

Jika aplikasi Anda memerlukan fungsi WinINet yang tidak tercantum, jangan port aplikasi Anda ke WinHTTP.

Fungsi WinINet WinHTTP yang setara dengan Perubahan penting
HttpAddRequestHeaders WinHttpAddRequestHeaders Tidak.
HttpEndRequest WinHttpReceiveResponse Nilai konteks diatur dengan WinHttpSendRequest atau WinHttpSetOption. Opsi permintaan diatur dengan WinHttpOpenRequest. WinHttpReceiveResponse harus dipanggil setelah mengirim permintaan.
httpOpenRequest WinHttpOpenRequest Nilai konteks diatur dengan WinHttpSendRequest atau WinHttpSetOption.
HttpQueryInfo WinHttpQueryHeaders Tidak.
HttpSendRequest WinHttpSendRequest Nilai konteks dapat diatur dengan WinHttpSendRequest.
httpSendRequestEx WinHttpSendRequest Buffer tidak dapat disediakan.
InternetCanonicalizeUrl Tidak ada yang setara URL sekarang dimasukkan ke dalam bentuk kanonis dalam WinHttpOpenRequest.
InternetCheckConnection Tidak ada yang setara Tidak diimplementasikan di WinHTTP.
InternetCloseHandle WinHttpCloseHandle Menutup handel induk di WinHTTP tidak menutup handel turunan secara rekursif.
InternetCombineUrl Tidak ada yang setara URL dapat dirakit dengan fungsiWinHttpCreateUrl.
KonfirmasiZonaLintasInternet Tidak ada yang setara Tidak diimplementasikan di WinHTTP.
KoneksiInternet WinHttpConnect Nilai konteks diatur dengan WinHttpSendRequest atau WinHttpSetOption. Opsi permintaan diatur dengan WinHttpOpenRequest. Kredensial pengguna diatur dengan WinHttpSetCredentials.
InternetCrackUrl WinHttpCrackUrl Perilaku berlawanan dari bendera ICU_ESCAPE: dengan InternetCrackUrl, bendera ini menyebabkan urutan escape (%xx) dikonversi menjadi karakter, tetapi dengan WinHttpCrackUrl, bendera ini menyebabkan karakter yang harus di-escape dalam permintaan HTTP dikonversi menjadi urutan escape.
InternetCreateUrl WinHttpCreateUrl Tidak.
InternetErrorDlg Tidak ada yang setara Karena WinHTTP ditargetkan pada aplikasi sisi server, WinHTTP tidak mengimplementasikan antarmuka pengguna apa pun.
InternetGetCookie Tidak ada yang setara WinHTTP tidak menyimpan data antar sesi dan tidak dapat mengakses cookie WinINet.
InternetTerbuka WinHttpOpen Tidak.
InternetOpenUrl WinHttpConnect, WinHttpOpenRequest, WinHttpSendRequest, WinHttpReceiveResponse Fungsionalitas ini tersedia dalam fungsi WinHTTP yang tercantum.
InternetQueryDataAvailable WinHttpQueryDataAvailable Tidak ada parameter yang dicadangkan.
OpsiKueriInternet WinHttpQueryOption WinHTTP menawarkan serangkaian opsi yang berbeda dari WinINet. Untuk informasi selengkapnya dan opsi yang ditawarkan oleh WinHTTP, lihat bendera Opsi .
InternetReadFile WinHttpReadData Tidak.
InternetReadFileEx WinHttpReadData Alih-alih struktur, buffer adalah wilayah memori yang ditujukan dengan pointer.
InternetSetOption WinHttpSetOption Tidak.
InternetSetStatusCallback WinHttpSetStatusCallback Untuk informasi selengkapnya, lihat "Penanganan Permintaan Asinkron yang Berbeda" dalam topik ini.
InternetTimeFromSystemTime WinHttpTimeFromSystemTime Tidak.
InternetTimeToSystemTime WinHttpTimeToSystemTime Tidak.
InternetWriteFile WinHttpWriteData Tidak.

 

Penanganan Permintaan Asinkron yang Berbeda

Ketahuilah bahwa di WinINet dan WinHTTP, beberapa fungsi dapat menyelesaikan permintaan asinkron baik secara sinkron atau asinkron. Aplikasi Anda harus menangani salah satu situasi. Ada perbedaan signifikan dalam cara WinINet dan WinHTTP menangani fungsi yang berpotensi asinkron ini.

WinINet

  • Penyelesaian sinkron: Jika panggilan fungsi WinINet yang berpotensi asinkron selesai secara sinkron, parameter OUT fungsi mengembalikan hasil operasi. Ketika kesalahan terjadi, ambil kode kesalahan dengan memanggil GetLastError setelah panggilan fungsi WinINet.

  • Penyelesaian asinkron: Jika panggilan fungsi yang berpotensi asinkron selesai secara asinkron, hasil operasi, dan kesalahan apa pun, dapat diakses dalam fungsi panggilan balik. Fungsi callback dijalankan pada thread pekerja, bukan pada thread yang melakukan panggilan fungsi awal.

Dengan kata lain, aplikasi Anda harus menduplikasi logika untuk menangani hasil operasi tersebut di dua tempat: baik segera setelah panggilan fungsi dan dalam fungsi panggilan balik.

WinHTTP menyederhanakan model ini dengan memungkinkan Anda menerapkan logika operasional hanya dalam fungsi panggilan balik, yang menerima pemberitahuan penyelesaian terlepas dari apakah operasi selesai secara sinkron atau asinkron. Ketika operasi asinkron diaktifkan, parameter OUT fungsi WinHTTP tidak mengembalikan data yang bermakna dan harus diatur ke NULL.

Satu-satunya perbedaan signifikan antara penyelesaian asinkron dan sinkron di WinHTTP, dari perspektif aplikasi, adalah di mana fungsi panggilan balik dijalankan.

WinHTTP

  • Penyelesaian sinkron: Ketika operasi selesai secara sinkron, hasilnya dikembalikan dalam fungsi panggilan balik yang dijalankan dalam utas yang sama dengan panggilan fungsi asli.

  • Penyelesaian asinkron: Ketika operasi selesai secara asinkron, hasilnya dikembalikan dalam fungsi callback yang dijalankan oleh utas pekerja.

Meskipun sebagian besar kesalahan dapat diatasi sepenuhnya dalam fungsi callback, aplikasi WinHTTP tetap harus siap untuk fungsi mengembalikan FALSE karena kesalahan ERROR_INVALID_PARAMETER atau kesalahan serupa lainnya yang didapat dengan memanggil GetLastError.

Tidak seperti WinINet, yang dapat menjalankan beberapa operasi asinkron secara bersamaan, WinHTTP memberlakukan kebijakan satu operasi asinkron yang tertunda per handel permintaan. Jika satu operasi tertunda dan fungsi WinHTTP lain dipanggil, fungsi kedua gagal dan GetLastError mengembalikan ERROR_INVALID_OPERATION.

WinHTTP menyederhanakan model ini dengan memungkinkan Anda menerapkan logika operasional hanya dalam fungsi panggilan balik, yang menerima pemberitahuan penyelesaian terlepas dari apakah operasi selesai secara sinkron atau asinkron. Ketika operasi asinkron diaktifkan, parameter OUT fungsi WinHTTP tidak mengembalikan data yang bermakna dan harus diatur ke NULL.

Perbedaan dalam Pemberitahuan Panggilan Balik WinHTTP

Fungsi panggilan balik status menerima pembaruan tentang status operasi melalui bendera pemberitahuan. Dalam WinHTTP, pemberitahuan dipilih menggunakan parameter dwNotificationFlags dalam fungsi WinHttpSetStatusCallback. Gunakan flag WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS untuk menerima pemberitahuan tentang semua pembaruan status.

Pemberitahuan yang menunjukkan operasi tertentu selesai disebut pemberitahuan penyelesaian, atau hanya penyelesaian. Di WinINet, setiap kali fungsi panggilan balik menerima penyelesaian, parameter lpvStatusInformation berisi struktur INTERNET_ASYNC_RESULT. Di WinHTTP, struktur ini tidak tersedia untuk semua proses penyelesaian. Penting untuk meninjau halaman referensi untuk WINHTTP_STATUS_CALLBACK, yang berisi informasi tentang pemberitahuan dan jenis data yang dapat diharapkan untuk masing-masing.

Di WinHTTP, satu penyelesaian tunggal, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, mengindikasikan bahwa suatu operasi telah gagal. Semua penyelesaian tugas lainnya menandakan operasi yang berhasil.

WinINet dan WinHTTP menggunakan nilai konteks yang ditentukan pengguna untuk meneruskan informasi dari utas utama ke fungsi panggilan balik status, yang dapat dijalankan pada utas pekerja. Di WinINet, nilai konteks yang digunakan oleh fungsi panggilan balik status diatur dengan memanggil salah satu dari beberapa fungsi. Di WinHTTP, nilai konteks diatur hanya dengan WinHttpSendRequest atau WinHttpSetOption. Karena itu, di WinHTTP dimungkinkan bahwa pemberitahuan dapat terjadi sebelum nilai konteks ditetapkan. Jika fungsi panggilan balik menerima pemberitahuan sebelum nilai konteks diatur, aplikasi harus siap untuk menerima null dalam parameter dwContext fungsi panggilan balik.

Perbedaan Autentikasi

Di WinINet, kredensial pengguna diatur dengan memanggil fungsiInternetSetOption, menggunakan kode yang mirip dengan yang disediakan dalam contoh kode berikut.

// Use the WinINet InternetSetOption function to set the 
// user credentials to the user name contained in strUsername 
// and the password to the contents of strPassword.
       
InternetSetOption( hRequest, INTERNET_OPTION_PROXY_USERNAME, 
                   strUsername, strlen(strUsername) + 1 );

InternetSetOption( hRequest, INTERNET_OPTION_PROXY_PASSWORD, 
                   strPassword, strlen(strPassword) + 1 );

Untuk kompatibilitas, kredensial pengguna juga dapat diatur di WinHTTP menggunakan fungsiWinHttpSetOption, tetapi ini tidak disarankan karena dapat menimbulkan kerentanan keamanan.

Sebagai gantinya, ketika aplikasi menerima kode status 401 di WinHTTP, metode yang direkomendasikan untuk mengatur kredensial adalah terlebih dahulu untuk mengidentifikasi skema autentikasi menggunakan WinHttpQueryAuthSchemes dan, kedua, mengatur kredensial menggunakan WinHttpSetCredentials. Contoh kode berikut menunjukkan cara melakukan ini.

DWORD dwSupportedSchemes;
DWORD dwPrefered;
DWORD dwTarget;

// Obtain the supported and first schemes.
WinHttpQueryAuthSchemes( hRequest, &dwSupportedSchemes, &dwPrefered, &dwTarget );

// Set the credentials before resending the request.
WinHttpSetCredentials( hRequest, dwTarget, dwPrefered, strUsername, strPassword, NULL );

Karena tidak ada yang setara dengan InternetErrorDlg di WinHTTP, aplikasi yang mendapatkan kredensial melalui antarmuka pengguna harus menyediakan antarmuka mereka sendiri.

Tidak seperti WinINet, WinHTTP tidak menyimpan kata sandi. Kredensial pengguna yang valid harus disediakan untuk setiap permintaan.

WinHTTP tidak mendukung skema Autentikasi Kata Sandi Terdistribusi (DPA) yang didukung oleh WinINet. Namun, WinHTTP mendukung Microsoft Passport 1.4. Untuk informasi selengkapnya tentang menggunakan autentikasi Paspor di WinHTTP, lihat Autentikasi Paspor di WinHTTP.

WinHTTP tidak mengandalkan pengaturan Internet Explorer untuk menentukan kebijakan masuk otomatis. Sebagai gantinya, kebijakan log masuk otomatis diatur dengan WinHttpSetOption. Untuk informasi selengkapnya tentang autentikasi di WinHTTP, termasuk kebijakan masuk otomatis, lihat Autentikasi di WinHTTP.

Perbedaan dalam Transaksi HTTP Aman

Di WinINet, mulai sesi aman menggunakan HttpOpenRequest atau InternetConnect, tetapi di WinHTTP, Anda harus memanggil WinHttpOpenRequest menggunakan bendera WINHTTP_FLAG_SECURE.

Dalam transaksi HTTP yang aman, sertifikat server dapat digunakan untuk mengautentikasi server ke klien. Di WinINet, jika sertifikat server berisi kesalahan, HttpSendRequest gagal dan memberikan detail tentang kesalahan sertifikat.

Di WinHttp, kesalahan sertifikat server ditangani sesuai dengan versi sebagai berikut:

  • Dimulai dengan WinHttp 5.1, jika sertifikat server gagal atau berisi kesalahan, panggilan ke WinHttpSendRequest melaporkan WINHTTP_CALLBACK_STATUS_SECURE_FAILURE dalam fungsi panggilan balik. Jika kesalahan yang dihasilkan oleh WinHttpSendRequest diabaikan, panggilan berikutnya ke WinHttpReceiveResponse gagal dengan kesalahan ERROR_WINHTTP_OPERATION_CANCELLED.
  • Di WinHTTP 5.0, kesalahan dalam sertifikat server tidak, secara default, menyebabkan permintaan gagal. Sebagai gantinya, kesalahan dilaporkan dalam fungsi callback dengan notifikasi WINHTTP_CALLBACK_STATUS_SECURE_FAILURE.

Pada beberapa platform sebelumnya, WinINet mendukung protokol Private Communication Technology (PCT) dan/atau Fortezza, meskipun tidak pada Windows XP.

WinHTTP tidak mendukung protokol PCT dan Fortezza pada platform apa pun, dan sebaliknya bergantung pada Secure Sockets Layer (SSL) 2.0, SSL 3.0, atau Transport Layer Security (TLS) 1.0.