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