Skip to content

Commit

Permalink
Merge 624f380 into 222e65f
Browse files Browse the repository at this point in the history
  • Loading branch information
monnerat committed Aug 31, 2017
2 parents 222e65f + 624f380 commit 168f993
Show file tree
Hide file tree
Showing 89 changed files with 4,933 additions and 1,492 deletions.
4 changes: 2 additions & 2 deletions docs/cmdline-opts/form-string.d
@@ -1,6 +1,6 @@
Long: form-string
Help: Specify HTTP multipart POST data
Protocols: HTTP
Help: Specify multipart MIME data
Protocols: HTTP SMTP IMAP
Arg: <name=string>
See-also: form
---
Expand Down
66 changes: 59 additions & 7 deletions docs/cmdline-opts/form.d
@@ -1,21 +1,26 @@
Long: form
Short: F
Arg: <name=content>
Help: Specify HTTP multipart POST data
Protocols: HTTP
Help: Specify multipart MIME data
Protocols: HTTP SMTP IMAP
Mutexed: data head upload
---
This lets curl emulate a filled-in form in which a user has pressed the submit
button. This causes curl to POST data using the Content-Type
multipart/form-data according to RFC 2388. This enables uploading of binary
For HTTP protocol family, this lets curl emulate a filled-in form in which a
user has pressed the submit button. This causes curl to POST data using the
Content-Type multipart/form-data according to RFC 2388.

For SMTP and IMAP protocols, this is the mean to compose a multipart mail
message to transmit.

This enables uploading of binary
files etc. To force the 'content' part to be a file, prefix the file name with
an @ sign. To just get the content part from a file, prefix the file name with
the symbol <. The difference between @ and < is then that @ makes a file get
attached in the post as a file upload, while the < makes a text field and just
get the contents for that text field from a file.

Example: to send an image to a server, where \&'profile' is the name of the
form-field to which portrait.jpg will be the input:
Example: to send an image to an HTTP server, where \&'profile' is the name of
the form-field to which portrait.jpg will be the input:

curl -F profile=@portrait.jpg https://example.com/upload.cgi

Expand Down Expand Up @@ -49,6 +54,53 @@ or
Note that if a filename/path is quoted by double-quotes, any double-quote
or backslash within the filename must be escaped by backslash.

You can add custom headers to the field by setting headers=, like

curl -F "submit=OK;headers=\\"X-submit-type: OK\\"" example.com

or

curl -F "submit=OK;headers=@headerfile" example.com

The headers= keyword may appear more that once and above notes about quoting
apply. When headers are read from a file, Empty lines and lines starting
with '#' are comments and ignored; each header can be folded by splitting
between two words and starting the continuation line with a space; embedded
carriage-returns and trailing spaces are stripped.
Here is an example of a header file contents:

# This file contain two headers.
.br
X-header-1: this is a header

# The following header is folded.
.br
X-header-2: this is
.br
another header


To support sending multipart mail messages, the syntax is extended as follows:
.br
- name can be omitted: the equal sign is the first character of the argument,
.br
- if data starts with '(', this signals to start a new multipart: it can be
followed by a content type specification.
.br
- a multipart can be terminated with a '=)' argument.

Example: the following command sends an SMTP mime e-mail consisting in an
inline part in two alternative formats: plain text and HTML. It attaches a
text file:

curl -F '=(;type=multipart/alternative' \\
.br
-F '=plain text message' \\
.br
-F '= <body>HTML message</body>;type=text/html' \\
.br
-F '=)' -F '=@textfile.txt' ... smtp://example.com

See further examples and details in the MANUAL.

This option can be used multiple times.
4 changes: 2 additions & 2 deletions docs/examples/Makefile.inc
Expand Up @@ -26,8 +26,8 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
https multi-app multi-debugcallback multi-double multi-post multi-single \
persistant post-callback postit2 sepheaders simple simplepost simplessl \
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
smtp-mail smtp-multi smtp-ssl smtp-tls smtp-vrfy smtp-expn rtsp \
externalsocket resolve progressfunc pop3-retr pop3-list pop3-uidl \
smtp-mail smtp-mime smtp-multi smtp-ssl smtp-tls smtp-vrfy smtp-expn \
rtsp externalsocket resolve progressfunc pop3-retr pop3-list pop3-uidl \
pop3-dele pop3-top pop3-stat pop3-noop pop3-ssl pop3-tls pop3-multi \
imap-list imap-lsub imap-fetch imap-store imap-append imap-examine \
imap-search imap-create imap-delete imap-copy imap-noop imap-ssl \
Expand Down
159 changes: 159 additions & 0 deletions docs/examples/smtp-mime.c
@@ -0,0 +1,159 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/

/* <DESC>
* SMTP example showing how to send mime e-mails
* </DESC>
*/

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

/* This is a simple example showing how to send mime mail using libcurl's SMTP
* capabilities. For an example of using the multi interface please see
* smtp-multi.c.
*
* Note that this example requires libcurl 7.56.0 or above.
*/

#define FROM "<sender@example.org>"
#define TO "<addressee@example.net>"
#define CC "<info@example.org>"

static const char *headers_text[] = {
"Date: Tue, 22 Aug 2017 14:08:43 +0100",
"To: " TO,
"From: " FROM "(Example User)",
"Cc: " CC "(Another example User)",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>",
"Subject: example sending a MIME-formatted message",
NULL
};

static const char inline_text[] =
"This is the inline text message of the e-mail.\r\n"
"\r\n"
" It could be a lot of lines that would be displayed in an e-mail\r\n"
"viewer that is not able to handle HTML.\r\n";

static const char inline_html[] =
"<html><body>\r\n"
"<p>This is the inline <b>HTML</b> message of the e-mail.</p>"
"<br />\r\n"
"<p>It could be a lot of HTML data that would be displayed by "
"e-mail viewers able to handle HTML.</p>"
"</body></html>\r\n";


int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *headers = NULL;
struct curl_slist *recipients = NULL;
struct curl_slist *slist = NULL;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
const char **cpp;

curl = curl_easy_init();
if(curl) {
/* This is the URL for your mailserver */
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.com");

/* Note that this option isn't strictly required, omitting it will result
* in libcurl sending the MAIL FROM command with empty sender data. All
* autoresponses should have an empty reverse-path, and should be directed
* to the address in the reverse-path which triggered them. Otherwise,
* they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
* details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);

/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO);
recipients = curl_slist_append(recipients, CC);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

/* Build and set the message header list. */
for(cpp = headers_text; *cpp; cpp++)
headers = curl_slist_append(headers, *cpp);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

/* Build the mime message. */
mime = curl_mime_init(curl);

/* The inline part is an alterative proposing the html and the text
versions of the e-mail. */
alt = curl_mime_init(curl);

/* HTML message. */
part = curl_mime_addpart(alt);
curl_mime_data(part, inline_html, -1);
curl_mime_type(part, "text/html");

/* Text message. */
part = curl_mime_addpart(alt);
curl_mime_data(part, inline_text, -1);

/* Create the inline part. */
part = curl_mime_addpart(mime);
curl_mime_subparts(part, alt);
curl_mime_type(part, "multipart/alternative");
slist = curl_slist_append(NULL, "Content-Disposition: inline");
curl_mime_headers(part, slist, 1);

/* Add the current source program as an attachment. */
part = curl_mime_addpart(mime);
curl_mime_filedata(part, "smtp-mime.c");
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);

/* Send the message */
res = curl_easy_perform(curl);

/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));

/* Free lists. */
curl_slist_free_all(recipients);
curl_slist_free_all(headers);

/* curl won't send the QUIT command until you call cleanup, so you should
* be able to re-use this connection for additional messages (setting
* CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
* curl_easy_perform() again. It may not be a good idea to keep the
* connection open for a very long time though (more than a few minutes
* may result in the server timing out the connection), and you do want to
* clean up in the end.
*/
curl_easy_cleanup(curl);
}

return (int)res;
}
6 changes: 5 additions & 1 deletion docs/libcurl/Makefile.inc
Expand Up @@ -17,4 +17,8 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \
curl_easy_pause.3 curl_easy_recv.3 curl_easy_send.3 \
curl_multi_socket_action.3 curl_multi_wait.3 libcurl-symbols.3 \
libcurl-thread.3 curl_multi_socket_all.3 curl_global_sslset.3
libcurl-thread.3 curl_multi_socket_all.3 curl_global_sslset.3 \
curl_mime_init.3 curl_mime_free.3 curl_mime_addpart.3 curl_mime_name.3 \
curl_mime_data.3 curl_mime_data_cb.3 curl_mime_filedata.3 \
curl_mime_file.3 curl_mime_filename.3 curl_mime_subparts.3 \
curl_mime_type.3 curl_mime_headers.3 curl_mime_encoder.3
2 changes: 2 additions & 0 deletions docs/libcurl/curl_easy_setopt.3
Expand Up @@ -411,6 +411,8 @@ Size of file to send. \fICURLOPT_INFILESIZE(3)\fP
Size of file to send. \fICURLOPT_INFILESIZE_LARGE(3)\fP
.IP CURLOPT_UPLOAD
Upload data. See \fICURLOPT_UPLOAD(3)\fP
.IP CURLOPT_MIMEPOST
Post/send MIME data. See \fICURLOPT_MIMEPOST(3)\fP
.IP CURLOPT_MAXFILESIZE
Maximum file size to get. See \fICURLOPT_MAXFILESIZE(3)\fP
.IP CURLOPT_MAXFILESIZE_LARGE
Expand Down
51 changes: 51 additions & 0 deletions docs/libcurl/curl_mime_addpart.3
@@ -0,0 +1,51 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" **************************************************************************
.TH curl_mime_addpart 3 "22 August 2017" "libcurl 7.56.0" "libcurl Manual"
.SH NAME
curl_mime_addpart - append a new empty part to a mime structure
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "curl_mimepart * curl_mime_addpart(curl_mime * " mime ");"
.ad
.SH DESCRIPTION
curl_mime_addpart() appends a new empty part to the given mime structure and
returns a handle to it.
The returned part can be subsequently filled using functions from the mime API.

\fImime\fP is the handle of the mime structure in which the new part must be
appended.
.SH RETURN VALUE
A mime part structure handle, or NULL upon failure.

.SH "SEE ALSO"
.BR curl_mime_init "(3),"
.BR curl_mime_name "(3),"
.BR curl_mime_data "(3),"
.BR curl_mime_data_cb "(3),"
.BR curl_mime_filedata "(3),"
.BR curl_mime_file "(3),"
.BR curl_mime_filename "(3),"
.BR curl_mime_subparts "(3),"
.BR curl_mime_type "(3),"
.BR curl_mime_headers "(3),"
.BR curl_mime_encoder "(3)"
51 changes: 51 additions & 0 deletions docs/libcurl/curl_mime_data.3
@@ -0,0 +1,51 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" **************************************************************************
.TH curl_mime_data 3 "22 August 2017" "libcurl 7.56.0" "libcurl Manual"
.SH NAME
curl_mime_data - set a mime part's body data from memory
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "CURLcode curl_mime_data(curl_mimepart * " part ", const char * " data
.BI ", ssize_t " datasize ");"
.ad
.SH DESCRIPTION
curl_mime_data() sets a mime part's body content from memory data.

\fIdata\fP points to the data bytes: those are copied to the part and their
storage may safely be reused after call.
\fIdatasize\fP is the number of data bytes: it can be set to -1 to indicate
\fIdata\fP is a nul-terminated character string.
\fIpart\fP is the part's to assign contents to.

Setting a part's contents twice is valid: only the value set by the last call
is retained. It is possible to unassign part's contents by setting
\fIdata\fP to NULL.

Setting very large data is memory consuming: one might consider using
\fIcurl_mime_data_cb\fP() in such a case.
.SH RETURN VALUE
CURLE_OK or a CURL error code upon failure.

.SH "SEE ALSO"
.BR curl_mime_addpart "(3),"
.BR curl_mime_data_cb "(3)"

0 comments on commit 168f993

Please sign in to comment.