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