1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2013, 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 http://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 #include <stdio.h> 23 #include <curl/curl.h> 24 25 struct data { 26 char trace_ascii; /* 1 or 0 */ 27 }; 28 29 static 30 void dump(const char *text, 31 FILE *stream, unsigned char *ptr, size_t size, 32 char nohex) 33 { 34 size_t i; 35 size_t c; 36 37 unsigned int width=0x10; 38 39 if(nohex) 40 /* without the hex output, we can fit more on screen */ 41 width = 0x40; 42 43 fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", 44 text, (long)size, (long)size); 45 46 for(i=0; i<size; i+= width) { 47 48 fprintf(stream, "%4.4lx: ", (long)i); 49 50 if(!nohex) { 51 /* hex not disabled, show it */ 52 for(c = 0; c < width; c++) 53 if(i+c < size) 54 fprintf(stream, "%02x ", ptr[i+c]); 55 else 56 fputs(" ", stream); 57 } 58 59 for(c = 0; (c < width) && (i+c < size); c++) { 60 /* check for 0D0A; if found, skip past and start a new line of output */ 61 if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) { 62 i+=(c+2-width); 63 break; 64 } 65 fprintf(stream, "%c", 66 (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); 67 /* check again for 0D0A, to avoid an extra \n if it's at width */ 68 if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { 69 i+=(c+3-width); 70 break; 71 } 72 } 73 fputc('\n', stream); /* newline */ 74 } 75 fflush(stream); 76 } 77 78 static 79 int my_trace(CURL *handle, curl_infotype type, 80 char *data, size_t size, 81 void *userp) 82 { 83 struct data *config = (struct data *)userp; 84 const char *text; 85 (void)handle; /* prevent compiler warning */ 86 87 switch (type) { 88 case CURLINFO_TEXT: 89 fprintf(stderr, "== Info: %s", data); 90 default: /* in case a new one is introduced to shock us */ 91 return 0; 92 93 case CURLINFO_HEADER_OUT: 94 text = "=> Send header"; 95 break; 96 case CURLINFO_DATA_OUT: 97 text = "=> Send data"; 98 break; 99 case CURLINFO_SSL_DATA_OUT: 100 text = "=> Send SSL data"; 101 break; 102 case CURLINFO_HEADER_IN: 103 text = "<= Recv header"; 104 break; 105 case CURLINFO_DATA_IN: 106 text = "<= Recv data"; 107 break; 108 case CURLINFO_SSL_DATA_IN: 109 text = "<= Recv SSL data"; 110 break; 111 } 112 113 dump(text, stderr, (unsigned char *)data, size, config->trace_ascii); 114 return 0; 115 } 116 117 int main(void) 118 { 119 CURL *curl; 120 CURLcode res; 121 struct data config; 122 123 config.trace_ascii = 1; /* enable ascii tracing */ 124 125 curl = curl_easy_init(); 126 if(curl) { 127 curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); 128 curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config); 129 130 /* the DEBUGFUNCTION has no effect until we enable VERBOSE */ 131 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 132 133 /* example.com is redirected, so we tell libcurl to follow redirection */ 134 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); 135 136 curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/"); 137 res = curl_easy_perform(curl); 138 /* Check for errors */ 139 if(res != CURLE_OK) 140 fprintf(stderr, "curl_easy_perform() failed: %s\n", 141 curl_easy_strerror(res)); 142 143 /* always cleanup */ 144 curl_easy_cleanup(curl); 145 } 146 return 0; 147 } 148