From 3f6133be2735936631c4bfe5aedd28ae9b084f3f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 12 Apr 2002 07:21:11 +0000 Subject: [PATCH] Jean-Philippe Barrette-LaPierre provided his patch that introduces CURLOPT_DEBUGFUNCTION and CURLOPT_DEBUGDATA. --- include/curl/curl.h | 23 +++++++++++++++++++++++ lib/ftp.c | 16 +++++++--------- lib/http.c | 17 ++++++----------- lib/sendf.c | 32 +++++++++++++++++++++++++++----- lib/sendf.h | 5 +++++ lib/url.c | 25 +++++++++++++++++++++---- lib/urldata.h | 4 +++- 7 files changed, 92 insertions(+), 30 deletions(-) diff --git a/include/curl/curl.h b/include/curl/curl.h index 05e1bec0d..ff37d3a5b 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -101,6 +101,23 @@ typedef int (*curl_passwd_callback)(void *clientp, char *buffer, int buflen); +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userp); /* whatever the user please */ + /* All possible error codes from all sorts of curl functions. Future versions may return other values, stay prepared. @@ -512,6 +529,12 @@ typedef enum { /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/ CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), CURLOPT_LASTENTRY /* the last unusued */ } CURLoption; diff --git a/lib/ftp.c b/lib/ftp.c index 0f0a8b9ac..52881c0cd 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -301,11 +301,8 @@ int Curl_GetFTPResponse(char *buf, CURLcode result; /* output debug output if that is requested */ - if(data->set.verbose) { - fputs("< ", data->set.err); - fwrite(line_start, perline, 1, data->set.err); - /* no need to output LF here, it is part of the data */ - } + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline); /* * We pass all response-lines to the callback function registered @@ -2080,15 +2077,13 @@ CURLcode Curl_ftpsendf(struct connectdata *conn, ssize_t write_len; char *sptr=s; CURLcode res = CURLE_OK; + size_t len; va_list ap; va_start(ap, fmt); vsnprintf(s, 250, fmt, ap); va_end(ap); - - if(conn->data->set.verbose) - fprintf(conn->data->set.err, "> %s\n", s); - + strcat(s, "\r\n"); /* append a trailing CRLF */ bytes_written=0; @@ -2101,6 +2096,9 @@ CURLcode Curl_ftpsendf(struct connectdata *conn, if(CURLE_OK != res) break; + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, bytes_written); + if(bytes_written != write_len) { write_len -= bytes_written; sptr += bytes_written; diff --git a/lib/http.c b/lib/http.c index 9e0275f70..42c167275 100644 --- a/lib/http.c +++ b/lib/http.c @@ -133,12 +133,6 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in, char *ptr; int size; - if(conn->data->set.verbose) { - fputs("> ", conn->data->set.err); - /* this data _may_ contain binary stuff */ - fwrite(in->buffer, in->size_used, 1, conn->data->set.err); - } - /* The looping below is required since we use non-blocking sockets, but due to the circumstances we will just loop and try again and again etc */ @@ -150,6 +144,10 @@ CURLcode add_buffer_send(int sockfd, struct connectdata *conn, send_buffer *in, if(CURLE_OK != res) break; + if(conn->data->set.verbose) + /* this data _may_ contain binary stuff */ + Curl_debug(conn->data, CURLINFO_DATA_OUT, ptr, amount); + if(amount != size) { size -= amount; ptr += amount; @@ -364,11 +362,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn, the line isn't really terminated until the LF comes */ /* output debug output if that is requested */ - if(data->set.verbose) { - fputs("< ", data->set.err); - fwrite(line_start, perline, 1, data->set.err); - /* no need to output LF here, it is part of the data */ - } + if(data->set.verbose) + Curl_debug(data, CURLINFO_DATA_IN, line_start, perline); if('\r' == line_start[0]) { /* end of headers */ diff --git a/lib/sendf.c b/lib/sendf.c index 721db36a8..6d4ab1fb7 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -135,10 +135,11 @@ void Curl_infof(struct SessionHandle *data, const char *fmt, ...) { va_list ap; if(data->set.verbose) { + char print_buffer[1024 + 1]; va_start(ap, fmt); - fputs("* ", data->set.err); - vfprintf(data->set.err, fmt, ap); + vsnprintf(print_buffer, 1024, fmt, ap); va_end(ap); + Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer)); } } @@ -174,9 +175,6 @@ CURLcode Curl_sendf(int sockfd, struct connectdata *conn, if(!s) return CURLE_OUT_OF_MEMORY; /* failure */ - if(data->set.verbose) - fprintf(data->set.err, "> %s", s); - bytes_written=0; write_len = strlen(s); sptr = s; @@ -188,6 +186,9 @@ CURLcode Curl_sendf(int sockfd, struct connectdata *conn, if(CURLE_OK != res) break; + if(data->set.verbose) + Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written); + if(bytes_written != write_len) { /* if not all was written at once, we must advance the pointer, decrease the size left and try again! */ @@ -380,6 +381,27 @@ int Curl_read(struct connectdata *conn, return CURLE_OK; } +/* return 0 on success */ +int Curl_debug(struct SessionHandle *data, curl_infotype type, + char *ptr, size_t size) +{ + static const char * const s_infotype[CURLINFO_END] = { + "* ", "< ", "> ", "{ ", "} " }; + + if(data->set.fdebug) + return (*data->set.fdebug)(data, type, ptr, size, + data->set.debugdata); + + if(type >= CURLINFO_DATA_IN) + /* don't do the data parts now */ + return 0; + + fwrite(s_infotype[type], 2, 1, data->set.err); + fwrite(ptr, size, 1, data->set.err); + + return 0; +} + /* * local variables: diff --git a/lib/sendf.h b/lib/sendf.h index 082feddcb..bafa999ba 100644 --- a/lib/sendf.h +++ b/lib/sendf.h @@ -53,4 +53,9 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd, void *mem, size_t len, ssize_t *written); +/* the function used to output verbose information */ +int Curl_debug(struct SessionHandle *handle, curl_infotype type, + char *data, size_t size); + + #endif diff --git a/lib/url.c b/lib/url.c index ed8d67b8b..365250e2d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -804,12 +804,29 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) */ data->set.set_resume_from = va_arg(param, long); break; + case CURLOPT_DEBUGFUNCTION: + /* + * stderr write callback. + */ + data->set.fdebug = va_arg(param, curl_debug_callback); + /* + * if the callback provided is NULL, it'll use the default callback + */ + break; + case CURLOPT_DEBUGDATA: + /* + * Set to a void * that should receive all error writes. This + * defaults to CURLOPT_STDERR for normal operations. + */ + data->set.debugdata = va_arg(param, void *); case CURLOPT_STDERR: /* * Set to a FILE * that should receive all error writes. This * defaults to stderr for normal operations. */ data->set.err = va_arg(param, FILE *); + if(!data->set.err) + data->set.err = stderr; break; case CURLOPT_HEADERFUNCTION: /* @@ -2265,13 +2282,13 @@ static CURLcode CreateConnection(struct SessionHandle *data, { struct in_addr in; (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr)); - infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name, + infof(data, "Connected to %s (%s) port %d\n", conn->hostaddr->h_name, #if defined(HAVE_INET_NTOA_R) - inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)) + inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)), #else - inet_ntoa(in) + inet_ntoa(in), #endif - ); + conn->port); } #endif diff --git a/lib/urldata.h b/lib/urldata.h index 95be3bcc8..43d2f5fe1 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -553,7 +553,8 @@ struct DynamicStatic { */ struct UserDefined { - FILE *err; /* the stderr writes goes here */ + FILE *err; /* the stderr user data goes here */ + void *debugdata; /* the data that will be passed to fdebug */ char *errorbuffer; /* store failure messages in here */ char *proxyuserpwd; /* Proxy , if used */ long proxyport; /* If non-zero, use this port number by default. If the @@ -584,6 +585,7 @@ struct UserDefined { curl_write_callback fwrite_header; /* function that stores headers */ curl_read_callback fread; /* function that reads the input */ curl_progress_callback fprogress; /* function for progress information */ + curl_debug_callback fdebug; /* function that write informational data */ void *progress_client; /* pointer to pass to the progress callback */ curl_passwd_callback fpasswd; /* call for password */ void *passwd_client; /* pass to the passwd callback */