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

Reply via email to