⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32transportagent.cpp

📁 This SDK allows to integrate a syncml stack in a C++ application on a variety of platforms. Current
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        }

        LOG.debug(MESSAGE_SENT);
        // Fire Send Data End Transport Event
        fireTransportEvent(contentLength, SEND_DATA_END);

        // Check the status code.
        size = sizeof(status);
        HttpQueryInfo (request,
                       HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
                       (LPDWORD)&status,
                       (LPDWORD)&size,
                       NULL);

        //
        // OK (200) -> OUT
        //
        if (status == HTTP_STATUS_OK) {
            break;
        }


        //
        // Proxy Authentication Required (407) / Server Authentication Required (401).
        // Need to set username/password.
        //
        else if(status == HTTP_STATUS_PROXY_AUTH_REQ ||
                status == HTTP_STATUS_DENIED) {
            LOG.debug("HTTP Authentication required.");
            DWORD dwError;
            
            // Automatic authentication (user/pass stored in win reg key).
            if (strcmp(proxy.user, "") && strcmp(proxy.password, "")) {
                WCHAR* wUser = toWideChar(proxy.user);
                WCHAR* wPwd  = toWideChar(proxy.password);

                InternetSetOption(request, INTERNET_OPTION_PROXY_USERNAME, wUser, wcslen(wUser)+1);
                InternetSetOption(request, INTERNET_OPTION_PROXY_PASSWORD, wPwd,  wcslen(wPwd)+1);

                delete [] wUser;
                delete [] wPwd;
                dwError = ERROR_INTERNET_FORCE_RETRY;
            }

            // Prompt dialog box.
            else {
                dwError = InternetErrorDlg(GetDesktopWindow(), request, NULL, 
                                           FLAGS_ERROR_UI_FILTER_FOR_ERRORS | 
                                           FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
                                           FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
                                           NULL);
            }
            
            if (dwError == ERROR_INTERNET_FORCE_RETRY) {
                continue;
            }
            else {
                LOG.error("HTTP Authentication failed.");
                break;
            }
        }
        
        //
        // Other HTTP errors -> OUT
        //
        else {
            break;
        }
    }

    // If wrong status, exit immediately.
    if (status != HTTP_STATUS_OK) {
        if (status == HTTP_STATUS_NOT_FOUND) {
            lastErrorCode = ERR_HTTP_NOT_FOUND;
            sprintf(lastErrorMsg, "HttpQueryInfo error: resource not found (status %d)", status);
        }
        else if (status == HTTP_STATUS_REQUEST_TIMEOUT) {
            lastErrorCode = ERR_HTTP_REQUEST_TIMEOUT;
            sprintf(lastErrorMsg, "HttpQueryInfo error: server timed out waiting for request (status %d)", status);
        }
        else {
            lastErrorCode = ERR_HTTP;
            DWORD code = GetLastError();
            char* tmp = createHttpErrorMessage(code);
            sprintf(lastErrorMsg, "HttpQueryInfo error (status received = %d): %s (code %d)", status, tmp, code);
		    delete [] tmp;
        }
        goto exit;
    }

    //Initialize response
    contentLength=0;
    HttpQueryInfo (request,
                   HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
                   (LPDWORD)&contentLength,
                   (LPDWORD)&size,
                   NULL);



#ifdef USE_ZLIB 

    if (compr) {
        // Delete the compressed message sent.
        delete [] compr;
        compr = NULL;
    }

    //
    // Read headers: get contentLenght/Uncompressed-Content-Length.
    //
    int uncompressedContentLenght = 0;
    wchar_t* wbuffer = new wchar_t[1024];
    DWORD ddsize = 1024;
    if (!HttpQueryInfo(request,HTTP_QUERY_RAW_HEADERS_CRLF ,(LPVOID)wbuffer,&ddsize,NULL)) {
        if (ERROR_HTTP_HEADER_NOT_FOUND == GetLastError()) {
            isToDeflate = FALSE;
        }
    }
    LOG.debug("Header: %ls", wbuffer);
    delete [] wbuffer; wbuffer = NULL;
           
    // isToDeflate to be set
    DWORD dwSize = 512;
    wchar_t* buffer = new wchar_t[dwSize];     
    memset(buffer, 0, dwSize*sizeof(wchar_t));
                   
    wcscpy(buffer, TEXT("Accept-Encoding"));
    HttpQueryInfo(request, HTTP_QUERY_CUSTOM, (LPVOID)buffer, &dwSize, NULL);
    if (ERROR_HTTP_HEADER_NOT_FOUND == GetLastError()) {
        isToDeflate = FALSE;
    } else {
        isToDeflate = TRUE;
    }	
    
    memset(buffer, 0, dwSize*sizeof(wchar_t));
    wcscpy(buffer, TEXT("Content-Encoding"));
    HttpQueryInfo(request, HTTP_QUERY_CUSTOM, (LPVOID)buffer, &dwSize, NULL);
    if (GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND) {
        isToInflate = FALSE;
    } else {
        if (wcscmp(buffer, TEXT("deflate")) == 0)
            isToInflate = TRUE;
        else
            isToInflate = FALSE;
    }

    memset(buffer, 0, dwSize*sizeof(wchar_t));
    wcscpy(buffer, TEXT("Uncompressed-Content-Length"));

    HttpQueryInfo(request, HTTP_QUERY_CUSTOM, (LPVOID)buffer, &dwSize, NULL);
    if (GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND) {
        isToInflate = FALSE;
    } else {
        uncompressedContentLenght = wcstol(buffer, NULL, 10);
    }	        	

    delete [] buffer;
    buffer = NULL;
#endif


//
// ====================================== Reading Response ======================================
//
    LOG.debug(READING_RESPONSE);
    LOG.debug("Content-length: %d", contentLength);
	
    if (contentLength <= 0) {
        LOG.debug("Undefined content-length = %d. Using the maxMsgSize = %d.", contentLength, maxmsgsize);
        contentLength = maxmsgsize;
    }

    // Allocate a block of memory for response read.
    response = new char[contentLength+1];
    if (response == NULL) {
        lastErrorCode = ERR_NOT_ENOUGH_MEMORY;
        sprintf(lastErrorMsg, "Not enough memory to allocate a buffer for the server response: %d required.", contentLength);
        LOG.error(lastErrorMsg);
        goto exit;
    }
    memset(response, 0, contentLength);
	p = response;
    (*p) = 0;
    int realResponseLenght = 0;

    // Fire Data Received Transport Event.
    fireTransportEvent(contentLength, RECEIVE_DATA_BEGIN);

    do {
        if (!InternetReadFile(request, (LPVOID)bufferA, readBufferSize, &read)) {
            DWORD code = GetLastError();
            lastErrorCode = ERR_READING_CONTENT;
            char* tmp = createHttpErrorMessage(code);
            sprintf(lastErrorMsg, "InternetReadFile Error: %d - %s", code, tmp);
            delete [] tmp;
            goto exit;
		}

        // Sanity check: some proxy could send additional bytes.
        // Correct 'read' value to be sure we won't overflow the 'response' buffer.
        if ((realResponseLenght + read) > contentLength) {
            LOG.debug("Warning! %d bytes read -> truncating data to content-lenght = %d.", (realResponseLenght + read), contentLength);
            read = contentLength - realResponseLenght;
        }

        if (read > 0) {
            memcpy(p, bufferA, read);               // Note: memcopy exactly the bytes read (could be no readable chars...)
            p += read;
            realResponseLenght += read;

            // Fire Data Received Transport Event
            fireTransportEvent(read, DATA_RECEIVED);
        }

    } while (read);

    if (realResponseLenght <= 0) {
        lastErrorCode = ERR_READING_CONTENT;
        sprintf(lastErrorMsg, "Error reading HTTP response from Server: received data of size = %d.", realResponseLenght);
        goto exit;
    }

    // Should be already the same...
    contentLength = realResponseLenght;

    // Fire Receive Data End Transport Event
    fireTransportEvent(contentLength, RECEIVE_DATA_END);


#ifdef USE_ZLIB
    if (isToInflate) {
        //
        // INFLATE (decompress data)
        //
        uLong uncomprLen = uncompressedContentLenght;
        Bytef* uncompr = new Bytef[uncomprLen + 1];        

        // Decompresses the source buffer into the destination buffer.
        int err = uncompress(uncompr, &uncomprLen, (Bytef*)response, contentLength);

        if (err == Z_OK) {
            delete [] response;
            response = (char*)uncompr;
            response[uncompressedContentLenght] = 0;
        }   
        else if (err < 0) {
            delete [] response;
            response = NULL;
            lastErrorCode = ERR_HTTP_INFLATE;
            sprintf(lastErrorMsg, "ZLIB: error occurred decompressing data from Server.");
            goto exit;
        }
    }
#endif

    LOG.debug("Response read:\n%s", response);

exit:
    // Close the Internet handles.
    if (inet) {
        InternetCloseHandle (inet);
    }
    if (connection) {
        InternetCloseHandle (connection);
    }
    if (request) {
        InternetCloseHandle (request);
    }

    if ((status != STATUS_OK) && (response !=NULL)) {
        delete [] response; response = NULL;
    }
    if (wurlHost)     delete [] wurlHost;
    if (wurlResource) delete [] wurlResource;
    if (bufferA)      delete [] bufferA;

    EXITING(L"TransportAgent::sendMessage");

    return response;
}


/**
 * Utility function to retrieve the correspondant message for the Wininet error code passed.
 * Pointer returned is allocated new, must be freed by caller.
 */
char* Win32TransportAgent::createHttpErrorMessage(DWORD errorCode) {
    
    char* errorMessage = new char[512];
    memset(errorMessage, 0, 512);

    FormatMessageA(
                FORMAT_MESSAGE_FROM_HMODULE,
                GetModuleHandleA("wininet.dll"),
                errorCode,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
                errorMessage, 
                512, 
                NULL);

    if (!errorMessage || strlen(errorMessage) == 0) {
        sprintf(errorMessage, "Unknown error.");
    }
    return errorMessage;
}


⌨️ 快捷键说明

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