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.
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);
}