curl_mime_data_cb.md (5576B)
1 --- 2 c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 3 SPDX-License-Identifier: curl 4 Title: curl_mime_data_cb 5 Section: 3 6 Source: libcurl 7 See-also: 8 - curl_easy_duphandle (3) 9 - curl_mime_addpart (3) 10 - curl_mime_data (3) 11 - curl_mime_name (3) 12 Protocol: 13 - HTTP 14 - IMAP 15 - SMTP 16 Added-in: 7.56.0 17 --- 18 19 # NAME 20 21 curl_mime_data_cb - set a callback-based data source for a mime part's body 22 23 # SYNOPSIS 24 25 ~~~c 26 #include <curl/curl.h> 27 28 size_t readfunc(char *buffer, size_t size, size_t nitems, void *arg); 29 30 int seekfunc(void *arg, curl_off_t offset, int origin); 31 32 void freefunc(void *arg); 33 34 CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, 35 curl_read_callback readfunc, 36 curl_seek_callback seekfunc, 37 curl_free_callback freefunc, void *arg); 38 ~~~ 39 40 # DESCRIPTION 41 42 curl_mime_data_cb(3) sets the data source of a mime part's body content 43 from a data read callback function. 44 45 *part* is the part's to assign contents to. 46 47 *readfunc* is a pointer to a data read callback function, with a signature 48 as shown by the above prototype. It may not be set to NULL. 49 50 *seekfunc* is a pointer to a seek callback function, with a signature as 51 shown by the above prototype. This function is used when resending data (i.e.: 52 after a redirect); this pointer may be set to NULL, in which case a resend 53 might not be not possible. 54 55 *freefunc* is a pointer to a user resource freeing callback function, with 56 a signature as shown by the above prototype. If no resource is to be freed, it 57 may safely be set to NULL. This function is called upon mime structure 58 freeing. 59 60 *arg* is a user defined argument to callback functions. 61 62 The read callback function gets called by libcurl as soon as it needs to 63 read data in order to send it to the peer - like if you ask it to upload or 64 post data to the server. The data area pointed at by the pointer *buffer* 65 should be filled up with at most *size* multiplied with *nitems* number 66 of bytes by your function. 67 68 Your read function must then return the actual number of bytes that it stored 69 in that memory area. Returning 0 signals end-of-file to the library and cause 70 it to stop the current transfer. 71 72 If you stop the current transfer by returning 0 "pre-maturely" (i.e. before 73 the server expected it, like when you have said you intend to upload N bytes 74 and yet you upload less than N bytes), you may experience that the server 75 "hangs" waiting for the rest of the data that does not come. 76 77 The read callback may return *CURL_READFUNC_ABORT* to stop the current 78 operation immediately, resulting in a *CURLE_ABORTED_BY_CALLBACK* error 79 code from the transfer. 80 81 The callback can return *CURL_READFUNC_PAUSE* to cause reading from this 82 connection to pause. See curl_easy_pause(3) for further details. 83 84 The seek function gets called by libcurl to rewind input stream data or to 85 seek to a certain position. The function shall work like fseek(3) or lseek(3) 86 and it gets SEEK_SET, SEEK_CUR or SEEK_END as argument for *origin*, 87 although libcurl currently only passes SEEK_SET. 88 89 The callback function must return *CURL_SEEKFUNC_OK* on success, 90 *CURL_SEEKFUNC_FAIL* to cause the upload operation to fail or 91 *CURL_SEEKFUNC_CANTSEEK* to indicate that while the seek failed, libcurl 92 is free to work around the problem if possible. The latter can sometimes be 93 done by instead reading from the input or similar. 94 95 Care must be taken if the part is bound to a curl easy handle that is later 96 duplicated: the *arg* pointer argument is also duplicated, resulting in 97 the pointed item to be shared between the original and the copied handle. In 98 particular, special attention should be given to the *freefunc* procedure 99 code since it then gets called twice with the same argument. 100 101 # %PROTOCOLS% 102 103 # EXAMPLE 104 105 Sending a huge data string causes the same amount of memory to be allocated: 106 to avoid overhead resources consumption, one might want to use a callback 107 source to avoid data duplication. In this case, original data must be retained 108 until after the transfer terminates. 109 ~~~c 110 #include <string.h> /* for memcpy */ 111 char hugedata[512000]; 112 113 struct ctl { 114 char *buffer; 115 curl_off_t size; 116 curl_off_t position; 117 }; 118 119 size_t read_callback(char *buffer, size_t size, size_t nitems, void *arg) 120 { 121 struct ctl *p = (struct ctl *) arg; 122 curl_off_t sz = p->size - p->position; 123 124 nitems *= size; 125 if(sz > nitems) 126 sz = nitems; 127 if(sz) 128 memcpy(buffer, p->buffer + p->position, sz); 129 p->position += sz; 130 return sz; 131 } 132 133 int seek_callback(void *arg, curl_off_t offset, int origin) 134 { 135 struct ctl *p = (struct ctl *) arg; 136 137 switch(origin) { 138 case SEEK_END: 139 offset += p->size; 140 break; 141 case SEEK_CUR: 142 offset += p->position; 143 break; 144 } 145 146 if(offset < 0) 147 return CURL_SEEKFUNC_FAIL; 148 p->position = offset; 149 return CURL_SEEKFUNC_OK; 150 } 151 152 int main(void) 153 { 154 CURL *curl = curl_easy_init(); 155 if(curl) { 156 curl_mime *mime = curl_mime_init(curl); 157 curl_mimepart *part = curl_mime_addpart(mime); 158 struct ctl hugectl; 159 160 hugectl.buffer = hugedata; 161 hugectl.size = sizeof(hugedata); 162 hugectl.position = 0; 163 curl_mime_data_cb(part, hugectl.size, read_callback, seek_callback, NULL, 164 &hugectl); 165 } 166 } 167 ~~~ 168 169 # %AVAILABILITY% 170 171 # RETURN VALUE 172 173 This function returns a CURLcode indicating success or error. 174 175 CURLE_OK (0) means everything was OK, non-zero means an error occurred, see 176 libcurl-errors(3). If CURLOPT_ERRORBUFFER(3) was set with curl_easy_setopt(3) 177 there can be an error message stored in the error buffer when non-zero is 178 returned.