Compartir a través de


Portabilidad de aplicaciones WinINet a WinHTTP

Los servicios HTTP de Microsoft Windows (WinHTTP) están destinados a aplicaciones de servidor de nivel intermedio y back-end que requieren acceso a una pila de cliente HTTP. Microsoft Windows Internet (WinINet) proporciona una pila de cliente HTTP para aplicaciones cliente, así como acceso al protocolo de transferencia de archivos (FTP), SOCKSv4 y protocolos Gopher. Esta introducción puede ayudar a determinar si la portabilidad de las aplicaciones WinINet a WinHTTP sería beneficiosa. También se describen requisitos de conversión específicos.

Aspectos que hay que tener en cuenta antes de migrar la aplicación WinINet

Considere la posibilidad de migrar la aplicación WinINet a WinHTTP si la aplicación se beneficiaría de:

  • Una pila de cliente HTTP segura para el servidor.
  • Uso minimizado de la pila.
  • Escalabilidad de una aplicación de servidor.
  • Menos dependencias en las API relacionadas con la plataforma.
  • Compatibilidad con la suplantación de subprocesos.
  • Una pila HTTP fácil de usar.
  • Acceso al objeto WinHttpRequest que admite scripts.

No considere la posibilidad de migrar la aplicación WinINet a WinHTTP si debe admitir una o varias de las siguientes opciones:

  • Protocolo FTP o Gopher de la pila HTTP.
  • Compatibilidad con el protocolo SOCKSv4 para comunicarse con servidores proxy SOCKS.
  • Servicios de acceso telefónico automático.

Si decide migrar la aplicación a WinHTTP, las secciones siguientes le guiarán a través del proceso de conversión.

Para una aplicación de ejemplo para WinINet y WinHTTP, compare el ejemplo AsyncDemo para WinINet con el ejemplo AsyncDemo para WinHTTP.

Equivalentes de WinHTTP a funciones de WinINet

En la tabla siguiente se enumeran las funciones de WinINet relacionadas con la pila de cliente HTTP junto con los equivalentes de WinHTTP.

Si la aplicación requiere funciones winINet que no aparecen en la lista, no portar la aplicación a WinHTTP.

Función WinINet Equivalente a WinHTTP Cambios importantes
HttpAddRequestHeaders WinHttpAddRequestHeaders Ninguno.
HttpEndRequest WinHttpReceiveResponse El valor de contexto se establece con WinHttpSendRequest o WinHttpSetOption. Las opciones de solicitud se establecen con WinHttpOpenRequest. Se debe llamar a WinHttpReceiveResponse después de enviar una solicitud.
HttpOpenRequest WinHttpOpenRequest El valor de contexto se establece con WinHttpSendRequest o WinHttpSetOption.
HttpQueryInfo WinHttpQueryHeaders Ninguno.
HttpSendRequest WinHttpSendRequest El valor de contexto se puede establecer con WinHttpSendRequest.
HttpSendRequestEx WinHttpSendRequest No se pueden proporcionar búferes.
InternetCanonicalizeUrl No equivalente Las direcciones URL ahora se colocan en forma canónica en WinHttpOpenRequest.
InternetCheckConnection No equivalente No se implementa en WinHTTP.
InternetCloseHandle WinHttpCloseHandle Cerrar un identificador primario en WinHTTP no cierra de forma recursiva los identificadores secundarios.
InternetCombineUrl No equivalente Las direcciones URL se pueden ensamblar con la función WinHttpCreateUrl .
InternetConfirmZoneCrossing No equivalente No se implementa en WinHTTP.
InternetConnect WinHttpConnect El valor de contexto se establece con WinHttpSendRequest o WinHttpSetOption. Las opciones de solicitud se establecen con WinHttpOpenRequest. Las credenciales de usuario se establecen con WinHttpSetCredentials.
InternetCrackUrl WinHttpCrackUrl Comportamiento opuesto de la marca de ICU_ESCAPE: con InternetCrackUrl, esta marca hace que las secuencias de escape (%xx) se conviertan en caracteres, pero con WinHttpCrackUrl, hace que los caracteres que se deben escapar de en una solicitud HTTP se conviertan en secuencias de escape.
InternetCreateUrl WinHttpCreateUrl Ninguno.
InternetErrorDlg No equivalente Dado que WinHTTP está destinado a aplicaciones del lado servidor, no implementa ninguna interfaz de usuario.
InternetGetCookie No equivalente WinHTTP no conserva los datos entre sesiones y no puede acceder a las cookies de WinINet.
InternetOpen WinHttpOpen Ninguno.
InternetOpenUrl WinHttpConnect, WinHttpOpenRequest, WinHttpSendRequest, WinHttpReceiveResponse Esta funcionalidad está disponible en las funciones WinHTTP enumeradas.
InternetQueryDataAvailable WinHttpQueryDataAvailable No hay parámetros reservados.
InternetQueryOption WinHttpQueryOption WinHTTP ofrece un conjunto diferente de opciones de WinINet. Para obtener más información y opciones ofrecidas por WinHTTP, consulte Marcas de opción.
InternetReadFile WinHttpReadData Ninguno.
InternetReadFileEx WinHttpReadData En lugar de una estructura, el búfer es una región de memoria dirigida con un puntero.
InternetSetOption WinHttpSetOption Ninguno.
InternetSetStatusCallback WinHttpSetStatusCallback Para obtener más información, vea "Control diferente de solicitudes asincrónicas" en este tema.
InternetTimeFromSystemTime WinHttpTimeFromSystemTime Ninguno.
InternetTimeToSystemTime WinHttpTimeToSystemTime Ninguno.
InternetWriteFile WinHttpWriteData Ninguno.

 

Control diferente de solicitudes asincrónicas

Tenga en cuenta que en WinINet y WinHTTP, algunas funciones pueden completar solicitudes asincrónicas de forma sincrónica o asincrónica. La aplicación debe controlar cualquiera de las situaciones. Hay diferencias significativas en la forma en que WinINet y WinHTTP controlan estas funciones potencialmente asincrónicas.

Wininet

  • Finalización sincrónica: si una llamada de función WinINet potencialmente asincrónica se completa de forma sincrónica, los parámetros OUT de la función devuelven los resultados de la operación. Cuando se produce un error, recupere el código de error llamando a GetLastError después de la llamada a la función WinINet.

  • Finalización asincrónica: si una llamada de función potencialmente asincrónica se completa de forma asincrónica, los resultados de la operación y los errores son accesibles en la función de devolución de llamada. La función de devolución de llamada se ejecuta en un subproceso de trabajo, no en el subproceso que realizó la llamada de función inicial.

En otras palabras, la aplicación debe duplicar la lógica para controlar los resultados de estas operaciones en dos lugares: ambos inmediatamente después de la llamada de función y en la función de devolución de llamada.

WinHTTP simplifica este modelo al permitirle implementar la lógica operativa solo en la función de devolución de llamada, que recibe una notificación de finalización independientemente de si la operación se completó de forma sincrónica o asincrónica. Cuando se habilita la operación asincrónica, los parámetros OUT de las funciones WinHTTP no devuelven datos significativos y deben establecerse en NULL.

La única diferencia significativa entre la finalización asincrónica y sincrónica en WinHTTP, desde la perspectiva de la aplicación, es donde se ejecuta la función de devolución de llamada.

WinHTTP

  • Finalización sincrónica: cuando una operación se completa de forma sincrónica, los resultados se devuelven en una función de devolución de llamada que se ejecuta en el mismo subproceso que la llamada de función original.

  • Finalización asincrónica: cuando una operación se completa de forma asincrónica, los resultados se devuelven en una función de devolución de llamada que se ejecuta en un subproceso de trabajo.

Aunque la mayoría de los errores también se pueden controlar completamente dentro de la función de devolución de llamada, las aplicaciones WinHTTP deben estar preparadas para que una función devuelva FALSE debido a un ERROR_INVALID_PARAMETER u otro error similar recuperado llamando a GetLastError.

A diferencia de WinINet, que puede ejecutar varias operaciones asincrónicas simultáneamente, WinHTTP aplica una directiva de una operación asincrónica pendiente por identificador de solicitud. Si hay una operación pendiente y se llama a otra función WinHTTP, se produce un error en la segunda función y GetLastError devuelve ERROR_INVALID_OPERATION.

WinHTTP simplifica este modelo al permitirle implementar la lógica operativa solo en la función de devolución de llamada, que recibe una notificación de finalización independientemente de si la operación se completó de forma sincrónica o asincrónica. Cuando se habilita la operación asincrónica, los parámetros OUT de las funciones WinHTTP no devuelven datos significativos y deben establecerse en NULL.

Diferencias en las notificaciones de devolución de llamada winHTTP

La función de devolución de llamada de estado recibe actualizaciones sobre el estado de las operaciones a través de marcas de notificación. En WinHTTP, las notificaciones se seleccionan mediante el parámetro dwNotificationFlags de la función WinHttpSetStatusCallback . Use la marca WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS para recibir una notificación de todas las actualizaciones de estado.

Las notificaciones que indican que se ha completado una operación determinada se denominan notificaciones de finalización o simplemente finalizaciones. En WinINet, cada vez que la función de devolución de llamada recibe una finalización, el parámetro lpvStatusInformation contiene una estructura de INTERNET_ASYNC_RESULT . En WinHTTP, esta estructura no está disponible para todas las finalizaciones. Es importante revisar la página de referencia para WINHTTP_STATUS_CALLBACK, que contiene información sobre las notificaciones y qué tipo de datos se puede esperar para cada uno.

En WinHTTP, una sola finalización, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, indica que se produjo un error en una operación. Todas las demás finalizaciones indican una operación correcta.

WinINet y WinHTTP usan un valor de contexto definido por el usuario para pasar información del subproceso principal a la función de devolución de llamada de estado, que se puede ejecutar en un subproceso de trabajo. En WinINet, el valor de contexto usado por la función de devolución de llamada de estado se establece mediante una llamada a una de varias funciones. En WinHTTP, el valor de contexto solo se establece con WinHttpSendRequest o WinHttpSetOption. Por este motivo, es posible que en WinHTTP se produzca una notificación antes de establecer un valor de contexto. Si la función de devolución de llamada recibe una notificación antes de establecer el valor de contexto, la aplicación debe estar preparada para recibir NULL en el parámetro dwContext de la función de devolución de llamada.

Diferencias de autenticación

En WinINet, las credenciales de usuario se establecen mediante una llamada a la función InternetSetOption , con código similar al proporcionado en el ejemplo de código siguiente.

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

Por motivos de compatibilidad, las credenciales de usuario se pueden establecer de forma similar en WinHTTP mediante la función WinHttpSetOption , pero esto no se recomienda porque puede suponer una vulnerabilidad de seguridad.

En su lugar, cuando una aplicación recibe un código de estado 401 en WinHTTP, el método recomendado de establecer credenciales es primero para identificar un esquema de autenticación mediante WinHttpQueryAuthSchemes y, en segundo lugar, establecer las credenciales mediante WinHttpSetCredentials. En el ejemplo de código siguiente se muestra cómo hacerlo.

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

Dado que no hay ningún equivalente a InternetErrorDlg en WinHTTP, las aplicaciones que obtienen credenciales a través de una interfaz de usuario deben proporcionar su propia interfaz.

A diferencia de WinINet, WinHTTP no almacena en caché las contraseñas. Se deben proporcionar credenciales de usuario válidas para cada solicitud.

WinHTTP no admite el esquema de autenticación de contraseña distribuida (DPA) compatible con WinINet. Sin embargo, WinHTTP admite Microsoft Passport 1.4. Para obtener más información sobre el uso de la autenticación de Passport en WinHTTP, consulte Autenticación de Passport en WinHTTP.

WinHTTP no se basa en la configuración de Internet Explorer para determinar la directiva de inicio de sesión automática. En su lugar, la directiva de inicio de sesión automático se establece con WinHttpSetOption. Para obtener más información sobre la autenticación en WinHTTP, incluida la directiva de inicio de sesión automático, consulte Autenticación en WinHTTP.

Diferencias en las transacciones HTTP seguras

En WinINet, inicie una sesión segura mediante HttpOpenRequest o InternetConnect, pero en WinHTTP, debe llamar a WinHttpOpenRequest con la marca WINHTTP_FLAG_SECURE .

En una transacción HTTP segura, los certificados de servidor se pueden usar para autenticar un servidor en el cliente. En WinINet, si un certificado de servidor contiene errores, HttpSendRequest produce un error y proporciona detalles sobre los errores de certificado.

En WinHttp, los errores de certificado de servidor se controlan según la versión de la siguiente manera:

  • A partir de WinHttp 5.1, si se produce un error en un certificado de servidor o contiene errores, la llamada a WinHttpSendRequest informa de un WINHTTP_CALLBACK_STATUS_SECURE_FAILURE en la función de devolución de llamada. Si se omite el error generado por WinHttpSendRequest , las llamadas posteriores a WinHttpReceiveResponse producen un error de ERROR_WINHTTP_OPERATION_CANCELLED.
  • En WinHTTP 5.0, los errores en los certificados de servidor no hacen, de forma predeterminada, un error en una solicitud. En su lugar, los errores se notifican en la función de devolución de llamada con la notificación WINHTTP_CALLBACK_STATUS_SECURE_FAILURE .

En algunas plataformas anteriores, WinINet admitía los protocolos de tecnología de comunicación privada (PCT) o Fortezza, aunque no en Windows XP.

WinHTTP no admite los protocolos PCT y Fortezza en ninguna plataforma y, en su lugar, se basa en capa de sockets seguros (SSL) 2.0, SSL 3.0 o Seguridad de la capa de transporte (TLS) 1.0.