summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/curl_trc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/curl_trc.c')
-rw-r--r--libs/libcurl/src/curl_trc.c205
1 files changed, 152 insertions, 53 deletions
diff --git a/libs/libcurl/src/curl_trc.c b/libs/libcurl/src/curl_trc.c
index eba9d57d52..dfe4d7d99b 100644
--- a/libs/libcurl/src/curl_trc.c
+++ b/libs/libcurl/src/curl_trc.c
@@ -53,6 +53,9 @@
#include "curl_memory.h"
#include "memdebug.h"
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
void Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size)
@@ -118,10 +121,16 @@ static void trc_infof(struct Curl_easy *data, struct curl_trc_feat *feat,
const char * const fmt, va_list ap)
{
int len = 0;
- char buffer[MAXINFO + 2];
+ char buffer[MAXINFO + 5];
if(feat)
- len = msnprintf(buffer, MAXINFO, "[%s] ", feat->name);
- len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
+ len = msnprintf(buffer, (MAXINFO + 1), "[%s] ", feat->name);
+ len += mvsnprintf(buffer + len, (MAXINFO + 1) - len, fmt, ap);
+ if(len >= MAXINFO) { /* too long, shorten with '...' */
+ --len;
+ buffer[len++] = '.';
+ buffer[len++] = '.';
+ buffer[len++] = '.';
+ }
buffer[len++] = '\n';
buffer[len] = '\0';
Curl_debug(data, CURLINFO_TEXT, buffer, len);
@@ -212,58 +221,144 @@ void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
}
#endif /* !CURL_DISABLE_FTP */
-static struct curl_trc_feat *trc_feats[] = {
- &Curl_trc_feat_read,
- &Curl_trc_feat_write,
+#ifndef CURL_DISABLE_SMTP
+struct curl_trc_feat Curl_trc_feat_smtp = {
+ "SMTP",
+ CURL_LOG_LVL_NONE,
+};
+
+void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
+{
+ DEBUGASSERT(!strchr(fmt, '\n'));
+ if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) {
+ va_list ap;
+ va_start(ap, fmt);
+ trc_infof(data, &Curl_trc_feat_smtp, fmt, ap);
+ va_end(ap);
+ }
+}
+#endif /* !CURL_DISABLE_SMTP */
+
+#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+struct curl_trc_feat Curl_trc_feat_ws = {
+ "WS",
+ CURL_LOG_LVL_NONE,
+};
+
+void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
+{
+ DEBUGASSERT(!strchr(fmt, '\n'));
+ if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) {
+ va_list ap;
+ va_start(ap, fmt);
+ trc_infof(data, &Curl_trc_feat_ws, fmt, ap);
+ va_end(ap);
+ }
+}
+#endif /* USE_WEBSOCKETS && !CURL_DISABLE_HTTP */
+
+#define TRC_CT_NONE (0)
+#define TRC_CT_PROTOCOL (1<<(0))
+#define TRC_CT_NETWORK (1<<(1))
+#define TRC_CT_PROXY (1<<(2))
+
+struct trc_feat_def {
+ struct curl_trc_feat *feat;
+ unsigned int category;
+};
+
+static struct trc_feat_def trc_feats[] = {
+ { &Curl_trc_feat_read, TRC_CT_NONE },
+ { &Curl_trc_feat_write, TRC_CT_NONE },
#ifndef CURL_DISABLE_FTP
- &Curl_trc_feat_ftp,
+ { &Curl_trc_feat_ftp, TRC_CT_PROTOCOL },
#endif
#ifndef CURL_DISABLE_DOH
- &Curl_doh_trc,
+ { &Curl_doh_trc, TRC_CT_NETWORK },
+#endif
+#ifndef CURL_DISABLE_SMTP
+ { &Curl_trc_feat_smtp, TRC_CT_PROTOCOL },
#endif
- NULL,
+#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+ { &Curl_trc_feat_ws, TRC_CT_PROTOCOL },
+#endif
+};
+
+struct trc_cft_def {
+ struct Curl_cftype *cft;
+ unsigned int category;
};
-static struct Curl_cftype *cf_types[] = {
- &Curl_cft_tcp,
- &Curl_cft_udp,
- &Curl_cft_unix,
- &Curl_cft_tcp_accept,
- &Curl_cft_happy_eyeballs,
- &Curl_cft_setup,
+static struct trc_cft_def trc_cfts[] = {
+ { &Curl_cft_tcp, TRC_CT_NETWORK },
+ { &Curl_cft_udp, TRC_CT_NETWORK },
+ { &Curl_cft_unix, TRC_CT_NETWORK },
+ { &Curl_cft_tcp_accept, TRC_CT_NETWORK },
+ { &Curl_cft_happy_eyeballs, TRC_CT_NETWORK },
+ { &Curl_cft_setup, TRC_CT_PROTOCOL },
#ifdef USE_NGHTTP2
- &Curl_cft_nghttp2,
+ { &Curl_cft_nghttp2, TRC_CT_PROTOCOL },
#endif
#ifdef USE_SSL
- &Curl_cft_ssl,
+ { &Curl_cft_ssl, TRC_CT_NETWORK },
#ifndef CURL_DISABLE_PROXY
- &Curl_cft_ssl_proxy,
+ { &Curl_cft_ssl_proxy, TRC_CT_PROXY },
#endif
#endif
#if !defined(CURL_DISABLE_PROXY)
#if !defined(CURL_DISABLE_HTTP)
- &Curl_cft_h1_proxy,
+ { &Curl_cft_h1_proxy, TRC_CT_PROXY },
#ifdef USE_NGHTTP2
- &Curl_cft_h2_proxy,
+ { &Curl_cft_h2_proxy, TRC_CT_PROXY },
#endif
- &Curl_cft_http_proxy,
+ { &Curl_cft_http_proxy, TRC_CT_PROXY },
#endif /* !CURL_DISABLE_HTTP */
- &Curl_cft_haproxy,
- &Curl_cft_socks_proxy,
+ { &Curl_cft_haproxy, TRC_CT_PROXY },
+ { &Curl_cft_socks_proxy, TRC_CT_PROXY },
#endif /* !CURL_DISABLE_PROXY */
#ifdef USE_HTTP3
- &Curl_cft_http3,
+ { &Curl_cft_http3, TRC_CT_PROTOCOL },
#endif
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
- &Curl_cft_http_connect,
+ { &Curl_cft_http_connect, TRC_CT_PROTOCOL },
#endif
- NULL,
};
-CURLcode Curl_trc_opt(const char *config)
+static void trc_apply_level_by_name(const char * const token, int lvl)
+{
+ size_t i;
+
+ for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) {
+ if(strcasecompare(token, trc_cfts[i].cft->name)) {
+ trc_cfts[i].cft->log_level = lvl;
+ break;
+ }
+ }
+ for(i = 0; i < ARRAYSIZE(trc_feats); ++i) {
+ if(strcasecompare(token, trc_feats[i].feat->name)) {
+ trc_feats[i].feat->log_level = lvl;
+ break;
+ }
+ }
+}
+
+static void trc_apply_level_by_category(int category, int lvl)
{
- char *token, *tok_buf, *tmp;
size_t i;
+
+ for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) {
+ if(!category || (trc_cfts[i].category & category))
+ trc_cfts[i].cft->log_level = lvl;
+ }
+ for(i = 0; i < ARRAYSIZE(trc_feats); ++i) {
+ if(!category || (trc_feats[i].category & category))
+ trc_feats[i].feat->log_level = lvl;
+ }
+}
+
+static CURLcode trc_opt(const char *config)
+{
+ char *token, *tok_buf, *tmp;
int lvl;
tmp = strdup(config);
@@ -285,42 +380,46 @@ CURLcode Curl_trc_opt(const char *config)
lvl = CURL_LOG_LVL_INFO;
break;
}
- for(i = 0; cf_types[i]; ++i) {
- if(strcasecompare(token, "all")) {
- cf_types[i]->log_level = lvl;
- }
- else if(strcasecompare(token, cf_types[i]->name)) {
- cf_types[i]->log_level = lvl;
- break;
- }
- }
- for(i = 0; trc_feats[i]; ++i) {
- if(strcasecompare(token, "all")) {
- trc_feats[i]->log_level = lvl;
- }
- else if(strcasecompare(token, trc_feats[i]->name)) {
- trc_feats[i]->log_level = lvl;
- break;
- }
- }
+ if(strcasecompare(token, "all"))
+ trc_apply_level_by_category(TRC_CT_NONE, lvl);
+ else if(strcasecompare(token, "protocol"))
+ trc_apply_level_by_category(TRC_CT_PROTOCOL, lvl);
+ else if(strcasecompare(token, "network"))
+ trc_apply_level_by_category(TRC_CT_NETWORK, lvl);
+ else if(strcasecompare(token, "proxy"))
+ trc_apply_level_by_category(TRC_CT_PROXY, lvl);
+ else
+ trc_apply_level_by_name(token, lvl);
+
token = strtok_r(NULL, ", ", &tok_buf);
}
free(tmp);
return CURLE_OK;
}
-CURLcode Curl_trc_init(void)
+CURLcode Curl_trc_opt(const char *config)
{
+ CURLcode result = config? trc_opt(config) : CURLE_OK;
#ifdef DEBUGBUILD
- /* WIP: we use the auto-init from an env var only in DEBUG builds for
- * convenience. */
- const char *config = getenv("CURL_DEBUG");
- if(config) {
- return Curl_trc_opt(config);
+ /* CURL_DEBUG can override anything */
+ if(!result) {
+ const char *dbg_config = getenv("CURL_DEBUG");
+ if(dbg_config)
+ result = trc_opt(dbg_config);
}
#endif /* DEBUGBUILD */
+ return result;
+}
+
+CURLcode Curl_trc_init(void)
+{
+#ifdef DEBUGBUILD
+ return Curl_trc_opt(NULL);
+#else
return CURLE_OK;
+#endif
}
+
#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */
CURLcode Curl_trc_init(void)