debug.c 3.0 KB

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