c++windowsunicodelibcurl

CURLE_READ_ERROR on reading filename which contains foreign language characters


I'm using libcurl to communicate with my http server. The functionality works fine until i try to read a file whose name is in foreign language. Let say the file name is फ़ाइल.txt and it is placed in the std::wstring filePath variable.

    CURLFORMcode formAddResult = curl_formadd(&formPost, &lastPtr, CURLFORM_COPYNAME, "file", CURLFORM_FILE, ws2s(filePath).c_str(), CURLFORM_END);

    if (formAddResult != CURL_FORMADD_OK) {
        std::cerr << "Failed to add form data: " << curl_easy_strerror((CURLcode)formAddResult) << std::endl;
        curl_easy_cleanup(curl);
        FreeLibrary(hCurlLib);
        return false;
    }

The above line of code returns:

Failed to upload file: 26

The above error is CURLE_READ_ERROR. This error indicates that the libcurl is unable to read from the specified file.

I'm converting the std::wstring to std::string using the below function

std::string ws2s(const std::wstring& wstr) {

    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.to_bytes(wstr);
}

I'm doing something wrong in handling wide characters or conversion. I'm on VS-2019 and using the default Unicode character set in my project properties.


Solution

  • Thanks to @Botje, So here is the solution if someone needs it in future.

    I have read the whole file in std::vector fileBuffer and then convert the filename to UTF-8 encoded C-style string

        // Convert the wstring filename to ```UTF-8``` encoded C-style string
        std::string filenameUtf8 = convertWStringToUTF8(filename);
    
        struct curl_httppost* formPost = nullptr;
        struct curl_httppost* lastPtr = nullptr;
    
        CURLFORMcode formAddResult = curl_formadd(&formPost, &lastPtr, 
            CURLFORM_COPYNAME, "file", 
            CURLFORM_BUFFER, filenameUtf8.c_str(), 
            CURLFORM_BUFFERPTR, fileBuffer.data(), 
            CURLFORM_BUFFERLENGTH, fileBuffer.size(), 
            CURLFORM_END);
    

    In case if you are wondering about UTF-8 conversion,

    std::string convertWStringToUTF8(const std::wstring& wstr) {
        std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> utf8_converter;
        return utf8_converter.to_bytes(wstr);
    }