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