1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel (at) haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 /* <DESC> 23 * Show how CURLOPT_DEBUGFUNCTION can be used. 24 * </DESC> 25 */ 26 #include <stdio.h> 27 #include <curl/curl.h> 28 29 struct data { 30 char trace_ascii; /* 1 or 0 */ 31 }; 32 33 static 34 void dump(const char *text, 35 FILE *stream, unsigned char *ptr, size_t size, 36 char nohex) 37 { 38 size_t i; 39 size_t c; 40 41 unsigned int width=0x10; 42 43 if(nohex) 44 /* without the hex output, we can fit more on screen */ 45 width = 0x40; 46 47 fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", 48 text, (long)size, (long)size); 49 50 for(i=0; i<size; i+= width) { 51 52 fprintf(stream, "%4.4lx: ", (long)i); 53 54 if(!nohex) { 55 /* hex not disabled, show it */ 56 for(c = 0; c < width; c++) 57 if(i+c < size) 58 fprintf(stream, "%02x ", ptr[i+c]); 59 else 60 fputs(" ", stream); 61 } 62 63 for(c = 0; (c < width) && (i+c < size); c++) { 64 /* check for 0D0A; if found, skip past and start a new line of output */ 65 if(nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) { 66 i+=(c+2-width); 67 break; 68 } 69 fprintf(stream, "%c", 70 (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); 71 /* check again for 0D0A, to avoid an extra \n if it's at width */ 72 if(nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { 73 i+=(c+3-width); 74 break; 75 } 76 } 77 fputc('\n', stream); /* newline */ 78 } 79 fflush(stream); 80 } 81 82 static 83 int my_trace(CURL *handle, curl_infotype type, 84 char *data, size_t size, 85 void *userp) 86 { 87 struct data *config = (struct data *)userp; 88 const char *text; 89 (void)handle; /* prevent compiler warning */ 90 91 switch (type) { 92 case CURLINFO_TEXT: 93 fprintf(stderr, "== Info: %s", data); 94 default: /* in case a new one is introduced to shock us */ 95 return 0; 96 97 case CURLINFO_HEADER_OUT: 98 text = "=> Send header"; 99 break; 100 case CURLINFO_DATA_OUT: 101 text = "=> Send data"; 102 break; 103 case CURLINFO_SSL_DATA_OUT: 104 text = "=> Send SSL data"; 105 break; 106 case CURLINFO_HEADER_IN: 107 text = "<= Recv header"; 108 break; 109 case CURLINFO_DATA_IN: 110 text = "<= Recv data"; 111 break; 112 case CURLINFO_SSL_DATA_IN: 113 text = "<= Recv SSL data"; 114 break; 115 } 116 117 dump(text, stderr, (unsigned char *)data, size, config->trace_ascii); 118 return 0; 119 } 120 121 int main(void) 122 { 123 CURL *curl; 124 CURLcode res; 125 struct data config; 126 127 config.trace_ascii = 1; /* enable ascii tracing */ 128 129 curl = curl_easy_init(); 130 if(curl) { 131 curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); 132 curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config); 133 134 /* the DEBUGFUNCTION has no effect until we enable VERBOSE */ 135 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 136 137 /* example.com is redirected, so we tell libcurl to follow redirection */ 138 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 139 140 curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/"); 141 res = curl_easy_perform(curl); 142 /* Check for errors */ 143 if(res != CURLE_OK) 144 fprintf(stderr, "curl_easy_perform() failed: %s\n", 145 curl_easy_strerror(res)); 146 147 /* always cleanup */ 148 curl_easy_cleanup(curl); 149 } 150 return 0; 151 } 152