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