gsoapwininet.cpp

来自「linux下简单对象应用协议的开发库」· C++ 代码 · 共 1,106 行 · 第 1/3 页

CPP
1,106
字号
/*gsoapWinInet.cppSee the header file for details.Redistribution:          This code is redistributed as part of the gSOAP software, under the         gsoap public license terms and conditions. These conditions are         compatible with open source and commercial licensing.*//* system */#include <windows.h>#include <crtdbg.h>#include <wininet.h>/* gsoap */#include <stdsoap2.h>/* local */#include "gsoapWinInet.h"/* ensure that the wininet library is linked */#pragma comment( lib, "wininet.lib" )#define UNUSED_ARG(x)           (x)#define INVALID_BUFFER_LENGTH  ((DWORD)-1)typedef unsigned long DWORD_PTR;/* plugin id */static const char wininet_id[] = "wininet-2.0";/* plugin private data */struct wininet_data{    HINTERNET           hInternet;          /* internet session handle */    HINTERNET           hConnection;        /* current connection handle */    BOOL                bDisconnect;        /* connection is disconnected */    DWORD               dwRequestFlags;     /* extra request flags from user */    char *              pBuffer;            /* send buffer */    size_t              uiBufferLenMax;     /* total length of the message */    size_t              uiBufferLen;        /* length of data in buffer */    BOOL                bIsChunkSize;       /* expecting a chunk size buffer */    wininet_rse_callback pRseCallback;      /* wininet_resolve_send_error callback.  Allows clients to resolve ssl errors programatically */#ifdef SOAP_DEBUG    /* this is only used for DBGLOG output */    char *              pszErrorMessage;    /* wininet/system error message */#endif};/* forward declarations */static BOOLwininet_init(    struct soap *           soap,     struct wininet_data *   a_pData,    DWORD                   a_dwRequestFlags );static int  wininet_copy(     struct soap *           soap,     struct soap_plugin *    a_pDst,     struct soap_plugin *    a_pSrc );static void wininet_delete(     struct soap *           soap,     struct soap_plugin *    a_pPluginData );static int  wininet_connect(     struct soap *   soap,     const char *    a_pszEndpoint,     const char *    a_pszHost,     int             a_nPort );static int wininet_post_header(    struct soap *   soap,     const char *    a_pszKey,     const char *    a_pszValue );static int wininet_fsend(     struct soap *   soap,     const char *    a_pBuffer,     size_t          a_uiBufferLen );static size_t wininet_frecv(    struct soap *   soap,     char *          a_pBuffer,     size_t          a_uiBufferLen );static int wininet_disconnect(     struct soap *   soap );void CALLBACKwininet_callback(    HINTERNET   hInternet,    DWORD_PTR   dwContext,    DWORD       dwInternetStatus,    LPVOID      lpvStatusInformation,    DWORD       dwStatusInformationLength );static BOOLwininet_have_connection(    struct soap *           soap,    struct wininet_data *   a_pData );static DWORDwininet_set_timeout(    struct soap *           soap,     struct wininet_data *   a_pData,    const char *            a_pszTimeout,    DWORD                   a_dwOption,    int                     a_nTimeout );static BOOLwininet_resolve_send_error(     HINTERNET   a_hHttpRequest,     DWORD       a_dwErrorCode );#ifdef SOAP_DEBUG/* this is only used for DBGLOG output */static const char *wininet_error_message(    struct soap *   a_pData,    DWORD           a_dwErrorMsgId );static voidwininet_free_error_message(    struct wininet_data *   a_pData );#else#define wininet_free_error_message(x)#endif/* plugin registration */int wininet_plugin(     struct soap *           soap,     struct soap_plugin *    a_pPluginData,     void *                  a_dwRequestFlags ){    DBGLOG(TEST, SOAP_MESSAGE(fdebug,         "wininet %p: plugin registration\n", soap ));    a_pPluginData->id        = wininet_id;    a_pPluginData->fcopy     = wininet_copy;    a_pPluginData->fdelete   = wininet_delete;    a_pPluginData->data      = (void*) malloc( sizeof(struct wininet_data) );    if ( !a_pPluginData->data )    {        return SOAP_EOM;    }    if ( !wininet_init( soap,         (struct wininet_data *) a_pPluginData->data,         (DWORD) a_dwRequestFlags ) )    {        free( a_pPluginData->data );        return SOAP_EOM;    }#ifdef SOAP_DEBUG    if ( (soap->omode & SOAP_IO) == SOAP_IO_STORE )    {        DBGLOG(TEST, SOAP_MESSAGE(fdebug,             "wininet %p: use of SOAP_IO_STORE is not recommended\n", soap ));    }#endif    return SOAP_OK;}/* initialize private data */static BOOLwininet_init(    struct soap *           soap,     struct wininet_data *   a_pData,    DWORD                   a_dwRequestFlags ){    DBGLOG(TEST, SOAP_MESSAGE(fdebug,         "wininet %p: init private data\n", soap ));    memset( a_pData, 0, sizeof(struct wininet_data) );    a_pData->dwRequestFlags = a_dwRequestFlags;    /* start our internet session */    a_pData->hInternet = InternetOpenA(         "gSOAP", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );    if ( !a_pData->hInternet )    {        soap->error = GetLastError();        DBGLOG(TEST, SOAP_MESSAGE(fdebug,             "wininet %p: init, error %d (%s) in InternetOpen\n",             soap, soap->error, wininet_error_message(soap,soap->error) ));        wininet_free_error_message( a_pData );        return FALSE;    }    /* set the timeouts, if any of these fail the error isn't fatal */    wininet_set_timeout( soap, a_pData, "connect",         INTERNET_OPTION_CONNECT_TIMEOUT, soap->connect_timeout );    wininet_set_timeout( soap, a_pData, "receive",         INTERNET_OPTION_RECEIVE_TIMEOUT, soap->recv_timeout );    wininet_set_timeout( soap, a_pData, "send",            INTERNET_OPTION_SEND_TIMEOUT, soap->send_timeout );    /* set up the callback function so we get notifications */    InternetSetStatusCallback( a_pData->hInternet, wininet_callback );    /* set all of our callbacks */    soap->fopen    = wininet_connect;    soap->fposthdr = wininet_post_header;    soap->fsend    = wininet_fsend;    soap->frecv    = wininet_frecv;    soap->fclose   = wininet_disconnect;    return TRUE;}void wininet_set_rse_callback(	 struct soap*			soap,	 wininet_rse_callback	a_pRsecallback){    struct wininet_data * pData = (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );    DBGLOG(TEST, SOAP_MESSAGE(fdebug,         "wininet %p: resolve_send_error callback = '%p'\n", soap, a_pRsecallback ));    pData->pRseCallback = a_pRsecallback;}/* copy the private data structure */static int  wininet_copy(     struct soap *           soap,     struct soap_plugin *    a_pDst,     struct soap_plugin *    a_pSrc ){    UNUSED_ARG( soap );    UNUSED_ARG( a_pDst );    UNUSED_ARG( a_pSrc );    _ASSERTE( !"wininet doesn't support copy" );    return SOAP_FATAL_ERROR;}/* deallocate of our private structure */static void wininet_delete(     struct soap *           soap,     struct soap_plugin *    a_pPluginData ){    struct wininet_data * pData =         (struct wininet_data *) a_pPluginData->data;    UNUSED_ARG( soap );    DBGLOG(TEST, SOAP_MESSAGE(fdebug,         "wininet %p: delete private data\n", soap ));    /* force a disconnect of any existing connection */    pData->bDisconnect = TRUE;    wininet_have_connection( soap, pData );    /* close down the internet */    if ( pData->hInternet )    {        DBGLOG(TEST, SOAP_MESSAGE(fdebug,             "wininet %p: closing internet handle\n", soap));        InternetCloseHandle( pData->hInternet );        pData->hInternet = NULL;    }    /* free our data */    wininet_free_error_message( pData );    free( a_pPluginData->data );}/* gsoap documentation:    Called from a client proxy to open a connection to a Web Service located     at endpoint. Input parameters host and port are micro-parsed from endpoint.    Should return a valid file descriptor, or SOAP_INVALID_SOCKET and     soap->error set to an error code. Built-in gSOAP function: tcp_connect*/static int  wininet_connect(     struct soap *   soap,     const char *    a_pszEndpoint,     const char *    a_pszHost,     int             a_nPort ){    URL_COMPONENTSA urlComponents;    char            szUrlPath[MAX_PATH];    char            szHost[MAX_PATH];    DWORD           dwFlags;    HINTERNET       hConnection  = NULL;    HINTERNET       hHttpRequest = NULL;    struct wininet_data * pData =         (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );    soap->error = SOAP_OK;    /* we parse the URL ourselves so we don't use these parameters */    UNUSED_ARG( a_pszHost );    UNUSED_ARG( a_nPort );    DBGLOG(TEST, SOAP_MESSAGE(fdebug,         "wininet %p: connect, endpoint = '%s'\n", soap, a_pszEndpoint ));    /* we should be initialized but not connected */    _ASSERTE( pData->hInternet );    _ASSERTE( !pData->hConnection );    _ASSERTE( soap->socket == SOAP_INVALID_SOCKET );    /* parse out the url path */    memset( &urlComponents, 0, sizeof(urlComponents) );    urlComponents.dwStructSize = sizeof(urlComponents);    urlComponents.lpszHostName      = szHost;    urlComponents.dwHostNameLength  = MAX_PATH;    urlComponents.lpszUrlPath       = szUrlPath;    urlComponents.dwUrlPathLength   = MAX_PATH;    if ( !InternetCrackUrlA( a_pszEndpoint, 0, 0, &urlComponents ) )    {        InternetCloseHandle( hConnection );        soap->error = GetLastError();        DBGLOG(TEST, SOAP_MESSAGE(fdebug,             "wininet %p: connect, error %d (%s) in InternetCrackUrl\n",             soap, soap->error, wininet_error_message(soap,soap->error) ));        return SOAP_INVALID_SOCKET;    }    /* connect to the target url, if we haven't connected yet        or if it was dropped */    hConnection = InternetConnectA( pData->hInternet,         szHost, urlComponents.nPort, "", "", INTERNET_SERVICE_HTTP,         0, (DWORD_PTR) soap );    if ( !hConnection )    {        soap->error = GetLastError();        DBGLOG(TEST, SOAP_MESSAGE(fdebug,             "wininet %p: connect, error %d (%s) in InternetConnect\n",             soap, soap->error, wininet_error_message(soap,soap->error) ));        return SOAP_INVALID_SOCKET;    }    /*         Note that although we specify HTTP/1.1 for the connection here, the         actual connection may be HTTP/1.0 depending on the settings in the         control panel. See the "Internet Options", "HTTP 1.1 settings".     */    dwFlags = pData->dwRequestFlags;    if ( soap->omode & SOAP_IO_KEEPALIVE )    {        dwFlags |= INTERNET_FLAG_KEEP_CONNECTION;    }    if ( urlComponents.nScheme == INTERNET_SCHEME_HTTPS )     {        dwFlags |= INTERNET_FLAG_SECURE;    }    hHttpRequest = HttpOpenRequestA(        hConnection, "POST", szUrlPath, "HTTP/1.1", NULL, NULL,         dwFlags, (DWORD_PTR) soap );    if ( !hHttpRequest )    {        InternetCloseHandle( hConnection );        soap->error = GetLastError();        DBGLOG(TEST, SOAP_MESSAGE(fdebug,             "wininet %p: connect, error %d (%s) in HttpOpenRequest\n",             soap, soap->error, wininet_error_message(soap,soap->error) ));        return SOAP_INVALID_SOCKET;    }    /* save the connection handle in our data structure */    pData->hConnection = hConnection;    /* return the http request handle as our file descriptor. */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?