Merge branch 'ep/http-curl-trace'
HTTP transport gained an option to produce more detailed debugging trace. * ep/http-curl-trace: imap-send.c: introduce the GIT_TRACE_CURL enviroment variable http.c: implement the GIT_TRACE_CURL environment variable
This commit is contained in:
commit
2f84df2ca0
@ -1083,6 +1083,14 @@ of clones and fetches.
|
||||
cloning of shallow repositories.
|
||||
See `GIT_TRACE` for available trace output options.
|
||||
|
||||
`GIT_TRACE_CURL`::
|
||||
Enables a curl full trace dump of all incoming and outgoing data,
|
||||
including descriptive information, of the git transport protocol.
|
||||
This is similar to doing curl `--trace-ascii` on the command line.
|
||||
This option overrides setting the `GIT_CURL_VERBOSE` environment
|
||||
variable.
|
||||
See `GIT_TRACE` for available trace output options.
|
||||
|
||||
`GIT_LITERAL_PATHSPECS`::
|
||||
Setting this variable to `1` will cause Git to treat all
|
||||
pathspecs literally, rather than as glob patterns. For example,
|
||||
|
124
http.c
124
http.c
@ -11,6 +11,7 @@
|
||||
#include "gettext.h"
|
||||
#include "transport.h"
|
||||
|
||||
static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
|
||||
#if LIBCURL_VERSION_NUM >= 0x070a08
|
||||
long int git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
|
||||
#else
|
||||
@ -477,6 +478,125 @@ static void set_curl_keepalive(CURL *c)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void redact_sensitive_header(struct strbuf *header)
|
||||
{
|
||||
const char *sensitive_header;
|
||||
|
||||
if (skip_prefix(header->buf, "Authorization:", &sensitive_header) ||
|
||||
skip_prefix(header->buf, "Proxy-Authorization:", &sensitive_header)) {
|
||||
/* The first token is the type, which is OK to log */
|
||||
while (isspace(*sensitive_header))
|
||||
sensitive_header++;
|
||||
while (*sensitive_header && !isspace(*sensitive_header))
|
||||
sensitive_header++;
|
||||
/* Everything else is opaque and possibly sensitive */
|
||||
strbuf_setlen(header, sensitive_header - header->buf);
|
||||
strbuf_addstr(header, " <redacted>");
|
||||
}
|
||||
}
|
||||
|
||||
static void curl_dump_header(const char *text, unsigned char *ptr, size_t size, int hide_sensitive_header)
|
||||
{
|
||||
struct strbuf out = STRBUF_INIT;
|
||||
struct strbuf **headers, **header;
|
||||
|
||||
strbuf_addf(&out, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
trace_strbuf(&trace_curl, &out);
|
||||
strbuf_reset(&out);
|
||||
strbuf_add(&out, ptr, size);
|
||||
headers = strbuf_split_max(&out, '\n', 0);
|
||||
|
||||
for (header = headers; *header; header++) {
|
||||
if (hide_sensitive_header)
|
||||
redact_sensitive_header(*header);
|
||||
strbuf_insert((*header), 0, text, strlen(text));
|
||||
strbuf_insert((*header), strlen(text), ": ", 2);
|
||||
strbuf_rtrim((*header));
|
||||
strbuf_addch((*header), '\n');
|
||||
trace_strbuf(&trace_curl, (*header));
|
||||
}
|
||||
strbuf_list_free(headers);
|
||||
strbuf_release(&out);
|
||||
}
|
||||
|
||||
static void curl_dump_data(const char *text, unsigned char *ptr, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
struct strbuf out = STRBUF_INIT;
|
||||
unsigned int width = 60;
|
||||
|
||||
strbuf_addf(&out, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
trace_strbuf(&trace_curl, &out);
|
||||
|
||||
for (i = 0; i < size; i += width) {
|
||||
size_t w;
|
||||
|
||||
strbuf_reset(&out);
|
||||
strbuf_addf(&out, "%s: ", text);
|
||||
for (w = 0; (w < width) && (i + w < size); w++) {
|
||||
unsigned char ch = ptr[i + w];
|
||||
|
||||
strbuf_addch(&out,
|
||||
(ch >= 0x20) && (ch < 0x80)
|
||||
? ch : '.');
|
||||
}
|
||||
strbuf_addch(&out, '\n');
|
||||
trace_strbuf(&trace_curl, &out);
|
||||
}
|
||||
strbuf_release(&out);
|
||||
}
|
||||
|
||||
static int curl_trace(CURL *handle, curl_infotype type, char *data, size_t size, void *userp)
|
||||
{
|
||||
const char *text;
|
||||
enum { NO_FILTER = 0, DO_FILTER = 1 };
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
trace_printf_key(&trace_curl, "== Info: %s", data);
|
||||
default: /* we ignore unknown types by default */
|
||||
return 0;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
curl_dump_header(text, (unsigned char *)data, size, DO_FILTER);
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
text = "=> Send data";
|
||||
curl_dump_data(text, (unsigned char *)data, size);
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
text = "=> Send SSL data";
|
||||
curl_dump_data(text, (unsigned char *)data, size);
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
curl_dump_header(text, (unsigned char *)data, size, NO_FILTER);
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
curl_dump_data(text, (unsigned char *)data, size);
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
text = "<= Recv SSL data";
|
||||
curl_dump_data(text, (unsigned char *)data, size);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setup_curl_trace(CURL *handle)
|
||||
{
|
||||
if (!trace_want(&trace_curl))
|
||||
return;
|
||||
curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, curl_trace);
|
||||
curl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);
|
||||
}
|
||||
|
||||
|
||||
static CURL *get_curl_handle(void)
|
||||
{
|
||||
CURL *result = curl_easy_init();
|
||||
@ -575,9 +695,9 @@ static CURL *get_curl_handle(void)
|
||||
warning("protocol restrictions not applied to curl redirects because\n"
|
||||
"your curl version is too old (>= 7.19.4)");
|
||||
#endif
|
||||
|
||||
if (getenv("GIT_CURL_VERBOSE"))
|
||||
curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(result, CURLOPT_VERBOSE, 1L);
|
||||
setup_curl_trace(result);
|
||||
|
||||
curl_easy_setopt(result, CURLOPT_USERAGENT,
|
||||
user_agent ? user_agent : git_user_agent());
|
||||
|
2
http.h
2
http.h
@ -225,4 +225,6 @@ extern int finish_http_object_request(struct http_object_request *freq);
|
||||
extern void abort_http_object_request(struct http_object_request *freq);
|
||||
extern void release_http_object_request(struct http_object_request *freq);
|
||||
|
||||
/* setup routine for curl_easy_setopt CURLOPT_DEBUGFUNCTION */
|
||||
void setup_curl_trace(CURL *handle);
|
||||
#endif /* HTTP_H */
|
||||
|
@ -1443,6 +1443,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc)
|
||||
|
||||
if (0 < verbosity || getenv("GIT_CURL_VERBOSE"))
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
setup_curl_trace(curl);
|
||||
|
||||
return curl;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user