Hi. On Thu, 23 Jun 2022 09:08:13 +0000 (UTC) Taw via curl-library <curl-library@lists.haxx.se> wrote:
> Hello, > I am trying to do a multipart/form-data upload with cURL + json + custom > headers and I am not sure how to do it properly. I want something equivalent > to this cmdline command: curl -H 'Content-Type: multipart/form-data' -H > 'x-custom-header: custom value' https://url_to_upload -F > "file=@file_to_upload" -F "params=@params.json" > > For simple POST requests, I am doing this and works: > curl_slist_append(headers, "Content-type: application/json") > curl_slist_append(headers, "x-custom-header: custom value") > curl_easy_setopt(CURLOPT_HTTPHEADER, headers); > curl_easy_setopt(CURLOPT_POSTFIELDS, json_str); > I read https://curl.se/libcurl/c/postit2.html, but still not sure how to send > the json and the headers for multipart upload. 1. For JSON should I use > CURLOPT_POSTFIELDS or curl_mime_addpart/curl_mime_name/curl_mime_data?2. For > headers should I use CURLOPT_HTTPHEADER or curl_mime_headers?3. Can I reuse a > mime handle for multiple files? Is there any way to reset it, so I won't do > curl_mime_init/curl_mime_free for each file? thank you Have you tried to use the option --libcurl to create the code? https://curl.se/docs/manpage.html#--libcurl curl -H 'Content-Type: multipart/form-data' \ -H 'x-custom-header: custom value' \ -F "file=@file_to_upload" \ -F "params=@params.json" \ --libcurl libcurl-code.c \ https://url_to_upload This is the output from that curl version ``` curl --version curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 \ brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) \ libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3 \ Release-Date: 2020-01-08 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 \ pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos \ Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets ``` What I have seen is if the files not exist will the created code be different, so use existing files with '@'! ``` /********* Sample code generated by the curl command line tool ********** * All curl_easy_setopt() options are documented at: * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html ************************************************************************/ #include <curl/curl.h> int main(int argc, char *argv[]) { CURLcode ret; CURL *hnd; curl_mime *mime1; curl_mimepart *part1; struct curl_slist *slist1; mime1 = NULL; slist1 = NULL; slist1 = curl_slist_append(slist1, "Content-Type: multipart/form-data"); slist1 = curl_slist_append(slist1, "x-custom-header: custom value"); hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L); curl_easy_setopt(hnd, CURLOPT_URL, "https://url_to_upload"); curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); mime1 = curl_mime_init(hnd); part1 = curl_mime_addpart(mime1); curl_mime_filedata(part1, "file_to_upload"); curl_mime_name(part1, "file"); part1 = curl_mime_addpart(mime1); curl_mime_filedata(part1, "params.json"); curl_mime_name(part1, "params"); curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime1); curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1); curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.68.0"); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS); curl_easy_setopt(hnd, CURLOPT_SSH_KNOWNHOSTS, ".../.ssh/known_hosts"); curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated as source easily. You may select to either not use them or implement them yourself. CURLOPT_WRITEDATA set to a objectpointer CURLOPT_INTERLEAVEDATA set to a objectpointer CURLOPT_WRITEFUNCTION set to a functionpointer CURLOPT_READDATA set to a objectpointer CURLOPT_READFUNCTION set to a functionpointer CURLOPT_SEEKDATA set to a objectpointer CURLOPT_SEEKFUNCTION set to a functionpointer CURLOPT_ERRORBUFFER set to a objectpointer CURLOPT_STDERR set to a objectpointer CURLOPT_HEADERFUNCTION set to a functionpointer CURLOPT_HEADERDATA set to a objectpointer */ ret = curl_easy_perform(hnd); curl_easy_cleanup(hnd); hnd = NULL; curl_mime_free(mime1); mime1 = NULL; curl_slist_free_all(slist1); slist1 = NULL; return (int)ret; } /**** End of sample code ****/ ``` Hth Alex -- Unsubscribe: https://lists.haxx.se/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html