Buy commercial curl support from WolfSSL. We help you work
out your issues, debug your libcurl applications, use the API, port to new
platforms, add new features and more. With a team lead by the curl founder
himself.
Re: Upload multipart with cURL & json & custom headers
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Aleksandar Lazic via curl-library <curl-library_at_lists.haxx.se>
Date: Thu, 23 Jun 2022 12:45:45 +0200
Hi.
On Thu, 23 Jun 2022 09:08:13 +0000 (UTC)
Taw via curl-library <curl-library_at_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=_at_file_to_upload" -F "params=_at_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=_at_file_to_upload" \
-F "params=_at_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 '_at_'!
```
/********* 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
Date: Thu, 23 Jun 2022 12:45:45 +0200
Hi.
On Thu, 23 Jun 2022 09:08:13 +0000 (UTC)
Taw via curl-library <curl-library_at_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=_at_file_to_upload" -F "params=_at_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=_at_file_to_upload" \
-F "params=_at_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 '_at_'!
```
/********* 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.htmlReceived on 2022-06-23