113498266Sopenharmony_ci/***************************************************************************
213498266Sopenharmony_ci *                                  _   _ ____  _
313498266Sopenharmony_ci *  Project                     ___| | | |  _ \| |
413498266Sopenharmony_ci *                             / __| | | | |_) | |
513498266Sopenharmony_ci *                            | (__| |_| |  _ <| |___
613498266Sopenharmony_ci *                             \___|\___/|_| \_\_____|
713498266Sopenharmony_ci *
813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
913498266Sopenharmony_ci *
1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which
1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms
1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html.
1313498266Sopenharmony_ci *
1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell
1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is
1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file.
1713498266Sopenharmony_ci *
1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
1913498266Sopenharmony_ci * KIND, either express or implied.
2013498266Sopenharmony_ci *
2113498266Sopenharmony_ci * SPDX-License-Identifier: curl
2213498266Sopenharmony_ci *
2313498266Sopenharmony_ci ***************************************************************************/
2413498266Sopenharmony_ci
2513498266Sopenharmony_ci#include "curl_setup.h"
2613498266Sopenharmony_ci
2713498266Sopenharmony_ci#include <curl/curl.h>
2813498266Sopenharmony_ci
2913498266Sopenharmony_ci#include "curl_trc.h"
3013498266Sopenharmony_ci#include "urldata.h"
3113498266Sopenharmony_ci#include "easyif.h"
3213498266Sopenharmony_ci#include "cfilters.h"
3313498266Sopenharmony_ci#include "timeval.h"
3413498266Sopenharmony_ci#include "multiif.h"
3513498266Sopenharmony_ci#include "strcase.h"
3613498266Sopenharmony_ci
3713498266Sopenharmony_ci#include "cf-socket.h"
3813498266Sopenharmony_ci#include "connect.h"
3913498266Sopenharmony_ci#include "http2.h"
4013498266Sopenharmony_ci#include "http_proxy.h"
4113498266Sopenharmony_ci#include "cf-h1-proxy.h"
4213498266Sopenharmony_ci#include "cf-h2-proxy.h"
4313498266Sopenharmony_ci#include "cf-haproxy.h"
4413498266Sopenharmony_ci#include "cf-https-connect.h"
4513498266Sopenharmony_ci#include "socks.h"
4613498266Sopenharmony_ci#include "strtok.h"
4713498266Sopenharmony_ci#include "vtls/vtls.h"
4813498266Sopenharmony_ci#include "vquic/vquic.h"
4913498266Sopenharmony_ci
5013498266Sopenharmony_ci/* The last 3 #include files should be in this order */
5113498266Sopenharmony_ci#include "curl_printf.h"
5213498266Sopenharmony_ci#include "curl_memory.h"
5313498266Sopenharmony_ci#include "memdebug.h"
5413498266Sopenharmony_ci
5513498266Sopenharmony_ci
5613498266Sopenharmony_civoid Curl_debug(struct Curl_easy *data, curl_infotype type,
5713498266Sopenharmony_ci                char *ptr, size_t size)
5813498266Sopenharmony_ci{
5913498266Sopenharmony_ci  if(data->set.verbose) {
6013498266Sopenharmony_ci    static const char s_infotype[CURLINFO_END][3] = {
6113498266Sopenharmony_ci      "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
6213498266Sopenharmony_ci    if(data->set.fdebug) {
6313498266Sopenharmony_ci      bool inCallback = Curl_is_in_callback(data);
6413498266Sopenharmony_ci      Curl_set_in_callback(data, true);
6513498266Sopenharmony_ci      (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
6613498266Sopenharmony_ci      Curl_set_in_callback(data, inCallback);
6713498266Sopenharmony_ci    }
6813498266Sopenharmony_ci    else {
6913498266Sopenharmony_ci      switch(type) {
7013498266Sopenharmony_ci      case CURLINFO_TEXT:
7113498266Sopenharmony_ci      case CURLINFO_HEADER_OUT:
7213498266Sopenharmony_ci      case CURLINFO_HEADER_IN:
7313498266Sopenharmony_ci        fwrite(s_infotype[type], 2, 1, data->set.err);
7413498266Sopenharmony_ci        fwrite(ptr, size, 1, data->set.err);
7513498266Sopenharmony_ci        break;
7613498266Sopenharmony_ci      default: /* nada */
7713498266Sopenharmony_ci        break;
7813498266Sopenharmony_ci      }
7913498266Sopenharmony_ci    }
8013498266Sopenharmony_ci  }
8113498266Sopenharmony_ci}
8213498266Sopenharmony_ci
8313498266Sopenharmony_ci
8413498266Sopenharmony_ci/* Curl_failf() is for messages stating why we failed.
8513498266Sopenharmony_ci * The message SHALL NOT include any LF or CR.
8613498266Sopenharmony_ci */
8713498266Sopenharmony_civoid Curl_failf(struct Curl_easy *data, const char *fmt, ...)
8813498266Sopenharmony_ci{
8913498266Sopenharmony_ci  DEBUGASSERT(!strchr(fmt, '\n'));
9013498266Sopenharmony_ci  if(data->set.verbose || data->set.errorbuffer) {
9113498266Sopenharmony_ci    va_list ap;
9213498266Sopenharmony_ci    int len;
9313498266Sopenharmony_ci    char error[CURL_ERROR_SIZE + 2];
9413498266Sopenharmony_ci    va_start(ap, fmt);
9513498266Sopenharmony_ci    len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
9613498266Sopenharmony_ci
9713498266Sopenharmony_ci    if(data->set.errorbuffer && !data->state.errorbuf) {
9813498266Sopenharmony_ci      strcpy(data->set.errorbuffer, error);
9913498266Sopenharmony_ci      data->state.errorbuf = TRUE; /* wrote error string */
10013498266Sopenharmony_ci    }
10113498266Sopenharmony_ci    error[len++] = '\n';
10213498266Sopenharmony_ci    error[len] = '\0';
10313498266Sopenharmony_ci    Curl_debug(data, CURLINFO_TEXT, error, len);
10413498266Sopenharmony_ci    va_end(ap);
10513498266Sopenharmony_ci  }
10613498266Sopenharmony_ci}
10713498266Sopenharmony_ci
10813498266Sopenharmony_ci#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
10913498266Sopenharmony_ci
11013498266Sopenharmony_ci/* Curl_infof() is for info message along the way */
11113498266Sopenharmony_ci#define MAXINFO 2048
11213498266Sopenharmony_ci
11313498266Sopenharmony_civoid Curl_infof(struct Curl_easy *data, const char *fmt, ...)
11413498266Sopenharmony_ci{
11513498266Sopenharmony_ci  DEBUGASSERT(!strchr(fmt, '\n'));
11613498266Sopenharmony_ci  if(data && data->set.verbose) {
11713498266Sopenharmony_ci    va_list ap;
11813498266Sopenharmony_ci    int len;
11913498266Sopenharmony_ci    char buffer[MAXINFO + 2];
12013498266Sopenharmony_ci    va_start(ap, fmt);
12113498266Sopenharmony_ci    len = mvsnprintf(buffer, MAXINFO, fmt, ap);
12213498266Sopenharmony_ci    va_end(ap);
12313498266Sopenharmony_ci    buffer[len++] = '\n';
12413498266Sopenharmony_ci    buffer[len] = '\0';
12513498266Sopenharmony_ci    Curl_debug(data, CURLINFO_TEXT, buffer, len);
12613498266Sopenharmony_ci  }
12713498266Sopenharmony_ci}
12813498266Sopenharmony_ci
12913498266Sopenharmony_civoid Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
13013498266Sopenharmony_ci                       const char *fmt, ...)
13113498266Sopenharmony_ci{
13213498266Sopenharmony_ci  DEBUGASSERT(cf);
13313498266Sopenharmony_ci  if(Curl_trc_cf_is_verbose(cf, data)) {
13413498266Sopenharmony_ci    va_list ap;
13513498266Sopenharmony_ci    int len;
13613498266Sopenharmony_ci    char buffer[MAXINFO + 2];
13713498266Sopenharmony_ci    len = msnprintf(buffer, MAXINFO, "[%s] ", cf->cft->name);
13813498266Sopenharmony_ci    va_start(ap, fmt);
13913498266Sopenharmony_ci    len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
14013498266Sopenharmony_ci    va_end(ap);
14113498266Sopenharmony_ci    buffer[len++] = '\n';
14213498266Sopenharmony_ci    buffer[len] = '\0';
14313498266Sopenharmony_ci    Curl_debug(data, CURLINFO_TEXT, buffer, len);
14413498266Sopenharmony_ci  }
14513498266Sopenharmony_ci}
14613498266Sopenharmony_ci
14713498266Sopenharmony_ci
14813498266Sopenharmony_cistatic struct Curl_cftype *cf_types[] = {
14913498266Sopenharmony_ci  &Curl_cft_tcp,
15013498266Sopenharmony_ci  &Curl_cft_udp,
15113498266Sopenharmony_ci  &Curl_cft_unix,
15213498266Sopenharmony_ci  &Curl_cft_tcp_accept,
15313498266Sopenharmony_ci  &Curl_cft_happy_eyeballs,
15413498266Sopenharmony_ci  &Curl_cft_setup,
15513498266Sopenharmony_ci#ifdef USE_NGHTTP2
15613498266Sopenharmony_ci  &Curl_cft_nghttp2,
15713498266Sopenharmony_ci#endif
15813498266Sopenharmony_ci#ifdef USE_SSL
15913498266Sopenharmony_ci  &Curl_cft_ssl,
16013498266Sopenharmony_ci#ifndef CURL_DISABLE_PROXY
16113498266Sopenharmony_ci  &Curl_cft_ssl_proxy,
16213498266Sopenharmony_ci#endif
16313498266Sopenharmony_ci#endif
16413498266Sopenharmony_ci#if !defined(CURL_DISABLE_PROXY)
16513498266Sopenharmony_ci#if !defined(CURL_DISABLE_HTTP)
16613498266Sopenharmony_ci  &Curl_cft_h1_proxy,
16713498266Sopenharmony_ci#ifdef USE_NGHTTP2
16813498266Sopenharmony_ci  &Curl_cft_h2_proxy,
16913498266Sopenharmony_ci#endif
17013498266Sopenharmony_ci  &Curl_cft_http_proxy,
17113498266Sopenharmony_ci#endif /* !CURL_DISABLE_HTTP */
17213498266Sopenharmony_ci  &Curl_cft_haproxy,
17313498266Sopenharmony_ci  &Curl_cft_socks_proxy,
17413498266Sopenharmony_ci#endif /* !CURL_DISABLE_PROXY */
17513498266Sopenharmony_ci#ifdef ENABLE_QUIC
17613498266Sopenharmony_ci  &Curl_cft_http3,
17713498266Sopenharmony_ci#endif
17813498266Sopenharmony_ci#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
17913498266Sopenharmony_ci  &Curl_cft_http_connect,
18013498266Sopenharmony_ci#endif
18113498266Sopenharmony_ci  NULL,
18213498266Sopenharmony_ci};
18313498266Sopenharmony_ci
18413498266Sopenharmony_ciCURLcode Curl_trc_opt(const char *config)
18513498266Sopenharmony_ci{
18613498266Sopenharmony_ci  char *token, *tok_buf, *tmp;
18713498266Sopenharmony_ci  size_t i;
18813498266Sopenharmony_ci  int lvl;
18913498266Sopenharmony_ci
19013498266Sopenharmony_ci  tmp = strdup(config);
19113498266Sopenharmony_ci  if(!tmp)
19213498266Sopenharmony_ci    return CURLE_OUT_OF_MEMORY;
19313498266Sopenharmony_ci
19413498266Sopenharmony_ci  token = strtok_r(tmp, ", ", &tok_buf);
19513498266Sopenharmony_ci  while(token) {
19613498266Sopenharmony_ci    switch(*token) {
19713498266Sopenharmony_ci      case '-':
19813498266Sopenharmony_ci        lvl = CURL_LOG_LVL_NONE;
19913498266Sopenharmony_ci        ++token;
20013498266Sopenharmony_ci        break;
20113498266Sopenharmony_ci      case '+':
20213498266Sopenharmony_ci        lvl = CURL_LOG_LVL_INFO;
20313498266Sopenharmony_ci        ++token;
20413498266Sopenharmony_ci        break;
20513498266Sopenharmony_ci      default:
20613498266Sopenharmony_ci        lvl = CURL_LOG_LVL_INFO;
20713498266Sopenharmony_ci        break;
20813498266Sopenharmony_ci    }
20913498266Sopenharmony_ci    for(i = 0; cf_types[i]; ++i) {
21013498266Sopenharmony_ci      if(strcasecompare(token, "all")) {
21113498266Sopenharmony_ci        cf_types[i]->log_level = lvl;
21213498266Sopenharmony_ci      }
21313498266Sopenharmony_ci      else if(strcasecompare(token, cf_types[i]->name)) {
21413498266Sopenharmony_ci        cf_types[i]->log_level = lvl;
21513498266Sopenharmony_ci        break;
21613498266Sopenharmony_ci      }
21713498266Sopenharmony_ci    }
21813498266Sopenharmony_ci    token = strtok_r(NULL, ", ", &tok_buf);
21913498266Sopenharmony_ci  }
22013498266Sopenharmony_ci  free(tmp);
22113498266Sopenharmony_ci  return CURLE_OK;
22213498266Sopenharmony_ci}
22313498266Sopenharmony_ci
22413498266Sopenharmony_ciCURLcode Curl_trc_init(void)
22513498266Sopenharmony_ci{
22613498266Sopenharmony_ci#ifdef DEBUGBUILD
22713498266Sopenharmony_ci  /* WIP: we use the auto-init from an env var only in DEBUG builds for
22813498266Sopenharmony_ci   * convenience. */
22913498266Sopenharmony_ci  const char *config = getenv("CURL_DEBUG");
23013498266Sopenharmony_ci  if(config) {
23113498266Sopenharmony_ci    return Curl_trc_opt(config);
23213498266Sopenharmony_ci  }
23313498266Sopenharmony_ci#endif /* DEBUGBUILD */
23413498266Sopenharmony_ci  return CURLE_OK;
23513498266Sopenharmony_ci}
23613498266Sopenharmony_ci#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */
23713498266Sopenharmony_ci
23813498266Sopenharmony_ciCURLcode Curl_trc_init(void)
23913498266Sopenharmony_ci{
24013498266Sopenharmony_ci  return CURLE_OK;
24113498266Sopenharmony_ci}
24213498266Sopenharmony_ci
24313498266Sopenharmony_ci#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
244