xref: /curl/docs/libcurl/curl_mime_data_cb.md (revision 5a488251)
1---
2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
3SPDX-License-Identifier: curl
4Title: curl_mime_data_cb
5Section: 3
6Source: libcurl
7See-also:
8  - curl_easy_duphandle (3)
9  - curl_mime_addpart (3)
10  - curl_mime_data (3)
11  - curl_mime_name (3)
12Protocol:
13  - HTTP
14  - IMAP
15  - SMTP
16Added-in: 7.56.0
17---
18
19# NAME
20
21curl_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
28size_t readfunc(char *buffer, size_t size, size_t nitems, void *arg);
29
30int seekfunc(void *arg, curl_off_t offset, int origin);
31
32void freefunc(void *arg);
33
34CURLcode 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
42curl_mime_data_cb(3) sets the data source of a mime part's body content
43from 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
48as 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
51shown by the above prototype. This function is used when resending data (i.e.:
52after a redirect); this pointer may be set to NULL, in which case a resend
53might not be not possible.
54
55*freefunc* is a pointer to a user resource freeing callback function, with
56a signature as shown by the above prototype. If no resource is to be freed, it
57may safely be set to NULL. This function is called upon mime structure
58freeing.
59
60*arg* is a user defined argument to callback functions.
61
62The read callback function gets called by libcurl as soon as it needs to
63read data in order to send it to the peer - like if you ask it to upload or
64post data to the server. The data area pointed at by the pointer *buffer*
65should be filled up with at most *size* multiplied with *nitems* number
66of bytes by your function.
67
68Your read function must then return the actual number of bytes that it stored
69in that memory area. Returning 0 signals end-of-file to the library and cause
70it to stop the current transfer.
71
72If you stop the current transfer by returning 0 "pre-maturely" (i.e. before
73the server expected it, like when you have said you intend to upload N bytes
74and 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
77The read callback may return *CURL_READFUNC_ABORT* to stop the current
78operation immediately, resulting in a *CURLE_ABORTED_BY_CALLBACK* error
79code from the transfer.
80
81The callback can return *CURL_READFUNC_PAUSE* to cause reading from this
82connection to pause. See curl_easy_pause(3) for further details.
83
84The seek function gets called by libcurl to rewind input stream data or to
85seek to a certain position. The function shall work like fseek(3) or lseek(3)
86and it gets SEEK_SET, SEEK_CUR or SEEK_END as argument for *origin*,
87although libcurl currently only passes SEEK_SET.
88
89The 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
92is free to work around the problem if possible. The latter can sometimes be
93done by instead reading from the input or similar.
94
95Care must be taken if the part is bound to a curl easy handle that is later
96duplicated: the *arg* pointer argument is also duplicated, resulting in
97the pointed item to be shared between the original and the copied handle. In
98particular, special attention should be given to the *freefunc* procedure
99code since it then gets called twice with the same argument.
100
101# %PROTOCOLS%
102
103# EXAMPLE
104
105Sending a huge data string causes the same amount of memory to be allocated:
106to avoid overhead resources consumption, one might want to use a callback
107source to avoid data duplication. In this case, original data must be retained
108until after the transfer terminates.
109~~~c
110#include <string.h> /* for memcpy */
111char hugedata[512000];
112
113struct ctl {
114  char *buffer;
115  curl_off_t size;
116  curl_off_t position;
117};
118
119size_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
133int 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
152int 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
173CURLE_OK or a CURL error code upon failure.
174