libcpr / cpr

C++ Requests: Curl for People, a spiritual port of Python Requests.
https://docs.libcpr.org/
Other
6.29k stars 904 forks source link

Does cpr not yet support curl_mime_data_cb? #931

Open ZACKhdn opened 11 months ago

ZACKhdn commented 11 months ago

Is your feature request related to a problem?

I'm uploading a large file, cpr::Multipart and cpr::File(use file path) work fine. But if I want to upload a file with a Chinese name under the English windows system,will fail to upload. I guess it's the character encoding that prevents curl from opening the file properly. I've tried re-encoding the characters without success. So I try to use cpr::ReadCallback to upload the file, but it fails because the content-type is application/x-www-form-urlencoded. I want to use cpr::Multipart with file stream. Is there any other way I can solve this problem? thank you.

Possible Solution

I see that curl is supported but cpr is not yet. I hope that cpr will support it as soon as possible.

Alternatives

No response

Additional Context

No response

COM8 commented 11 months ago

@ZACKhdn Thanks for reporting. This shouldn't be too hard to add. Will look into it at ~the end of the month after my vacation.

ZACKhdn commented 11 months ago

I found a solution. curl uses 'fopen' to open files, which cannot handle Chinese paths on English Windows systems. We can use 'GetShortPathName' to convert the Chinese path to a short English path, allowing 'fopen' to open it correctly. However, please be aware that 'GetShortPathName' may fail if the system has disabled the short path functionality.

COM8 commented 11 months ago

I'm failing to reproduce this. I created a PR with a few test cases for it. What am I doing wrong here?

https://github.com/libcpr/cpr/pull/936

ZACKhdn commented 11 months ago

Thank you for your attention to this question. I tried this new gtest using win10 system.

I found, if build lincurl with Unicode, test can pass. If build libcurl with multibyte, the test will fail.

When in Unicode, libcurl did wchar character transcoding, use _wstati64/_waccess/_wfopen to process files. When in multibyte, libcurl uses char* directly, use _wtati64/_access/_fopen to process files.

Because char* cannot handle Chinese characters, so multibyte fails.

My code project is multibyte, so I used multibyte to build libcurl, and this problem occurred.

Some advices, if you want to test Chinese filename, you should not put the filename in the code. In my impression, the code source file encoding format(ansi/utf8), will make char save different content, then cause the file to fail to load. You should use some api like FindFirstFile to get the file path directly from disk.

In file_upload_tests.cpp, I think, must check size of expected_text, because under multibyte, std::ifstream may cannot read the file content. expected_text and response.text are both empty, the the test can't find the problem.

(My english is not very good, used google translate to help me, may be hard to read, sorry.)