Condividi tramite


Conversione di applicazioni WinINet in WinHTTP

Microsoft Windows HTTP Services (WinHTTP) è destinato a applicazioni server di livello intermedio e back-end che richiedono l'accesso a uno stack client HTTP. Microsoft Windows Internet (WinINet) offre uno stack client HTTP per le applicazioni client, nonché l'accesso al protocollo FTP (File Transfer Protocol), SOCKSv4 e Gopher. Questa panoramica può aiutare a determinare se la conversione delle applicazioni WinINet in WinHTTP sarebbe utile. Descrive anche requisiti di conversione specifici.

Operazioni da prendere in considerazione prima di convertire l'applicazione WinINet

Prendere in considerazione la conversione dell'applicazione WinINet in WinHTTP se l'applicazione può trarre vantaggio da:

  • Stack client HTTP sicuro del server.
  • Utilizzo dello stack ridotto al minimo.
  • Scalabilità di un'applicazione server.
  • Meno dipendenze sulle API correlate alla piattaforma.
  • Supporto per la rappresentazione del thread.
  • Stack HTTP descrittivo del servizio.
  • Accesso all'oggetto WinHttpRequest scriptable.

Non prendere in considerazione la conversione dell'applicazione WinINet in WinHTTP se deve supportare uno o più dei seguenti elementi:

  • Protocollo FTP o Gopher dallo stack HTTP.
  • Supporto per il protocollo SOCKSv4 per la comunicazione con i proxy SOCKS.
  • Servizi automatici di accesso esterno.

Se si decide di convertire l'applicazione in WinHTTP, le sezioni seguenti illustrano il processo di conversione.

Per un'applicazione di esempio per WinINet e WinHTTP, confrontare l'esempio AsyncDemo per WinINet con l'esempio AsyncDemo per WinHTTP.

WinHTTP equivalenti alle funzioni WinINet

La tabella seguente elenca le funzioni WinINet correlate allo stack client HTTP insieme agli equivalenti WinHTTP.

Se l'applicazione richiede funzioni WinINet non elencate, non convertire l'applicazione in WinHTTP.

Funzione WinINet WinHTTP equivalente Modifiche rilevanti
HttpAddRequestHeaders WinHttpAddRequestHeaders Nessuno.
HttpEndRequest WinHttpReceiveResponse Il valore di contesto viene impostato con WinHttpSendRequest o WinHttpSetOption. Le opzioni di richiesta vengono impostate con WinHttpOpenRequest. WinHttpReceiveResponse deve essere chiamato dopo l'invio di una richiesta.
HttpOpenRequest WinHttpOpenRequest Il valore di contesto viene impostato con WinHttpSendRequest o WinHttpSetOption.
HttpQueryInfo WinHttpQueryHeaders Nessuno.
HttpSendRequest WinHttpSendRequest Il valore di contesto può essere impostato con WinHttpSendRequest.
HttpSendRequestEx WinHttpSendRequest I buffer non possono essere forniti.
InternetCanonicalizeUrl Nessun equivalente Gli URL vengono ora inseriti in forma canonica in WinHttpOpenRequest.
InternetCheckConnection Nessun equivalente Non implementato in WinHTTP.
InternetCloseHandle WinHttpCloseHandle La chiusura di un handle padre in WinHTTP non chiude in modo ricorsivo handle figlio.
InternetCombineUrl Nessun equivalente Gli URL possono essere assemblati con la funzione WinHttpCreateUrl .
InternetConfirmZoneCrossing Nessun equivalente Non implementato in WinHTTP.
InternetConnect WinHttpConnect Il valore di contesto viene impostato con WinHttpSendRequest o WinHttpSetOption. Le opzioni di richiesta vengono impostate con WinHttpOpenRequest. Le credenziali utente vengono impostate con WinHttpSetCredentials.
InternetCrackUrl WinHttpCrackUrl Comportamento opposto del flag di ICU_ESCAPE: con InternetCrackUrl, questo flag causa la conversione di sequenze di escape (%xx) in caratteri, ma con WinHttpCrackUrl, causa l'escape dei caratteri da una richiesta HTTP in sequenze di escape.
InternetCreateUrl WinHttpCreateUrl Nessuno.
InternetErrorDlg Nessun equivalente Poiché WinHTTP è destinato alle applicazioni lato server, non implementa alcuna interfaccia utente.
InternetGetCookie Nessun equivalente WinHTTP non mantiene i dati tra sessioni e non può accedere ai cookie WinINet.
InternetOpen WinHttpOpen Nessuno.
Internetopenurl WinHttpConnect, WinHttpOpenRequest, WinHttpSendRequest, WinHttpReceiveResponse Questa funzionalità è disponibile nelle funzioni WinHTTP elencate.
InternetQueryDataAvailable WinHttpQueryDataAvailable Nessun parametro riservato.
InternetQueryOption WinHttpQueryOption WinHTTP offre un set di opzioni diverso da WinINet. Per altre informazioni e opzioni offerte da WinHTTP, vedere Flag di opzione.
InternetReadFile WinHttpReadData Nessuno.
InternetReadFileEx WinHttpReadData Anziché una struttura, il buffer è un'area di memoria indirizzata con un puntatore.
Internetsetoption WinHttpSetOption Nessuno.
InternetSetStatusCallback WinHttpSetStatusCallback Per altre informazioni, vedere "Gestione diversa delle richieste asincrone" in questo argomento.
InternetTimeFromSystemTime WinHttpTimeFromSystemTime Nessuno.
InternetTimeToSystemTime WinHttpTimeToSystemTime Nessuno.
InternetWriteFile WinHttpWriteData Nessuno.

 

Gestione diversa delle richieste asincrone

Tenere presente che in WinINet e WinHTTP alcune funzioni possono completare richieste asincrone in modo sincrono o asincrono. L'applicazione deve gestire entrambe le situazioni. Esistono differenze significative nel modo in cui WinINet e WinHTTP gestiscono queste funzioni potenzialmente asincrone.

Wininet

  • Completamento sincrono: se una chiamata di funzione WinINet potenzialmente asincrona completa in modo sincrono, i parametri OUT della funzione restituiscono i risultati dell'operazione. Quando si verifica un errore, recuperare il codice di errore chiamando GetLastError dopo la chiamata alla funzione WinINet.

  • Completamento asincrono: se una chiamata di funzione potenzialmente asincrona viene completata in modo asincrono, i risultati dell'operazione e eventuali errori, sono accessibili nella funzione di callback. La funzione di callback viene eseguita in un thread di lavoro, non nel thread che ha effettuato la chiamata iniziale alla funzione.

In altre parole, l'applicazione deve duplicare la logica per gestire i risultati di tali operazioni in due posizioni: entrambe dopo la chiamata alla funzione e nella funzione di callback.

WinHTTP semplifica questo modello consentendo di implementare la logica operativa solo nella funzione di callback, che riceve una notifica di completamento indipendentemente dal fatto che l'operazione sia stata completata in modo sincrono o asincrono. Quando l'operazione asincrona è abilitata, i parametri OUT delle funzioni WinHTTP non restituiscono dati significativi e devono essere impostati su NULL.

L'unica differenza significativa tra il completamento asincrono e sincrono in WinHTTP, dal punto di vista dell'applicazione, si trova in cui viene eseguita la funzione di callback.

WinHTTP

  • Completamento sincrono: quando un'operazione completa in modo sincrono, i risultati vengono restituiti in una funzione di callback che viene eseguita nello stesso thread della chiamata di funzione originale.

  • Completamento asincrono: quando un'operazione viene completata in modo asincrono, i risultati vengono restituiti in una funzione di callback che viene eseguita in un thread di lavoro.

Anche se la maggior parte degli errori può essere gestita interamente all'interno della funzione di callback, le applicazioni WinHTTP devono comunque essere preparate per restituire false a causa di un ERROR_INVALID_PARAMETER o di un altro errore simile recuperato chiamando GetLastError.

A differenza di WinINet, che può eseguire più operazioni asincrone contemporaneamente, WinHTTP applica un criterio di un'operazione asincrona in sospeso per ogni handle di richiesta. Se un'operazione è in sospeso e viene chiamata un'altra funzione WinHTTP, la seconda funzione ha esito negativo e GetLastError restituisce ERROR_INVALID_OPERATION.

WinHTTP semplifica questo modello consentendo di implementare la logica operativa solo nella funzione di callback, che riceve una notifica di completamento indipendentemente dal fatto che l'operazione sia stata completata in modo sincrono o asincrono. Quando l'operazione asincrona è abilitata, i parametri OUT delle funzioni WinHTTP non restituiscono dati significativi e devono essere impostati su NULL.

Differenze nelle notifiche di callback WinHTTP

La funzione di callback di stato riceve gli aggiornamenti sullo stato delle operazioni tramite flag di notifica. In WinHTTP le notifiche vengono selezionate usando il parametro dwNotificationFlags della funzione WinHttpSetStatusCallback . Usare il flag WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS per ricevere una notifica di tutti gli aggiornamenti dello stato.

Le notifiche che indicano che un'operazione specifica è completa sono chiamate notifiche di completamento o solo completamento. In WinINet ogni volta che la funzione di callback riceve un completamento, il parametro lpvStatusInformation contiene una struttura INTERNET_ASYNC_RESULT . In WinHTTP questa struttura non è disponibile per tutti i completamento. È importante esaminare la pagina di riferimento per WINHTTP_STATUS_CALLBACK, che contiene informazioni sulle notifiche e sul tipo di dati che possono essere previsti per ogni oggetto.

In WinHTTP un singolo completamento, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, indica che un'operazione non è riuscita. Tutti gli altri completamento indicano un'operazione riuscita.

Sia WinINet che WinHTTP usano un valore di contesto definito dall'utente per passare informazioni dal thread principale alla funzione di callback di stato, che può essere eseguita in un thread di lavoro. In WinINet il valore di contesto utilizzato dalla funzione di callback di stato viene impostato chiamando una delle diverse funzioni. In WinHTTP il valore di contesto viene impostato solo con WinHttpSendRequest o WinHttpSetOption. A causa di questo, è possibile che in WinHTTP venga eseguita una notifica prima che venga impostato un valore di contesto. Se la funzione callback riceve una notifica prima dell'impostazione del valore di contesto, l'applicazione deve essere preparata per ricevere NULL nel parametro dwContext della funzione callback.

Differenze di autenticazione

In WinINet le credenziali utente vengono impostate chiamando la funzione InternetSetOption usando codice simile a quello fornito nell'esempio di codice seguente.

// 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 );

Per la compatibilità, le credenziali utente possono essere impostate in Modo analogo in WinHTTP usando la funzione WinHttpSetOption , ma non è consigliabile perché può rappresentare una vulnerabilità di sicurezza.

Quando un'applicazione riceve invece un codice di stato 401 in WinHTTP, il metodo consigliato per impostare le credenziali consiste innanzitutto nell'identificare uno schema di autenticazione usando WinHttpQueryAuthSchemes e, secondo, impostare le credenziali usando WinHttpSetCredentials. Nell'esempio di codice seguente viene illustrato come eseguire questa operazione.

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 );

Poiché non esiste alcun equivalente a InternetErrorDlg in WinHTTP, le applicazioni che ottengono le credenziali tramite un'interfaccia utente devono fornire la propria interfaccia.

A differenza di WinINet, WinHTTP non memorizza nella cache le password. Le credenziali utente valide devono essere fornite per ogni richiesta.

WinHTTP non supporta lo schema DPA (Distributed Password Authentication) supportato da WinINet. WinHTTP supporta tuttavia Microsoft Passport 1.4. Per altre informazioni sull'uso dell'autenticazione Passport in WinHTTP, vedere Autenticazione passport in WinHTTP.

WinHTTP non si basa sulle impostazioni di Internet Explorer per determinare i criteri di accesso automatici. Il criterio di accesso automatico viene invece impostato con WinHttpSetOption. Per altre informazioni sull'autenticazione in WinHTTP, inclusi i criteri di accesso automatico, vedere Autenticazione in WinHTTP.

Differenze nelle transazioni HTTP sicure

In WinINet avviare una sessione sicura usando HttpOpenRequest o InternetConnect, ma in WinHTTP è necessario chiamare WinHttpOpenRequest usando il flag WINHTTP_FLAG_SECURE .

In una transazione HTTP sicura, i certificati del server possono essere usati per autenticare un server nel client. In WinINet, se un certificato server contiene errori, HttpSendRequest ha esito negativo e fornisce informazioni dettagliate sugli errori del certificato.

In WinHttp gli errori del certificato del server vengono gestiti in base alla versione come indicato di seguito:

  • A partire da WinHttp 5.1, se un certificato server ha esito negativo o contiene errori, la chiamata a WinHttpSendRequest segnala un WINHTTP_CALLBACK_STATUS_SECURE_FAILURE nella funzione di callback. Se l'errore generato da WinHttpSendRequest viene ignorato, le chiamate successive a WinHttpReceiveResponse hanno esito negativo con un errore di ERROR_WINHTTP_OPERATION_CANCELLED.
  • In WinHTTP 5.0 gli errori nei certificati del server non, per impostazione predefinita, causano l'esito negativo di una richiesta. Gli errori vengono invece segnalati nella funzione callback con la notifica di WINHTTP_CALLBACK_STATUS_SECURE_FAILURE .

In alcune piattaforme precedenti, WinINet supportava i protocolli PRIVATE Communication Technology (PCT) e/o Fortezza, anche se non in Windows XP.

WinHTTP non supporta i protocolli PCT e Fortezza in qualsiasi piattaforma e si basa invece su Secure Sockets Layer (SSL) 2.0, SSL 3.0 o Transport Layer Security (TLS) 1.0.