From 164799e4c48f77c4266ae3b464fbc08fca924a10 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 12 Aug 2012 03:33:33 +0200 Subject: [PATCH] Curl debug output improvements and minor fixes. --- indra/cwdebug/debug.cc | 3 +- indra/cwdebug/debug.h | 16 ++++-- indra/llmessage/aicurl.cpp | 10 +--- indra/llmessage/debug_libcurl.cpp | 90 ++++++++++++++++++++++++++++--- 4 files changed, 97 insertions(+), 22 deletions(-) diff --git a/indra/cwdebug/debug.cc b/indra/cwdebug/debug.cc index b202a8ac6..cad6da46d 100644 --- a/indra/cwdebug/debug.cc +++ b/indra/cwdebug/debug.cc @@ -421,7 +421,8 @@ void cwdebug_backtrace(int n) namespace debug { -libcwd_do_type const libcw_do; +namespace libcwd { libcwd_do_type const libcw_do; } + ll_thread_local int Indent::S_indentation; Indent::Indent(int indent) : M_indent(indent) diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h index c8f15cfb9..862ea263c 100644 --- a/indra/cwdebug/debug.h +++ b/indra/cwdebug/debug.h @@ -46,14 +46,15 @@ struct buf2str { int mSize; }; -} // namespace libcwd - -enum print_thread_id_t { print_thread_id }; -inline void init() { } struct libcwd_do_type { void on() const { } }; extern LL_COMMON_API libcwd_do_type const libcw_do; + +} // namespace libcwd + +enum print_thread_id_t { print_thread_id }; +inline void init() { } struct Indent { int M_indent; static ll_thread_local int S_indentation; @@ -87,8 +88,13 @@ extern LL_COMMON_API fake_channel const notice; } // namespace dc } // namespace debug +#define LIBCWD_DEBUG_CHANNELS debug +#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; llinfos_nf << print_thread_id << (c).mLabel << ": " << Indent::print; +#define LibcwDoutStream llcont +#define LibcwDoutScopeEnd llcont << llendl; } while(0) + #define Debug(x) do { using namespace debug; x; } while(0) -#define Dout(a, b) do { using namespace debug; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0) +#define Dout(a, b) do { using namespace debug; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0) #define DoutEntering(a, b) \ int __slviewer_debug_indentation = 2; \ { \ diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index d22408491..edbcfec83 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -958,13 +958,6 @@ void CurlEasyRequest::addHeader(char const* header) #if defined(CWDEBUG) || defined(DEBUG_CURLIO) -#ifndef CWDEBUG -#define LIBCWD_DEBUGCHANNELS 0 -#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; llinfos_nf << dc::curlio.mLabel << ": "; -#define LibcwDoutStream llcont -#define LibcwDoutScopeEnd llcont << llendl; } while(0) -#endif - static int curl_debug_cb(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr) { #ifdef CWDEBUG @@ -977,14 +970,15 @@ static int curl_debug_cb(CURL*, curl_infotype infotype, char* buf, size_t size, libcw_do.marker().assign(marker.str().data(), marker.str().size()); if (!debug::channels::dc::curlio.is_on()) debug::channels::dc::curlio.on(); + LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcwd::libcw_do, dc::curlio|cond_nonewline_cf(infotype == CURLINFO_TEXT)) #else if (infotype == CURLINFO_TEXT) { while (size > 0 && (buf[size - 1] == '\r' || buf[size - 1] == '\n')) --size; } + LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcwd::libcw_do, dc::curlio) #endif - LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcw_do, dc::curlio|cond_nonewline_cf(infotype == CURLINFO_TEXT)) switch (infotype) { case CURLINFO_TEXT: diff --git a/indra/llmessage/debug_libcurl.cpp b/indra/llmessage/debug_libcurl.cpp index c981ef38f..3f85dcc2d 100644 --- a/indra/llmessage/debug_libcurl.cpp +++ b/indra/llmessage/debug_libcurl.cpp @@ -11,6 +11,9 @@ #include "debug_libcurl.h" #include "debug.h" #include "llerror.h" +#ifdef CWDEBUG +#include +#endif #define CURL_VERSION(major, minor, patch) \ (LIBCURL_VERSION_MAJOR > major || \ @@ -277,6 +280,7 @@ std::ostream& operator<<(std::ostream& os, CURLoption option) CASEPRINT(CURLOPT_PROGRESSDATA); CASEPRINT(CURLOPT_AUTOREFERER); CASEPRINT(CURLOPT_PROXYPORT); + CASEPRINT(CURLOPT_POSTFIELDSIZE); CASEPRINT(CURLOPT_HTTPPROXYTUNNEL); CASEPRINT(CURLOPT_INTERFACE); CASEPRINT(CURLOPT_KRBLEVEL); @@ -552,25 +556,26 @@ CURLcode debug_curl_easy_getinfo(CURL* curl, CURLINFO info, ...) CURLcode ret; va_list ap; union param_type { + void* some_ptr; long* long_ptr; - char* char_ptr; - curl_slist* curl_slist_ptr; + char** char_ptr; + curl_slist** curl_slist_ptr; double* double_ptr; } param; va_start(ap, info); - param.long_ptr = va_arg(ap, long*); + param.some_ptr = va_arg(ap, void*); va_end(ap); - ret = curl_easy_getinfo(curl, info, param.long_ptr); + ret = curl_easy_getinfo(curl, info, param.some_ptr); if (info == CURLINFO_PRIVATE) { - Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", 0x" << std::hex << (size_t)param.char_ptr << std::dec << ") = " << ret); + Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", 0x" << std::hex << (size_t)param.some_ptr << std::dec << ") = " << ret); } else { switch((info & CURLINFO_TYPEMASK)) { case CURLINFO_STRING: - Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (char*){ \"" << (ret == CURLE_OK ? param.char_ptr : " ") << "\" }) = " << ret); + Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (char**){ \"" << (ret == CURLE_OK ? *param.char_ptr : " ") << "\" }) = " << ret); break; case CURLINFO_LONG: Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (long*){ " << (ret == CURLE_OK ? *param.long_ptr : 0L) << "L }) = " << ret); @@ -579,7 +584,7 @@ CURLcode debug_curl_easy_getinfo(CURL* curl, CURLINFO info, ...) Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (double*){" << (ret == CURLE_OK ? *param.double_ptr : 0.) << "}) = " << ret); break; case CURLINFO_SLIST: - Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (curl_slist*){ " << (ret == CURLE_OK ? *param.curl_slist_ptr : unchanged_slist) << " }) = " << ret); + Dout(dc::curl, "curl_easy_getinfo(" << curl << ", " << info << ", (curl_slist**){ " << (ret == CURLE_OK ? **param.curl_slist_ptr : unchanged_slist) << " }) = " << ret); break; } } @@ -644,24 +649,93 @@ CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...) std::exit(EXIT_FAILURE); } va_end(ap); + static long postfieldsize; // Cache. Assumes only one thread sets CURLOPT_POSTFIELDSIZE. switch (param_type) { case CURLOPTTYPE_LONG: + { ret = curl_easy_setopt(handle, option, param.along); Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", " << param.along << "L) = " << ret); + if (option == CURLOPT_POSTFIELDSIZE) + { + postfieldsize = param.along; + } break; + } case CURLOPTTYPE_OBJECTPOINT: + { ret = curl_easy_setopt(handle, option, param.ptr); - Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (object*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); + LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcwd::libcw_do, dc::curl) + LibcwDoutStream << "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", "; + // For a subset of all options that take a char*, print the string passed. + if (option == CURLOPT_PROXY || // Set HTTP proxy to use. The parameter should be a char* to a zero terminated string holding the host name or dotted IP address. + option == CURLOPT_PROXYUSERPWD || // Pass a char* as parameter, which should be [user name]:[password] to use for the connection to the HTTP proxy. + option == CURLOPT_CAINFO || // Pass a char * to a zero terminated string naming a file holding one or more certificates to verify the peer with. + option == CURLOPT_URL || // Pass in a pointer to the actual URL to deal with. The parameter should be a char * to a zero terminated string [...] + option == CURLOPT_COOKIEFILE || // Pass a pointer to a zero terminated string as parameter. It should contain the name of your file holding cookie data to read. + option == CURLOPT_CUSTOMREQUEST || // Pass a pointer to a zero terminated string as parameter. It can be used to specify the request instead of GET or HEAD when performing HTTP based requests + option == CURLOPT_ENCODING || // Sets the contents of the Accept-Encoding: header sent in a HTTP request, and enables decoding of a response when a Content-Encoding: header is received. + option == CURLOPT_POSTFIELDS || + option == CURLOPT_COPYPOSTFIELDS) // Full data to post in a HTTP POST operation. + { + bool const is_postfield = option == CURLOPT_POSTFIELDS || option == CURLOPT_COPYPOSTFIELDS; + char* str = (char*)param.ptr; + long size; + LibcwDoutStream << "(char*)0x" << std::hex << (size_t)param.ptr << std::dec << ")"; + if (is_postfield) + { + size = postfieldsize < 32 ? postfieldsize : 32; // Only print first 32 characters (this was already written to debug output before). + } + else + { + size = strlen(str); + } + LibcwDoutStream << "["; + if (str) + { + LibcwDoutStream << libcwd::buf2str(str, size); + if (is_postfield && postfieldsize > 32) + LibcwDoutStream << "..."; + } + else + { + LibcwDoutStream << "NULL"; + } + LibcwDoutStream << "](" << (is_postfield ? postfieldsize : size) << " bytes))"; + } + else + { + LibcwDoutStream << "(object*)0x" << std::hex << (size_t)param.ptr << std::dec << ")"; + } + LibcwDoutStream << " = " << ret; + LibcwDoutScopeEnd; + if (option == CURLOPT_HTTPHEADER && param.ptr) + { + debug::Indent indent(2); + Dout(dc::curl, "HTTP Headers:"); + struct curl_slist* list = (struct curl_slist*)param.ptr; + while (list) + { + Dout(dc::curl, '"' << list->data << '"'); + list = list->next; + } + } break; + } case CURLOPTTYPE_FUNCTIONPOINT: ret = curl_easy_setopt(handle, option, param.ptr); Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (function*)0x" << std::hex << (size_t)param.ptr << std::dec << ") = " << ret); break; case CURLOPTTYPE_OFF_T: + { ret = curl_easy_setopt(handle, option, param.offset); Dout(dc::curl, "curl_easy_setopt(" << (AICURL*)handle << ", " << option << ", (curl_off_t)" << param.offset << ") = " << ret); + if (option == CURLOPT_POSTFIELDSIZE_LARGE) + { + postfieldsize = (long)param.offset; + } break; + } default: break; }