diff --git a/docs/libcurl/curl_mime_init.3 b/docs/libcurl/curl_mime_init.3 index 9ee466f12..09c3ee166 100644 --- a/docs/libcurl/curl_mime_init.3 +++ b/docs/libcurl/curl_mime_init.3 @@ -31,11 +31,14 @@ curl_mime_init - create a mime handle curl_mime *curl_mime_init(CURL *easy_handle); .fi .SH DESCRIPTION -\fIcurl_mime_init(3)\fP creates a handle to a new empty mime structure -intended to be used with \fIeasy_handle\fP. This mime structure can be -subsequently filled using the mime API, then attached to \fIeasy_handle\fP -using option \fICURLOPT_MIMEPOST(3)\fP within a \fIcurl_easy_setopt(3)\fP -call. +\fIcurl_mime_init(3)\fP creates a handle to a new empty mime structure, +This mime structure can be subsequently filled using the mime API, then +attached to some easy handle using option \fICURLOPT_MIMEPOST(3)\fP within +a \fIcurl_easy_setopt(3)\fP call or added as a multipart in another mime +handle's part using \fIcurl_mime_subparts(3)\fP. + +\fIeasy_handle\fP is used for part separator randomization and error +reporting. It does not need to be the final target handle. Using a mime handle is the recommended way to post an HTTP form, format and send a multi-part email with SMTP or upload such an email to an IMAP server. @@ -65,5 +68,6 @@ As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. A mime struct handle, or NULL upon failure. .SH "SEE ALSO" .BR curl_mime_addpart "(3)," +.BR curl_mime_subparts "(3)," .BR curl_mime_free "(3)," .BR CURLOPT_MIMEPOST "(3)" diff --git a/lib/easy.c b/lib/easy.c index b61ea7b7c..d7f93be1e 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -828,7 +828,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) /* Copy src->set into dst->set first, then deal with the strings afterwards */ dst->set = src->set; - Curl_mime_initpart(&dst->set.mimepost, dst); + Curl_mime_initpart(&dst->set.mimepost); /* clear all string pointers first */ memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); @@ -862,7 +862,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) } /* Duplicate mime data. */ - result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost); + result = Curl_mime_duppart(dst, &dst->set.mimepost, &src->set.mimepost); if(src->set.resolve) dst->state.resolve = dst->set.resolve; diff --git a/lib/formdata.c b/lib/formdata.c index 058e06f1f..b30e8deee 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -715,10 +715,10 @@ int curl_formget(struct curl_httppost *form, void *arg, CURLcode result; curl_mimepart toppart; - Curl_mime_initpart(&toppart, NULL); /* default form is empty */ + Curl_mime_initpart(&toppart); /* default form is empty */ result = Curl_getformdata(NULL, &toppart, form, NULL); if(!result) - result = Curl_mime_prepare_headers(&toppart, "multipart/form-data", + result = Curl_mime_prepare_headers(NULL, &toppart, "multipart/form-data", NULL, MIMESTRATEGY_FORM); while(!result) { diff --git a/lib/http.c b/lib/http.c index 66d3b4dd6..85528a221 100644 --- a/lib/http.c +++ b/lib/http.c @@ -265,7 +265,7 @@ static CURLcode http_setup_conn(struct Curl_easy *data, if(!http) return CURLE_OUT_OF_MEMORY; - Curl_mime_initpart(&http->form, data); + Curl_mime_initpart(&http->form); data->req.p.http = http; if(data->state.httpwant == CURL_HTTP_VERSION_3) { @@ -2303,7 +2303,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, cthdr = "multipart/form-data"; curl_mime_headers(http->sendit, data->set.headers, 0); - result = Curl_mime_prepare_headers(http->sendit, cthdr, + result = Curl_mime_prepare_headers(data, http->sendit, cthdr, NULL, MIMESTRATEGY_FORM); curl_mime_headers(http->sendit, NULL, 0); if(!result) diff --git a/lib/imap.c b/lib/imap.c index 03dc19166..a462ff042 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -777,7 +777,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data) /* Add external headers and mime version. */ curl_mime_headers(&data->set.mimepost, data->set.headers, 0); - result = Curl_mime_prepare_headers(&data->set.mimepost, NULL, + result = Curl_mime_prepare_headers(data, &data->set.mimepost, NULL, NULL, MIMESTRATEGY_MAIL); if(!result) diff --git a/lib/mime.c b/lib/mime.c index 117c66f4d..e3f2821db 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -1175,7 +1175,7 @@ void Curl_mime_cleanpart(curl_mimepart *part) Curl_safefree(part->mimetype); Curl_safefree(part->name); Curl_safefree(part->filename); - Curl_mime_initpart(part, part->easy); + Curl_mime_initpart(part); } /* Recursively delete a mime handle and its parts. */ @@ -1195,7 +1195,8 @@ void curl_mime_free(curl_mime *mime) } } -CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src) +CURLcode Curl_mime_duppart(struct Curl_easy *data, + curl_mimepart *dst, const curl_mimepart *src) { curl_mime *mime; curl_mimepart *d; @@ -1224,13 +1225,13 @@ CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src) case MIMEKIND_MULTIPART: /* No one knows about the cloned subparts, thus always attach ownership to the part. */ - mime = curl_mime_init(dst->easy); + mime = curl_mime_init(data); res = mime? curl_mime_subparts(dst, mime): CURLE_OUT_OF_MEMORY; /* Duplicate subparts. */ for(s = ((curl_mime *) src->arg)->firstpart; !res && s; s = s->nextpart) { d = curl_mime_addpart(mime); - res = d? Curl_mime_duppart(d, s): CURLE_OUT_OF_MEMORY; + res = d? Curl_mime_duppart(data, d, s): CURLE_OUT_OF_MEMORY; } break; default: /* Invalid kind: should not occur. */ @@ -1282,7 +1283,6 @@ curl_mime *curl_mime_init(struct Curl_easy *easy) mime = (curl_mime *) malloc(sizeof(*mime)); if(mime) { - mime->easy = easy; mime->parent = NULL; mime->firstpart = NULL; mime->lastpart = NULL; @@ -1302,10 +1302,9 @@ curl_mime *curl_mime_init(struct Curl_easy *easy) } /* Initialize a mime part. */ -void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy) +void Curl_mime_initpart(curl_mimepart *part) { memset((char *) part, 0, sizeof(*part)); - part->easy = easy; part->lastreadstatus = 1; /* Successful read status. */ mimesetstate(&part->state, MIMESTATE_BEGIN, NULL); } @@ -1321,7 +1320,7 @@ curl_mimepart *curl_mime_addpart(curl_mime *mime) part = (curl_mimepart *) malloc(sizeof(*part)); if(part) { - Curl_mime_initpart(part, mime->easy); + Curl_mime_initpart(part); part->parent = mime; if(mime->lastpart) @@ -1551,10 +1550,6 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part, cleanup_part_content(part); if(subparts) { - /* Must belong to the same data handle. */ - if(part->easy && subparts->easy && part->easy != subparts->easy) - return CURLE_BAD_FUNCTION_ARGUMENT; - /* Should not have been attached already. */ if(subparts->parent) return CURLE_BAD_FUNCTION_ARGUMENT; @@ -1565,8 +1560,7 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part, while(root->parent && root->parent->parent) root = root->parent->parent; if(subparts == root) { - if(part->easy) - failf(part->easy, "Can't add itself as a subpart"); + /* Can't add as a subpart of itself. */ return CURLE_BAD_FUNCTION_ARGUMENT; } } @@ -1766,7 +1760,8 @@ static bool content_type_match(const char *contenttype, return FALSE; } -CURLcode Curl_mime_prepare_headers(curl_mimepart *part, +CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, + curl_mimepart *part, const char *contenttype, const char *disposition, enum mimestrategy strategy) @@ -1835,12 +1830,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part, char *filename = NULL; if(part->name) { - name = escape_string(part->easy, part->name, strategy); + name = escape_string(data, part->name, strategy); if(!name) ret = CURLE_OUT_OF_MEMORY; } if(!ret && part->filename) { - filename = escape_string(part->easy, part->filename, strategy); + filename = escape_string(data, part->filename, strategy); if(!filename) ret = CURLE_OUT_OF_MEMORY; } @@ -1897,7 +1892,8 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part, if(content_type_match(contenttype, STRCONST("multipart/form-data"))) disposition = "form-data"; for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) { - ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy); + ret = Curl_mime_prepare_headers(data, subpart, NULL, + disposition, strategy); if(ret) return ret; } diff --git a/lib/mime.h b/lib/mime.h index bafde29f4..b9ea0f101 100644 --- a/lib/mime.h +++ b/lib/mime.h @@ -99,7 +99,6 @@ struct mime_state { /* A mime multipart. */ struct curl_mime { - struct Curl_easy *easy; /* The associated easy handle. */ curl_mimepart *parent; /* Parent part. */ curl_mimepart *firstpart; /* First part. */ curl_mimepart *lastpart; /* Last part. */ @@ -109,7 +108,6 @@ struct curl_mime { /* A mime part. */ struct curl_mimepart { - struct Curl_easy *easy; /* The associated easy handle. */ curl_mime *parent; /* Parent mime structure. */ curl_mimepart *nextpart; /* Forward linked list. */ enum mimekind kind; /* The part kind. */ @@ -139,14 +137,16 @@ CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...); !defined(CURL_DISABLE_IMAP)) /* Prototypes. */ -void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy); +void Curl_mime_initpart(struct curl_mimepart *part); void Curl_mime_cleanpart(struct curl_mimepart *part); -CURLcode Curl_mime_duppart(struct curl_mimepart *dst, +CURLcode Curl_mime_duppart(struct Curl_easy *data, + struct curl_mimepart *dst, const curl_mimepart *src); CURLcode Curl_mime_set_subparts(struct curl_mimepart *part, struct curl_mime *subparts, int take_ownership); -CURLcode Curl_mime_prepare_headers(struct curl_mimepart *part, +CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, + struct curl_mimepart *part, const char *contenttype, const char *disposition, enum mimestrategy strategy); @@ -159,11 +159,11 @@ void Curl_mime_unpause(struct curl_mimepart *part); #else /* if disabled */ -#define Curl_mime_initpart(x,y) +#define Curl_mime_initpart(x) #define Curl_mime_cleanpart(x) -#define Curl_mime_duppart(x,y) CURLE_OK /* Nothing to duplicate. Succeed */ +#define Curl_mime_duppart(x,y,z) CURLE_OK /* Nothing to duplicate. Succeed */ #define Curl_mime_set_subparts(a,b,c) CURLE_NOT_BUILT_IN -#define Curl_mime_prepare_headers(a,b,c,d) CURLE_NOT_BUILT_IN +#define Curl_mime_prepare_headers(a,b,c,d,e) CURLE_NOT_BUILT_IN #define Curl_mime_size(x) (curl_off_t) -1 #define Curl_mime_read NULL #define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN) diff --git a/lib/smtp.c b/lib/smtp.c index cbaf482e9..085faf9e3 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -697,7 +697,7 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data) /* Add external headers and mime version. */ curl_mime_headers(&data->set.mimepost, data->set.headers, 0); - result = Curl_mime_prepare_headers(&data->set.mimepost, NULL, + result = Curl_mime_prepare_headers(data, &data->set.mimepost, NULL, NULL, MIMESTRATEGY_MAIL); if(!result) diff --git a/lib/url.c b/lib/url.c index 74201f9bb..0af812bcd 100644 --- a/lib/url.c +++ b/lib/url.c @@ -560,7 +560,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) /* make libcurl quiet by default: */ set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ - Curl_mime_initpart(&set->mimepost, data); + Curl_mime_initpart(&set->mimepost); /* * libcurl 7.10 introduced SSL verification *by default*! This needs to be