| .\" ************************************************************************** |
| .\" * _ _ ____ _ |
| .\" * Project ___| | | | _ \| | |
| .\" * / __| | | | |_) | | |
| .\" * | (__| |_| | _ <| |___ |
| .\" * \___|\___/|_| \_\_____| |
| .\" * |
| .\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <[email protected]>, 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 "April 17, 2018" "libcurl 7.66.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)" |