The pointer named \fIuserdata\fP is the one you set with the
\fICURLOPT_HEADERDATA(3)\fP option.
-This callback function must return the number of bytes actually taken care of.
-If that amount differs from the amount passed in to your function, it will signal
-an error to the library. This will cause the transfer to get aborted and the
-libcurl function in progress will return \fICURLE_WRITE_ERROR\fP.
+Your callback should return the number of bytes actually taken care of. If
+that amount differs from the amount passed to your callback function, it will
+signal an error condition to the library. This will cause the transfer to get
+aborted and the libcurl function used will return \fICURLE_WRITE_ERROR\fP.
+
+You can also abort the transfer by returning CURL_WRITEFUNC_ERROR. (7.87.0)
A complete HTTP header that is passed to this function can be up to
\fICURL_MAX_HTTP_HEADER\fP (100K) bytes and includes the final line terminator.
The \fICURLOPT_INTERLEAVEDATA(3)\fP is passed in the \fIuserdata\fP argument in
the callback.
+
+Your callback should return the number of bytes actually taken care of. If
+that amount differs from the amount passed to your callback function, it will
+signal an error condition to the library. This will cause the transfer to get
+aborted and the libcurl function used will return \fICURLE_WRITE_ERROR\fP.
+
+You can also abort the transfer by returning CURL_WRITEFUNC_ERROR. (7.87.0)
.SH DEFAULT
NULL, the interleave data is then passed to the regular write function:
\fICURLOPT_WRITEFUNCTION(3)\fP.
signal an error condition to the library. This will cause the transfer to get
aborted and the libcurl function used will return \fICURLE_WRITE_ERROR\fP.
+You can also abort the transfer by returning CURL_WRITEFUNC_ERROR. (7.87.0)
+
If your callback function returns CURL_WRITEFUNC_PAUSE it will cause this
transfer to become paused. See \fIcurl_easy_pause(3)\fP for further details.
CURL_WAIT_POLLOUT 7.28.0
CURL_WAIT_POLLPRI 7.28.0
CURL_WIN32 7.69.0
+CURL_WRITEFUNC_ERROR 7.87.0
CURL_WRITEFUNC_PAUSE 7.18.0
CURL_ZERO_TERMINATED 7.56.0
CURLALTSVC_H1 7.64.1
will signal libcurl to pause receiving on the current transfer. */
#define CURL_WRITEFUNC_PAUSE 0x10000001
+/* This is a magic return code for the write callback that, when returned,
+ will signal an error from the callback. */
+#define CURL_WRITEFUNC_ERROR 0xFFFFFFFF
+
typedef size_t (*curl_write_callback)(char *buffer,
size_t size,
size_t nitems,
const char *end = (char *)ptr + cb;
const char *scheme = NULL;
- /*
- * Once that libcurl has called back tool_header_cb() the returned value
- * is checked against the amount that was intended to be written, if
- * it does not match then it fails with CURLE_WRITE_ERROR. So at this
- * point returning a value different from sz*nmemb indicates failure.
- */
- size_t failure = (size && nmemb) ? 0 : 1;
-
if(!per->config)
- return failure;
+ return CURL_WRITEFUNC_ERROR;
#ifdef DEBUGBUILD
if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
warnf(per->config->global, "Header data exceeds single call write "
"limit!\n");
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
#endif
if(outs->stream) {
/* indication of problem, get out! */
free(filename);
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
outs->is_cd_filename = TRUE;
outs->alloc_filename = TRUE;
hdrcbdata->honor_cd_filename = FALSE; /* done now! */
if(!tool_create_output_file(outs, per->config))
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
break;
}
if(!outs->stream && !tool_create_output_file(outs, per->config))
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
if(hdrcbdata->config->writeout) {
char *value = memchr(ptr, ':', cb);
char *value = NULL;
if(!outs->stream && !tool_create_output_file(outs, per->config))
- return failure;
+ return CURL_WRITEFUNC_ERROR;
if(hdrcbdata->global->isatty && hdrcbdata->global->styled_output)
value = memchr(ptr, ':', cb);
intptr_t fhnd;
#endif
- /*
- * Once that libcurl has called back tool_write_cb() the returned value
- * is checked against the amount that was intended to be written, if
- * it does not match then it fails with CURLE_WRITE_ERROR. So at this
- * point returning a value different from sz*nmemb indicates failure.
- */
- const size_t failure = bytes ? 0 : 1;
-
#ifdef DEBUGBUILD
{
char *tty = curlx_getenv("CURL_ISATTY");
if(bytes > (size_t)CURL_MAX_HTTP_HEADER) {
warnf(config->global, "Header data size exceeds single call write "
"limit!\n");
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
}
else {
if(bytes > (size_t)CURL_MAX_WRITE_SIZE) {
warnf(config->global, "Data size exceeds single call write limit!\n");
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
}
}
if(check_fails) {
warnf(config->global, "Invalid output struct data for write callback\n");
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
}
#endif
if(!outs->stream && !tool_create_output_file(outs, per->config))
- return failure;
+ return CURL_WRITEFUNC_ERROR;
if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) {
/* binary output to terminal? */
"Use \"--output -\" to tell curl to output it to your terminal "
"anyway, or consider \"--output <FILE>\" to save to a file.\n");
config->synthetic_error = TRUE;
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
}
wc_len = MultiByteToWideChar(CP_UTF8, 0, buffer, in_len, NULL, 0);
wc_buf = (wchar_t*) malloc(wc_len * sizeof(wchar_t));
if(!wc_buf)
- return failure;
+ return CURL_WRITEFUNC_ERROR;
/* calculate buffer size for multi-byte characters */
wc_len = MultiByteToWideChar(CP_UTF8, 0, buffer, in_len, wc_buf, wc_len);
if(!wc_len) {
free(wc_buf);
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
if(!WriteConsoleW(
&wc_len,
NULL)) {
free(wc_buf);
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
free(wc_buf);
rc = bytes;
/* output buffering disabled */
int res = fflush(outs->stream);
if(res)
- return failure;
+ return CURL_WRITEFUNC_ERROR;
}
return rc;