Issue
I'm using libcurl
to upload some files to my server. I need to handle files whose names are in different languages e.g. Chinese, Hindi, etc. For that, I need to handle files using std::wstring
instead of std::string
.
libcurl
has a function with a prototype like below:
CURLcode curl_mime_filename(curl_mimepart *part, const char *filename);
But I cannot pass std::wstring::c_str()
because it will return const wchar_t*
instead of const char*
.
Edit: I still don't know what encoding scheme is used by the server as it is a third party app so I used std::wstring
for handling filenames and the conversion from std::wstring
to std::string
is done by the below function I found on this forum.
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);
}
Solution
curl_mime_filename
is not suitable for
files whose names are in different languages e.g. Chinese, Hindi, etc.
It is suitable for ASCII and UTF-8 file name encodings only.
The job of curl_mime_filename
is:
- Detect the data content type, for example
file.jpg
→image/jpeg
. - Add the multipart header
Content-Disposition
, for exampleContent-Disposition: attachment; name="data"; filename="file.jpg"
. The encoding tofilename=
is not set.
If you know the server encoding, then encode the chars
0x80 .. 0xff
in filename to%80 .. %ff
:- Example for UTF8:
Naïve file.txt
→Na%C3%AFve%20file.txt
. - Example for UCS2:
file.txt
→%00f%00i%00l%00e%00.%00t%00x%00t
.
Pass the encoded file name to
curl_mime_filename
.- Example for UTF8:
If you do not know the server encoding used or whish to use another encoding, then do not use
curl_mime_filename
.- Use the desired char encoding for the filename.
- Encode the chars over
0x7f
like above. - Use
curl_mime_headers
and set the headers mentioned above, usefilename*=
instead offilename=
.struct curl_slist *headers = nullptr; headers = curl_slist_append(headers, "Content-Type: image/jpeg"); headers = curl_slist_append(headers, "Content-Disposition: attachment; name=\"data\"; filename*=UTF-8''Na%C3%AFve%20file.txt"); curl_mime_headers(part, headers, true);
Answered By - 273K Answer Checked By - Dawn Plyler (WPSolving Volunteer)