0

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);
}
imli
  • 13
  • 4
  • Depends on how the server accept it I think. Probably UTF8? – user202729 Jun 22 '22 at 08:03
  • 1
    MIME has several conflicting standards over how non-ASCII characters are handled. What particular encoding(s) does your server actually support for Unicode filenames? If you don't know, ask the server admin. – Remy Lebeau Jun 22 '22 at 08:15

2 Answers2

0

According to the CURL wiki, curl_mime_filename expects filename to be in codepage determined by context on either the local or remote side. That means you have to ask server what encoding it uses and use that encoding too.

Osyotr
  • 784
  • 1
  • 7
  • 20
0

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:

  1. Detect the data content type, for example file.jpgimage/jpeg.
  2. Add the multipart header Content-Disposition, for example Content-Disposition: attachment; name="data"; filename="file.jpg". The encoding to filename= is not set.

  • If you know the server encoding, then encode the chars 0x80 .. 0xff in filename to %80 .. %ff:

    1. Example for UTF8: Naïve file.txtNa%C3%AFve%20file.txt.
    2. Example for UCS2: file.txt%00f%00i%00l%00e%00.%00t%00x%00t.

    Pass the encoded file name to curl_mime_filename.

  • If you do not know the server encoding used or whish to use another encoding, then do not use curl_mime_filename.

    1. Use the desired char encoding for the filename.
    2. Encode the chars over 0x7f like above.
    3. Use curl_mime_headers and set the headers mentioned above, use filename*= instead of filename=.
      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);
      
273K
  • 29,503
  • 10
  • 41
  • 64