1--- 2c: Copyright (C) Daniel Stenberg, <daniel.se>, et al. 3SPDX-License-Identifier: curl 4Title: CURLOPT_DEBUGFUNCTION 5Section: 3 6Source: libcurl 7See-also: 8 - CURLINFO_CONN_ID (3) 9 - CURLINFO_XFER_ID (3) 10 - CURLOPT_DEBUGDATA (3) 11 - CURLOPT_VERBOSE (3) 12 - curl_global_trace (3) 13--- 14 15# NAME 16 17CURLOPT_DEBUGFUNCTION - debug callback 18 19# SYNOPSIS 20 21~~~c 22#include <curl/curl.h> 23 24typedef enum { 25 CURLINFO_TEXT = 0, 26 CURLINFO_HEADER_IN, /* 1 */ 27 CURLINFO_HEADER_OUT, /* 2 */ 28 CURLINFO_DATA_IN, /* 3 */ 29 CURLINFO_DATA_OUT, /* 4 */ 30 CURLINFO_SSL_DATA_IN, /* 5 */ 31 CURLINFO_SSL_DATA_OUT, /* 6 */ 32 CURLINFO_END 33} curl_infotype; 34 35int debug_callback(CURL *handle, 36 curl_infotype type, 37 char *data, 38 size_t size, 39 void *clientp); 40 41CURLcode curl_easy_setopt(CURL *handle, CURLOPT_DEBUGFUNCTION, 42 debug_callback); 43~~~ 44 45# DESCRIPTION 46 47Pass a pointer to your callback function, which should match the prototype 48shown above. 49 50CURLOPT_DEBUGFUNCTION(3) replaces the standard debug function used when 51CURLOPT_VERBOSE(3) is in effect. This callback receives debug 52information, as specified in the *type* argument. This function must 53return 0. The *data* pointed to by the char * passed to this function is 54not null-terminated, but is exactly of the *size* as told by the 55*size* argument. 56 57The *clientp* argument is the pointer set with CURLOPT_DEBUGDATA(3). 58 59Available **curl_infotype** values: 60 61## CURLINFO_TEXT 62 63The data is informational text. 64 65## CURLINFO_HEADER_IN 66 67The data is header (or header-like) data received from the peer. 68 69## CURLINFO_HEADER_OUT 70 71The data is header (or header-like) data sent to the peer. 72 73## CURLINFO_DATA_IN 74 75The data is the unprocessed protocol data received from the peer. Even if the 76data is encoded or compressed, it is not not provided decoded nor decompressed 77to this callback. If you need the data in decoded and decompressed form, use 78CURLOPT_WRITEFUNCTION(3). 79 80## CURLINFO_DATA_OUT 81 82The data is protocol data sent to the peer. 83 84## CURLINFO_SSL_DATA_OUT 85 86The data is SSL/TLS (binary) data sent to the peer. 87 88## CURLINFO_SSL_DATA_IN 89 90The data is SSL/TLS (binary) data received from the peer. 91 92WARNING: This callback may be called with the curl *handle* set to an 93internal handle. (Added in 8.4.0) 94 95If you need to distinguish your curl *handle* from internal handles then 96set CURLOPT_PRIVATE(3) on your handle. 97 98# DEFAULT 99 100NULL 101 102# PROTOCOLS 103 104All 105 106# EXAMPLE 107 108~~~c 109static 110void dump(const char *text, 111 FILE *stream, unsigned char *ptr, size_t size) 112{ 113 size_t i; 114 size_t c; 115 unsigned int width = 0x10; 116 117 fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", 118 text, (long)size, (long)size); 119 120 for(i = 0; i < size; i += width) { 121 fprintf(stream, "%4.4lx: ", (long)i); 122 123 /* show hex to the left */ 124 for(c = 0; c < width; c++) { 125 if(i + c < size) 126 fprintf(stream, "%02x ", ptr[i + c]); 127 else 128 fputs(" ", stream); 129 } 130 131 /* show data on the right */ 132 for(c = 0; (c < width) && (i + c < size); c++) { 133 char x = (ptr[i + c] >= 0x20 && ptr[i + c] < 0x80) ? ptr[i + c] : '.'; 134 fputc(x, stream); 135 } 136 137 fputc('\n', stream); /* newline */ 138 } 139} 140 141static 142int my_trace(CURL *handle, curl_infotype type, 143 char *data, size_t size, 144 void *clientp) 145{ 146 const char *text; 147 (void)handle; /* prevent compiler warning */ 148 (void)clientp; 149 150 switch(type) { 151 case CURLINFO_TEXT: 152 fputs("== Info: ", stderr); 153 fwrite(data, size, 1, stderr); 154 default: /* in case a new one is introduced to shock us */ 155 return 0; 156 157 case CURLINFO_HEADER_OUT: 158 text = "=> Send header"; 159 break; 160 case CURLINFO_DATA_OUT: 161 text = "=> Send data"; 162 break; 163 case CURLINFO_SSL_DATA_OUT: 164 text = "=> Send SSL data"; 165 break; 166 case CURLINFO_HEADER_IN: 167 text = "<= Recv header"; 168 break; 169 case CURLINFO_DATA_IN: 170 text = "<= Recv data"; 171 break; 172 case CURLINFO_SSL_DATA_IN: 173 text = "<= Recv SSL data"; 174 break; 175 } 176 177 dump(text, stderr, (unsigned char *)data, size); 178 return 0; 179} 180 181int main(void) 182{ 183 CURL *curl; 184 CURLcode res; 185 186 curl = curl_easy_init(); 187 if(curl) { 188 curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); 189 190 /* the DEBUGFUNCTION has no effect until we enable VERBOSE */ 191 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 192 193 /* example.com is redirected, so we tell libcurl to follow redirection */ 194 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 195 196 curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); 197 res = curl_easy_perform(curl); 198 /* Check for errors */ 199 if(res != CURLE_OK) 200 fprintf(stderr, "curl_easy_perform() failed: %s\n", 201 curl_easy_strerror(res)); 202 203 /* always cleanup */ 204 curl_easy_cleanup(curl); 205 } 206 return 0; 207} 208~~~ 209 210# AVAILABILITY 211 212Always 213 214# RETURN VALUE 215 216Returns CURLE_OK 217