Post a multipart/form-data using C++ with winhttp to flask

70 views Asked by At

I used the following code to send formData to my Flask server, and I tried to read formData using request.files but the result is immutablemultidict([]).

What should I do to get data as formData?

I can get request.get_data or request.data.

DWORD dwSize = 0;
LPVOID lpOutBuffer = NULL;

std::wstring filePath = L"C:img.png";

std::vector<char> fileContent = ReadFileContent(filePath);

HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL;

hSession = WinHttpOpen(L"WinHTTP Example/1.0",
    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
    WINHTTP_NO_PROXY_NAME,
    WINHTTP_NO_PROXY_BYPASS, 0);

if (!hSession) {
    std::wcerr << L"WinHttpOpen failed!" << std::endl;
    return 1;
}

hConnect = WinHttpConnect(hSession, L"127.0.0.0", INTERNET_DEFAULT_HTTP_PORT, 0);

if (!hConnect) {
    std::wcerr << L"WinHttpConnect failed!" << std::endl;
    WinHttpCloseHandle(hSession);
    return 1;
}

std::wstring boundary = L"--------------------------" + std::to_wstring(GetTickCount64());;

std::wstring headers = L"Content-Type: multipart/form-data; boundary=" + boundary;

std::wstring formData = L"--" + boundary + L"\r\n"
    L"Content-Disposition: form-data; name=\"file\"; filename=\"" + filePath + L"\"\r\n"
    L"Content-Type: image/*\r\n\r\n";
std::wstring finalBoundary = L"\r\n--" + boundary + L"--\r\n";


hRequest = WinHttpOpenRequest(hConnect, L"POST",
    L"/upload", 
    NULL, WINHTTP_NO_REFERER,
    WINHTTP_DEFAULT_ACCEPT_TYPES,
    0);

if (!hRequest) {
    std::wcerr << L"WinHttpOpenRequest failed!" << std::endl;
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    return 1;
}

DWORD dwOption = WINHTTP_OPTION_REDIRECT_POLICY_NEVER;
WinHttpSetOption(hRequest, WINHTTP_OPTION_REDIRECT_POLICY, &dwOption, sizeof(dwOption));

BOOL bResults = WinHttpSendRequest(hRequest, headers.c_str(),
    headers.length(), 0, 0, fileContent.size() + formData.size() * sizeof(wchar_t) +
    finalBoundary.size() * sizeof(wchar_t), 0);

if (!bResults) {
    std::wcerr << L"WinHttpSendRequest failed: " << GetLastError() << std::endl;
    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    return 1;
}

bResults = WinHttpWriteData(hRequest, formData.data(), formData.size() * sizeof(wchar_t), 0);
bResults = WinHttpWriteData(hRequest, fileContent.data(), fileContent.size(), 0);
bResults = WinHttpWriteData(hRequest, finalBoundary.data(), finalBoundary.size() * sizeof(wchar_t), 0);

if (!bResults) {
    std::wcerr << L"WinHttpWriteData failed: " << GetLastError() << std::endl;
    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    return 1;
}

bResults = WinHttpReceiveResponse(hRequest, NULL);

if (!bResults) {
    std::wcerr << L"WinHttpReceiveResponse failed: " << GetLastError() << std::endl;
    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    return 1;
}

I want to see ImmutableMultiDict(['file'], <filename: 'img.png' ('image/png')>)] in the Python terminal. Here are my results: enter image description here

0

There are 0 answers