如何通过宽字符libcurl API只需要const char*?



我使用libcurl上传一些文件到我的服务器。我需要处理文件的名称是在不同的语言,如中文,印地语等。为此,我需要使用std::wstring而不是std::string来处理文件。

libcurl函数的原型如下:

CURLcode curl_mime_filename(curl_mimepart *part, const char *filename);

但是我不能传递std::wstring::c_str(),因为它将返回const wchar_t*而不是const char*

编辑:我仍然不知道服务器使用什么编码方案,因为它是第三方应用程序,所以我使用std::wstring来处理文件名,从std::wstringstd::string的转换是由我在这个论坛上发现的以下功能完成的。

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

curl_mime_filename不适合

文件名为不同语言的文件,例如中文、印地语等

只适合ASCII和UTF-8文件名编码。

curl_mime_filename的工作是:

  1. 检测数据内容类型,例如:file.jpgimage/jpeg
  2. 添加多部分标题Content-Disposition,例如Content-Disposition: attachment; name="data"; filename="file.jpg"。没有设置编码为filename=

  • 如果您知道服务器编码,则将文件名中的字符0x80 .. 0xff编码为%80 .. %ff:

    1. 以UTF8为例:Naïve file.txtNa%C3%AFve%20file.txt.
    2. UCS2示例:file.txt%00f%00i%00l%00e%00.%00t%00x%00t

    传递编码后的文件名给curl_mime_filename

  • 如果您不知道所使用的服务器编码或希望使用其他编码,则不要使用curl_mime_filename

    1. 使用所需的字符编码作为文件名
    2. 像上面那样编码0x7f上的字符。
    3. 使用curl_mime_headers并设置上面提到的头,使用filename*=代替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);
      

根据CURL wiki,curl_mime_filename期望filenamecodepage determined by context on either the local or remote side中。这意味着你必须询问服务器使用什么编码,并使用该编码。

最新更新