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