168 lines
6.2 KiB
Groff
168 lines
6.2 KiB
Groff
|
.\" **************************************************************************
|
||
|
.\" * _ _ ____ _
|
||
|
.\" * Project ___| | | | _ \| |
|
||
|
.\" * / __| | | | |_) | |
|
||
|
.\" * | (__| |_| | _ <| |___
|
||
|
.\" * \___|\___/|_| \_\_____|
|
||
|
.\" *
|
||
|
.\" * Copyright (C) 1998 - 2018, 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_cb 3 "22 August 2017" "libcurl 7.56.0" "libcurl Manual"
|
||
|
.SH NAME
|
||
|
curl_mime_data_cb - set a callback-based data source for a mime part's body
|
||
|
.SH SYNOPSIS
|
||
|
.B #include <curl/curl.h>
|
||
|
.sp
|
||
|
size_t readfunc(char *buffer, size_t size, size_t nitems, void *arg);
|
||
|
.br
|
||
|
int seekfunc(void *arg, curl_off_t offset, int origin);
|
||
|
.br
|
||
|
void freefunc(void *arg);
|
||
|
.sp
|
||
|
.BI "CURLcode curl_mime_data_cb(curl_mimepart * " part ", curl_off_t " datasize ,
|
||
|
.br
|
||
|
.BI " curl_read_callback " readfunc ", curl_seek_callback " seekfunc ,
|
||
|
.br
|
||
|
.BI " curl_free_callback " freefunc ", void * " arg ");"
|
||
|
.ad
|
||
|
.SH DESCRIPTION
|
||
|
\fIcurl_mime_data_cb(3)\fP sets the data source of a mime part's body content
|
||
|
from a data read callback function.
|
||
|
|
||
|
\fIpart\fP is the part's to assign contents to.
|
||
|
|
||
|
\fIreadfunc\fP is a pointer to a data read callback function, with a signature
|
||
|
as shown by the above prototype. It may not be set to NULL.
|
||
|
|
||
|
\fIseekfunc\fP is a pointer to a seek callback function, with a signature as
|
||
|
shown by the above prototype. This function will be used upon resending data
|
||
|
(i.e.: after a redirect); this pointer may be set to NULL, in which case a
|
||
|
resend is not possible.
|
||
|
|
||
|
\fIfreefunc\fP is a pointer to a user resource freeing callback function, with
|
||
|
a signature as shown by the above prototype. If no resource is to be freed, it
|
||
|
may safely be set to NULL. This function will be called upon mime structure
|
||
|
freeing.
|
||
|
|
||
|
\fIarg\fP is a user defined argument to callback functions.
|
||
|
|
||
|
The read callback function gets called by libcurl as soon as it needs to
|
||
|
read data in order to send it to the peer - like if you ask it to upload or
|
||
|
post data to the server. The data area pointed at by the pointer \fIbuffer\fP
|
||
|
should be filled up with at most \fIsize\fP multiplied with \fInmemb\fP number
|
||
|
of bytes by your function.
|
||
|
|
||
|
Your read function must then return the actual number of bytes that it stored
|
||
|
in that memory area. Returning 0 will signal end-of-file to the library and
|
||
|
cause it to stop the current transfer.
|
||
|
|
||
|
If you stop the current transfer by returning 0 "pre-maturely" (i.e. before the
|
||
|
server expected it, like when you've said you will upload N bytes and you
|
||
|
upload less than N bytes), you may experience that the server "hangs" waiting
|
||
|
for the rest of the data that won't come.
|
||
|
|
||
|
The read callback may return \fICURL_READFUNC_ABORT\fP to stop the current
|
||
|
operation immediately, resulting in a \fICURLE_ABORTED_BY_CALLBACK\fP error
|
||
|
code from the transfer.
|
||
|
|
||
|
The callback can return \fICURL_READFUNC_PAUSE\fP to cause reading from this
|
||
|
connection to pause. See \fIcurl_easy_pause(3)\fP for further details.
|
||
|
|
||
|
The seek function gets called by libcurl to rewind input stream data or to
|
||
|
seek to a certain position. The function shall work like fseek(3) or lseek(3)
|
||
|
and it gets SEEK_SET, SEEK_CUR or SEEK_END as argument for \fIorigin\fP,
|
||
|
although libcurl currently only passes SEEK_SET.
|
||
|
|
||
|
The callback function must return \fICURL_SEEKFUNC_OK\fP on success,
|
||
|
\fICURL_SEEKFUNC_FAIL\fP to cause the upload operation to fail or
|
||
|
\fICURL_SEEKFUNC_CANTSEEK\fP to indicate that while the seek failed, libcurl
|
||
|
is free to work around the problem if possible. The latter can sometimes be
|
||
|
done by instead reading from the input or similar.
|
||
|
|
||
|
Care must be taken if the part is bound to a curl easy handle that is later
|
||
|
duplicated: the \fIarg\fP pointer argument is also duplicated, resulting in
|
||
|
the pointed item to be shared between the original and the copied handle.
|
||
|
In particular, special attention should be given to the \fIfreefunc\fP
|
||
|
procedure code since it will be called twice with the same argument.
|
||
|
|
||
|
.SH AVAILABILITY
|
||
|
As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0.
|
||
|
.SH RETURN VALUE
|
||
|
CURLE_OK or a CURL error code upon failure.
|
||
|
.SH EXAMPLE
|
||
|
Sending a huge data string will cause the same amount of memory to be
|
||
|
allocated: to avoid overhead resources consumption, one might want to use a
|
||
|
callback source to avoid data duplication. In this case, original data
|
||
|
must be retained until after the transfer terminates.
|
||
|
.nf
|
||
|
|
||
|
char hugedata[512000];
|
||
|
|
||
|
struct ctl {
|
||
|
char *buffer;
|
||
|
curl_off_t size;
|
||
|
curl_off_t position;
|
||
|
};
|
||
|
|
||
|
size_t read_callback(char *buffer, size_t size, size_t nitems, void *arg)
|
||
|
{
|
||
|
struct ctl *p = (struct ctl *) arg;
|
||
|
curl_off_t sz = p->size - p->position;
|
||
|
|
||
|
nitems *= size;
|
||
|
if(sz > nitems)
|
||
|
sz = nitems;
|
||
|
if(sz)
|
||
|
memcpy(buffer, p->buffer + p->position, sz);
|
||
|
p->position += sz;
|
||
|
return sz;
|
||
|
}
|
||
|
|
||
|
int seek_callback(void *arg, curl_off_t offset, int origin)
|
||
|
{
|
||
|
struct ctl *p = (struct ctl *) arg;
|
||
|
|
||
|
switch(origin) {
|
||
|
case SEEK_END:
|
||
|
offset += p->size;
|
||
|
break;
|
||
|
case SEEK_CUR:
|
||
|
offset += p->position;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(offset < 0)
|
||
|
return CURL_SEEKFUNC_FAIL;
|
||
|
p->position = offset;
|
||
|
return CURL_SEEKFUNC_OK;
|
||
|
}
|
||
|
|
||
|
CURL *easy = curl_easy_init();
|
||
|
curl_mime *mime = curl_mime_init(easy);
|
||
|
curl_mimepart *part = curl_mime_addpart(mime);
|
||
|
struct ctl hugectl;
|
||
|
|
||
|
hugectl.buffer = hugedata;
|
||
|
hugectl.size = sizeof hugedata;
|
||
|
hugectl.position = 0;
|
||
|
curl_mime_data_cb(part, hugectl.size, read_callback, seek_callback, NULL,
|
||
|
&hugectl);
|
||
|
|
||
|
.SH "SEE ALSO"
|
||
|
.BR curl_mime_addpart "(3),"
|
||
|
.BR curl_mime_data "(3),"
|
||
|
.BR curl_mime_name "(3),"
|
||
|
.BR curl_easy_duphandle "(3)"
|