【问题标题】:WinHTTP issue when uploading files上传文件时出现 WinHTTP 问题
【发布时间】:2014-01-28 04:48:23
【问题描述】:

花了几天时间撞墙后,我想我会在这里问。

下面代码的问题是我基本上是在迭代一个目录,在那里上传文件。所有文件都很小,大小约为 1KB,因此这不是大小问题。第一次上传很顺利,所有后续调用都被 winhttp 中断,只发送标头。

代码如下:

BOOL NetworkManager::UploadFileToServer(wchar_t *pszURL, wchar_t *pszFilePath, wchar_t *_pszProxyAddress, wchar_t *pszServerAddress)
{
HINTERNET  hSession = NULL, 
hConnect = NULL,
hRequest = NULL;
BOOL bResults;
DWORD dwSize = 0;
DWORD dwContentLength = 0;
LPCWSTR pszProxyAddress = 0;
wchar_t wszContentLength[256] = { 0 };

pszProxyAddress = _pszProxyAddress;

printf("Trying to send %S\r\n", pszFilePath);

if(pszProxyAddress != NULL && wcslen(pszProxyAddress) < 4)
{
    pszProxyAddress = NULL;
}

HANDLE hFile = CreateFile(pszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);

if(hFile == INVALID_HANDLE_VALUE)
{
    printf("UM: Unable to open the file for sending, aborting...\r\n");
    return FALSE;
}

DWORD dwFileSize = GetFileSize(hFile, NULL);

// Use WinHttpOpen to obtain a session handle.
if(pszProxyAddress == NULL)
{
    hSession = WinHttpOpen( L"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", 
                        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                        NULL,
                        WINHTTP_NO_PROXY_BYPASS, 0);
}
else
{
    hSession = WinHttpOpen( L"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", 
                        WINHTTP_ACCESS_TYPE_NAMED_PROXY,
                        pszProxyAddress, 
                        WINHTTP_NO_PROXY_BYPASS, 0);
}

// Specify an HTTP server.
if (hSession)
{
    hConnect = WinHttpConnect( hSession, _pszServerAddress,
                               INTERNET_DEFAULT_HTTPS_PORT, 0);
}
else
{
    printf("hSession failed, errorcode 0x%08x\r\n", GetLastError());
    return FALSE;
}

// Create an HTTP request handle.
if (hConnect)
{
    hRequest = WinHttpOpenRequest( hConnect, L"POST", L"upload.php",
                                   NULL, WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                   WINHTTP_FLAG_SECURE);
}
else
{
    printf("hConnect failed, errorcode 0x%08x\r\n", GetLastError());
    WinHttpCloseHandle(hSession);
    return FALSE;
}
PHEAP_BUFFER pBuf = NULL;
DWORD dwBytesWritten = 0;
// Send a request.
if (hRequest)
{

DWORD options = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID  |  SECURITY_FLAG_IGNORE_UNKNOWN_CA ;

    bResults = WinHttpSetOption( hRequest, WINHTTP_OPTION_SECURITY_FLAGS , (LPVOID)&options, sizeof (DWORD) );

WinHttpAddRequestHeaders(hRequest, L"Content-Type: multipart/form-data; boundary=----BoundaryXu02", (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD);

dwContentLength = strlen(pszFormHeader) + dwFileSize + strlen(pszFinalBoundary);        
DWORD dwTotalSent = 0;
pBuf = MemoryManager::AllocateHeapMemory(dwContentLength, 1);
DWORD dwBytesRead = 0;
strcat_s((PCHAR)pBuf->pBuffer, pBuf->dwBufferSize, pszFormHeader);
ReadFile(hFile, &pBuf->pBuffer[strlen(pszFormHeader)], dwFileSize, &dwBytesRead, NULL);
memcpy(&pBuf->pBuffer[strlen(pszFormHeader) + dwFileSize], pszFinalBoundary, strlen(pszFinalBoundary));

wsprintf(wszContentLength, L"Content-Length: %d", dwContentLength);

bResults = WinHttpSendRequest( hRequest, wszContentLength, -1, 0, 0, dwContentLength, 0);

printf("Sending out the request\r\n");

WinHttpWriteData(hRequest, pBuf->pBuffer, pBuf->dwBufferSize, &dwBytesWritten);
}
else
{
    printf("hRequest failed, errorcode 0x%08x\r\n", GetLastError());
    WinHttpCloseHandle(hSession);
    WinHttpCloseHandle(hConnect);
    return FALSE;
}


//WinHttpWriteData(hRequest, pBuf->pBuffer, pBuf->dwBufferSize, &dwBytesWritten);

 // End the request.
if (bResults)
{
    bResults = WinHttpReceiveResponse( hRequest, NULL);
}
else
{
    printf("hResults failed, errorcode 0x%08x\r\n");
    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    MemoryManager::FreeHeapMemory(pBuf);
    return FALSE;
}

WinHttpQueryDataAvailable(hRequest, &dwBytesWritten);

// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
MemoryManager::FreeHeapMemory(pBuf);
CloseHandle(hFile);
DeleteFile(pszFilePath);
return TRUE;
}

这是来自服务器的 access_log:

xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:33 +0200] "POST /upload.php HTTP/1.1" 200 1811 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:33 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:33 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:33 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:33 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
xxx.xxx.xxx.244 - - [09/Jan/2014:16:39:34 +0200] "POST /upload.php HTTP/1.1" 200 295 "-" "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"

我完全不知道为什么世界上第一个 POST 成功,但其余的都去 sh*t :(

编辑:

忘记添加标题声明:

char *pszFormHeader = "------BoundaryXu02\r\nContent-Disposition: form-data; name=\"uploaded\"; filename=\"aviconv.dat\"\r\nContent-Type: application/octet-stream\r\n\r\n";
char *pszFinalBoundary = "\r\n------BoundaryXu02--\r\n";
char *pwzContentHeader = "Content-Type: multipart/form-data; boundary=----BoundaryXu02";
wchar_t wszContentLength[256] = { 0 };

【问题讨论】:

  • 我的猜测是,CreateFile 第二轮失败,GetFileSize 返回 (DWORD)-1。找出为什么。一种可能性:您在发送文件后立即删除文件 - 我认为这可能会干扰当前正在进行的枚举。
  • 不。枚举工作正常,而且我已经在调试器下确认 createfile 工作正常,并且所有参数都传递给 WinHTTP,因为它们应该是
  • AllocateMemory 是否将缓冲区归零?你 strcat 在分配后立即进入它,除非第一个字节为零,否则它不会做正确的事情。您可能想改用strcpymemcpy
  • AllocateMemory 将缓冲区归零。
  • 好的,开始工作了。永远不要低估良好睡眠的力量。我会稍后发布答案

标签: c++ visual-c++ winhttp


【解决方案1】:

好的,所以终于弄清楚了代码存在的问题。

1) 为了防止潜在的代理干扰上传,在调用 WinHttpOpenRequest 时使用 WINHTTP_FLAG_REFRESH

2) 由于在此代码中您为每次上传创建新连接,因此某些服务器似乎会感到困惑,因为 WinHTTP 的默认设置是在标头中使用“连接:保持活动”。添加“连接:关闭”解决了这个问题。

3) 似乎调用 WinHttpReceiveResponse 和 WinHttpQueryDataAvailable 是不够的。在最后添加 WinHttpReadData 调用后,事情开始正常运行。

4) 确保每次添加 CurrentTickCount 调用时上传使用不同的边界。只是为了确保一路上愚蠢的代理不会认为“我以前见过这个”

以下是通过 SSL (HTTPS) 将文件上传到 php 脚本的功能代码。我已经剥离了在我的项目中引用其他组件的调用,并将它们替换为普通的 C 等效项。

我希望这对其他与 WinHTTP 搏斗的人有所帮助:)

另外,请注意该函数会在发送后删除文件,所以不要只是复制/粘贴并在 c:\windows\system32\kernel32.dll 上测试...

免责声明:我知道代码仍有改进的空间,特别是在一些不安全的函数调用以及如果文件大小大于 DWORD 会出现问题的事实。再说一次,另一方面,如果您尝试像这样发送它们,WinHTTP 无论如何都会拒绝上传那么大的文件。

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <winhttp.h>

char *pszFormHeader = "------Boundary%08X\r\nContent-Disposition: form-data; name=\"uploaded\"; filename=\"%08x.dat\"\r\nContent-Type: application/octet-stream\r\n\r\n";
char *pszFinalBoundary = "\r\n------Boundary%08X--\r\n";
wchar_t *wszContentHeader = L"Content-Type: multipart/form-data; boundary=----Boundary%08X";
wchar_t wszContentLength[256] = { 0 };

#define BUFFER_SIZE_1KB 1024

BOOL UploadFileToServer(wchar_t *wszURL, wchar_t *wszFilePath, wchar_t *_wszProxyAddress, wchar_t *_wszServerAddress);

int main(int argc, char **argv)
{
    UploadFileToServer(L"upload.php", L"c:\\sample1.txt", NULL, L"www.example.com");
    UploadFileToServer(L"upload.php", L"c:\\sample2.txt", NULL, L"www.example.com");

}

BOOL UploadFileToServer(wchar_t *wszURL, wchar_t *wszFilePath, wchar_t *_wszProxyAddress, wchar_t *_wszServerAddress)
{
    /*
     * Declarations and initializations
     */
    HINTERNET  hSession = NULL, hConnect = NULL, hRequest = NULL;
    BOOL bResults;
    DWORD dwSize = 0;
    DWORD dwContentLength = 0;
    DWORD dwBytesToRead = 0;
    DWORD dwBytesRead = 0;
    DWORD dwBytesWritten = 0;
    DWORD dwBoundaryValue = 0;
    DWORD dwFileSize = 0;
    DWORD options = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID  |  SECURITY_FLAG_IGNORE_UNKNOWN_CA ;
    LPCWSTR wszProxyAddress = 0;
    wchar_t wszContentLength[256] = { 0 };

    PUCHAR pResponse = 0;
    PCHAR pFormHeader = 0;
    PCHAR pFinalBoundary = 0;
    PUCHAR pBuf = 0;
    wchar_t *pContentHeader = 0;

    /*
     * Preparations, set up the content headers
     */
    pFormHeader = (PCHAR) calloc(BUFFER_SIZE_1KB, 1);
    pFinalBoundary = (PCHAR) calloc(BUFFER_SIZE_1KB, 1);
    pContentHeader = (wchar_t *) calloc(BUFFER_SIZE_1KB, 1);

    dwBoundaryValue = GetTickCount();
    wszProxyAddress = _wszProxyAddress;

    sprintf_s(pFormHeader, BUFFER_SIZE_1KB, pszFormHeader, dwBoundaryValue, dwBoundaryValue);
    sprintf_s(pFinalBoundary, BUFFER_SIZE_1KB, pszFinalBoundary, dwBoundaryValue);
    wsprintf(pContentHeader, wszContentHeader, dwBoundaryValue);

    if(wszProxyAddress != NULL && wcslen(wszProxyAddress) < 4)
    {
        wszProxyAddress = NULL;
    }

    HANDLE hFile = CreateFile(wszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);

    if(hFile == INVALID_HANDLE_VALUE)
    {
        free(pFormHeader);
        free(pFinalBoundary);
        free(pContentHeader);
        printf("Unable to open the file for sending, aborting...\r\n");
        return FALSE;
    }

    dwFileSize = GetFileSize(hFile, NULL);

    if(dwFileSize == 0)
    {
        free(pFormHeader);
        free(pFinalBoundary);
        free(pContentHeader);
        printf("The file is 0 bytes in size, cannot send it\r\n");
        return FALSE;
    }

    if(wszProxyAddress == NULL)
    {
        hSession = WinHttpOpen( L"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", 
                            WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                            NULL,
                            WINHTTP_NO_PROXY_BYPASS, 0);
    }
    else
    {
        hSession = WinHttpOpen( L"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", 
                            WINHTTP_ACCESS_TYPE_NAMED_PROXY,
                            wszProxyAddress, 
                            WINHTTP_NO_PROXY_BYPASS, 0);
    }


    if (hSession)
    {
        hConnect = WinHttpConnect( hSession, _wszServerAddress,
                                INTERNET_DEFAULT_HTTPS_PORT, 0);
    }
    else
    {
        free(pFormHeader);
        free(pFinalBoundary);
        free(pContentHeader);
        printf("hSession failed, errorcode 0x%08x\r\n", GetLastError());
        return FALSE;
    }

    if (hConnect)
    {
        hRequest = WinHttpOpenRequest( hConnect, L"POST", wszURL,
                                   NULL, WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                   WINHTTP_FLAG_SECURE | WINHTTP_FLAG_REFRESH);
    }
    else
    {
        free(pFormHeader);
        free(pFinalBoundary);
        free(pContentHeader);
        printf("hConnect failed, errorcode 0x%08x\r\n", GetLastError());
        WinHttpCloseHandle(hSession);
        return FALSE;
    }

if (hRequest)
{
    bResults = WinHttpSetOption( hRequest, WINHTTP_OPTION_SECURITY_FLAGS , (LPVOID)&options, sizeof (DWORD) );

    WinHttpAddRequestHeaders(hRequest, pContentHeader, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD);
    WinHttpAddRequestHeaders(hRequest, L"Connection: close", (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);

    dwContentLength = strlen(pFormHeader) + dwFileSize + strlen(pFinalBoundary);        

    pBuf = (PUCHAR)calloc(dwContentLength, 1);

    strcat_s((PCHAR)pBuf, dwContentLength, pFormHeader);

    ReadFile(hFile, &pBuf[strlen(pFormHeader)], dwFileSize, &dwBytesRead, NULL);

    memcpy(&pBuf[strlen(pFormHeader) + dwFileSize], pFinalBoundary, strlen(pFinalBoundary));

    wsprintf(wszContentLength, L"Content-Length: %d", dwContentLength);

    bResults = WinHttpSendRequest( hRequest,
                                    wszContentLength,
                                    -1, pBuf, dwContentLength, 
                                   dwContentLength, 0);

}
else
{
    free(pFormHeader);
    free(pFinalBoundary);
    free(pContentHeader);
    printf("hRequest failed, errorcode 0x%08x\r\n", GetLastError());
    WinHttpCloseHandle(hSession);
    WinHttpCloseHandle(hConnect);
    return FALSE;
}

if (bResults)
{
    bResults = WinHttpReceiveResponse( hRequest, NULL);
}
else
{
    printf("hResults failed, errorcode 0x%08x\r\n");
    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    free(pBuf);
    free(pFormHeader);
    free(pFinalBoundary);
    free(pContentHeader);
    return FALSE;
}

WinHttpQueryDataAvailable(hRequest, &dwBytesToRead);

pResponse = (PUCHAR)calloc(dwBytesToRead, 1);

WinHttpReadData(hRequest, pResponse, dwBytesToRead, &dwBytesRead);

free(pResponse);
free(pFormHeader);
free(pFinalBoundary);
free(pContentHeader);
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);

free(pBuf);
CloseHandle(hFile);

DeleteFile(wszFilePath);

return TRUE;

}

【讨论】:

    【解决方案2】:

    以下代码适用于我将文本图块上传到返回状态代码 200 的 HTTP 侦听器。

    #include <Windows.h>
    #include <winhttp.h>
    #include <string>
    #include <fstream>
    #include <sstream>
    using namespace std;
    
    std::wstring ErrorMessage(DWORD dwMessageId)
    {
        HMODULE h = GetModuleHandle(L"Winhttp");
        constexpr DWORD dwSize = 512;
        HANDLE hHeap = GetProcessHeap();
        LPWSTR lpwszBuffer = static_cast<LPWSTR>(HeapAlloc(hHeap, 0, dwSize * sizeof(WCHAR)));
        if (lpwszBuffer) {
            if (0 == FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, h, dwMessageId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpwszBuffer, dwSize, nullptr))
                _ltow_s(dwMessageId, lpwszBuffer, dwSize, 16);
            else {
                for (WCHAR* p; (p = wcschr(lpwszBuffer, L'\r')) != nullptr; *p = L' ') {}
                for (WCHAR* p; (p = wcschr(lpwszBuffer, L'\n')) != nullptr; *p = L' ') {}
            }
    
            std::wstring wsError = lpwszBuffer;
            HeapFree(hHeap, 0, lpwszBuffer);
            return wsError;
        }
        return std::wstring{};
    }
    
    int main()
    {
        DWORD dwSize = 0;
        LPVOID lpOutBuffer = NULL;
        BOOL  bResults = FALSE;
        HINTERNET hSession = NULL,
            hConnect = NULL,
            hRequest = NULL;
    
        // Use WinHttpOpen to obtain a session handle.
        hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0",
            WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
            WINHTTP_NO_PROXY_NAME,
            WINHTTP_NO_PROXY_BYPASS, 0);
    
        std::wstring url{ L"http://app.pomdit.com:3010/uploadfile" };
        URL_COMPONENTS components{};
        components.dwStructSize = sizeof(components);
        components.dwHostNameLength = (DWORD)-1;
        components.dwUrlPathLength = (DWORD)-1;
        if (!WinHttpCrackUrl(url.c_str(), static_cast<DWORD>(url.length()), 0, &components)) {
            wprintf((L"WinHttpCrackUrl(): " + ErrorMessage(GetLastError())).c_str());
        }
    
        std::wstring hostName(components.lpszHostName ? std::wstring{ components.lpszHostName, components.dwHostNameLength } : L"localhost");
        // Specify an HTTP server.
        if (hSession)
            hConnect = WinHttpConnect(hSession, hostName.c_str(),
                                      components.nPort, 0);
    
        // Create an HTTP request handle.
        if (hConnect)
            hRequest = WinHttpOpenRequest(hConnect, L"POST", components.lpszUrlPath,
                NULL, WINHTTP_NO_REFERER,
                WINHTTP_DEFAULT_ACCEPT_TYPES,
                0);
    
        const WCHAR* ContentType =
            L"Content-Type: multipart/form-data;boundary = 19024605111143684786787635207";
    
        std::ifstream in("LogFile.txt");
        std::stringstream buffer;
        buffer << in.rdbuf();
        std::string contents(buffer.str());
    
        std::string MultipartRequestBody =
            "--19024605111143684786787635207\r\n"
            "Content-Disposition: form-data; name=\"file\"; filename=\"Logfile\"\r\n"
            "Content-Type: application/octet-stream\r\n"
            "\r\n";
    
        std::string finalBody =  "--19024605111143684786787635207--\r\n";
        MultipartRequestBody += contents + "\r\n" + finalBody;
    
        bResults = WinHttpAddRequestHeaders(
            hRequest,
            ContentType,
            -1L,
            WINHTTP_ADDREQ_FLAG_ADD
        );
    
        bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                    WINHTTP_NO_REQUEST_DATA,
                    0,
                    MultipartRequestBody.length(),
                    NULL);
    
            DWORD dwBytesWritten = 0;
            if (bResults)
                bResults = WinHttpWriteData(hRequest, MultipartRequestBody.c_str(),
                    MultipartRequestBody.length(),
                    &dwBytesWritten);
    
        // End the request.
        if (bResults)
            bResults = WinHttpReceiveResponse(hRequest, NULL);
    
        if (bResults)
        {
            DWORD status{}, len = sizeof(status);
            bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &len, NULL);
            printf("Status code = %d.\n", status);
        }
        else
        {
            wprintf(L"WinHttpReceiveResponse(): %s\n", ErrorMessage(GetLastError()).c_str());
        }
    
        // Close any open handles.
        if (hRequest) WinHttpCloseHandle(hRequest);
        if (hConnect) WinHttpCloseHandle(hConnect);
        if (hSession) WinHttpCloseHandle(hSession);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 2021-08-04
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多