Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/curl/src/tool_cb_dbg.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /*************************************************************************** | |
| 2 * _ _ ____ _ | |
| 3 * Project ___| | | | _ \| | | |
| 4 * / __| | | | |_) | | | |
| 5 * | (__| |_| | _ <| |___ | |
| 6 * \___|\___/|_| \_\_____| | |
| 7 * | |
| 8 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. | |
| 9 * | |
| 10 * This software is licensed as described in the file COPYING, which | |
| 11 * you should have received as part of this distribution. The terms | |
| 12 * are also available at https://curl.haxx.se/docs/copyright.html. | |
| 13 * | |
| 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell | |
| 15 * copies of the Software, and permit persons to whom the Software is | |
| 16 * furnished to do so, under the terms of the COPYING file. | |
| 17 * | |
| 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | |
| 19 * KIND, either express or implied. | |
| 20 * | |
| 21 ***************************************************************************/ | |
| 22 #include "tool_setup.h" | |
| 23 | |
| 24 #define ENABLE_CURLX_PRINTF | |
| 25 /* use our own printf() functions */ | |
| 26 #include "curlx.h" | |
| 27 | |
| 28 #include "tool_cfgable.h" | |
| 29 #include "tool_convert.h" | |
| 30 #include "tool_msgs.h" | |
| 31 #include "tool_cb_dbg.h" | |
| 32 #include "tool_util.h" | |
| 33 | |
| 34 #include "memdebug.h" /* keep this as LAST include */ | |
| 35 | |
| 36 static void dump(const char *timebuf, const char *text, | |
| 37 FILE *stream, const unsigned char *ptr, size_t size, | |
| 38 trace tracetype, curl_infotype infotype); | |
| 39 | |
| 40 /* | |
| 41 ** callback for CURLOPT_DEBUGFUNCTION | |
| 42 */ | |
| 43 | |
| 44 int tool_debug_cb(CURL *handle, curl_infotype type, | |
| 45 char *data, size_t size, | |
| 46 void *userdata) | |
| 47 { | |
| 48 struct OperationConfig *operation = userdata; | |
| 49 struct GlobalConfig *config = operation->global; | |
| 50 FILE *output = config->errors; | |
| 51 const char *text; | |
| 52 struct timeval tv; | |
| 53 char timebuf[20]; | |
| 54 time_t secs; | |
| 55 | |
| 56 (void)handle; /* not used */ | |
| 57 | |
| 58 if(config->tracetime) { | |
| 59 struct tm *now; | |
| 60 static time_t epoch_offset; | |
| 61 static int known_offset; | |
| 62 tv = tvnow(); | |
| 63 if(!known_offset) { | |
| 64 epoch_offset = time(NULL) - tv.tv_sec; | |
| 65 known_offset = 1; | |
| 66 } | |
| 67 secs = epoch_offset + tv.tv_sec; | |
| 68 now = localtime(&secs); /* not thread safe but we don't care */ | |
| 69 msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ", | |
| 70 now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec); | |
| 71 } | |
| 72 else | |
| 73 timebuf[0] = 0; | |
| 74 | |
| 75 if(!config->trace_stream) { | |
| 76 /* open for append */ | |
| 77 if(!strcmp("-", config->trace_dump)) | |
| 78 config->trace_stream = stdout; | |
| 79 else if(!strcmp("%", config->trace_dump)) | |
| 80 /* Ok, this is somewhat hackish but we do it undocumented for now */ | |
| 81 config->trace_stream = config->errors; /* aka stderr */ | |
| 82 else { | |
| 83 config->trace_stream = fopen(config->trace_dump, FOPEN_WRITETEXT); | |
| 84 config->trace_fopened = TRUE; | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 if(config->trace_stream) | |
| 89 output = config->trace_stream; | |
| 90 | |
| 91 if(!output) { | |
| 92 warnf(config, "Failed to create/open output"); | |
| 93 return 0; | |
| 94 } | |
| 95 | |
| 96 if(config->tracetype == TRACE_PLAIN) { | |
| 97 /* | |
| 98 * This is the trace look that is similar to what libcurl makes on its | |
| 99 * own. | |
| 100 */ | |
| 101 static const char * const s_infotype[] = { | |
| 102 "*", "<", ">", "{", "}", "{", "}" | |
| 103 }; | |
| 104 static bool newl = FALSE; | |
| 105 static bool traced_data = FALSE; | |
| 106 | |
| 107 switch(type) { | |
| 108 case CURLINFO_HEADER_OUT: | |
| 109 if(size > 0) { | |
| 110 size_t st = 0; | |
| 111 size_t i; | |
| 112 for(i = 0; i < size - 1; i++) { | |
| 113 if(data[i] == '\n') { /* LF */ | |
| 114 if(!newl) { | |
| 115 fprintf(output, "%s%s ", timebuf, s_infotype[type]); | |
| 116 } | |
| 117 (void)fwrite(data + st, i - st + 1, 1, output); | |
| 118 st = i + 1; | |
| 119 newl = FALSE; | |
| 120 } | |
| 121 } | |
| 122 if(!newl) | |
| 123 fprintf(output, "%s%s ", timebuf, s_infotype[type]); | |
| 124 (void)fwrite(data + st, i - st + 1, 1, output); | |
| 125 } | |
| 126 newl = (size && (data[size - 1] != '\n')) ? TRUE : FALSE; | |
| 127 traced_data = FALSE; | |
| 128 break; | |
| 129 case CURLINFO_TEXT: | |
| 130 case CURLINFO_HEADER_IN: | |
| 131 if(!newl) | |
| 132 fprintf(output, "%s%s ", timebuf, s_infotype[type]); | |
| 133 (void)fwrite(data, size, 1, output); | |
| 134 newl = (size && (data[size - 1] != '\n')) ? TRUE : FALSE; | |
| 135 traced_data = FALSE; | |
| 136 break; | |
| 137 case CURLINFO_DATA_OUT: | |
| 138 case CURLINFO_DATA_IN: | |
| 139 case CURLINFO_SSL_DATA_IN: | |
| 140 case CURLINFO_SSL_DATA_OUT: | |
| 141 if(!traced_data) { | |
| 142 /* if the data is output to a tty and we're sending this debug trace | |
| 143 to stderr or stdout, we don't display the alert about the data not | |
| 144 being shown as the data _is_ shown then just not via this | |
| 145 function */ | |
| 146 if(!config->isatty || ((output != stderr) && (output != stdout))) { | |
| 147 if(!newl) | |
| 148 fprintf(output, "%s%s ", timebuf, s_infotype[type]); | |
| 149 fprintf(output, "[%zu bytes data]\n", size); | |
| 150 newl = FALSE; | |
| 151 traced_data = TRUE; | |
| 152 } | |
| 153 } | |
| 154 break; | |
| 155 default: /* nada */ | |
| 156 newl = FALSE; | |
| 157 traced_data = FALSE; | |
| 158 break; | |
| 159 } | |
| 160 | |
| 161 return 0; | |
| 162 } | |
| 163 | |
| 164 #ifdef CURL_DOES_CONVERSIONS | |
| 165 /* Special processing is needed for CURLINFO_HEADER_OUT blocks | |
| 166 * if they contain both headers and data (separated by CRLFCRLF). | |
| 167 * We dump the header text and then switch type to CURLINFO_DATA_OUT. | |
| 168 */ | |
| 169 if((type == CURLINFO_HEADER_OUT) && (size > 4)) { | |
| 170 size_t i; | |
| 171 for(i = 0; i < size - 4; i++) { | |
| 172 if(memcmp(&data[i], "\r\n\r\n", 4) == 0) { | |
| 173 /* dump everything through the CRLFCRLF as a sent header */ | |
| 174 text = "=> Send header"; | |
| 175 dump(timebuf, text, output, (unsigned char *)data, i + 4, | |
| 176 config->tracetype, type); | |
| 177 data += i + 3; | |
| 178 size -= i + 4; | |
| 179 type = CURLINFO_DATA_OUT; | |
| 180 data += 1; | |
| 181 break; | |
| 182 } | |
| 183 } | |
| 184 } | |
| 185 #endif /* CURL_DOES_CONVERSIONS */ | |
| 186 | |
| 187 switch(type) { | |
| 188 case CURLINFO_TEXT: | |
| 189 fprintf(output, "%s== Info: %s", timebuf, data); | |
| 190 /* FALLTHROUGH */ | |
| 191 default: /* in case a new one is introduced to shock us */ | |
| 192 return 0; | |
| 193 | |
| 194 case CURLINFO_HEADER_OUT: | |
| 195 text = "=> Send header"; | |
| 196 break; | |
| 197 case CURLINFO_DATA_OUT: | |
| 198 text = "=> Send data"; | |
| 199 break; | |
| 200 case CURLINFO_HEADER_IN: | |
| 201 text = "<= Recv header"; | |
| 202 break; | |
| 203 case CURLINFO_DATA_IN: | |
| 204 text = "<= Recv data"; | |
| 205 break; | |
| 206 case CURLINFO_SSL_DATA_IN: | |
| 207 text = "<= Recv SSL data"; | |
| 208 break; | |
| 209 case CURLINFO_SSL_DATA_OUT: | |
| 210 text = "=> Send SSL data"; | |
| 211 break; | |
| 212 } | |
| 213 | |
| 214 dump(timebuf, text, output, (unsigned char *) data, size, config->tracetype, | |
| 215 type); | |
| 216 return 0; | |
| 217 } | |
| 218 | |
| 219 static void dump(const char *timebuf, const char *text, | |
| 220 FILE *stream, const unsigned char *ptr, size_t size, | |
| 221 trace tracetype, curl_infotype infotype) | |
| 222 { | |
| 223 size_t i; | |
| 224 size_t c; | |
| 225 | |
| 226 unsigned int width = 0x10; | |
| 227 | |
| 228 if(tracetype == TRACE_ASCII) | |
| 229 /* without the hex output, we can fit more on screen */ | |
| 230 width = 0x40; | |
| 231 | |
| 232 fprintf(stream, "%s%s, %zu bytes (0x%zx)\n", timebuf, text, size, size); | |
| 233 | |
| 234 for(i = 0; i < size; i += width) { | |
| 235 | |
| 236 fprintf(stream, "%04zx: ", i); | |
| 237 | |
| 238 if(tracetype == TRACE_BIN) { | |
| 239 /* hex not disabled, show it */ | |
| 240 for(c = 0; c < width; c++) | |
| 241 if(i + c < size) | |
| 242 fprintf(stream, "%02x ", ptr[i + c]); | |
| 243 else | |
| 244 fputs(" ", stream); | |
| 245 } | |
| 246 | |
| 247 for(c = 0; (c < width) && (i + c < size); c++) { | |
| 248 /* check for 0D0A; if found, skip past and start a new line of output */ | |
| 249 if((tracetype == TRACE_ASCII) && | |
| 250 (i + c + 1 < size) && (ptr[i + c] == 0x0D) && | |
| 251 (ptr[i + c + 1] == 0x0A)) { | |
| 252 i += (c + 2 - width); | |
| 253 break; | |
| 254 } | |
| 255 #ifdef CURL_DOES_CONVERSIONS | |
| 256 /* repeat the 0D0A check above but use the host encoding for CRLF */ | |
| 257 if((tracetype == TRACE_ASCII) && | |
| 258 (i + c + 1 < size) && (ptr[i + c] == '\r') && | |
| 259 (ptr[i + c + 1] == '\n')) { | |
| 260 i += (c + 2 - width); | |
| 261 break; | |
| 262 } | |
| 263 /* convert to host encoding and print this character */ | |
| 264 fprintf(stream, "%c", convert_char(infotype, ptr[i + c])); | |
| 265 #else | |
| 266 (void)infotype; | |
| 267 fprintf(stream, "%c", ((ptr[i + c] >= 0x20) && (ptr[i + c] < 0x80)) ? | |
| 268 ptr[i + c] : UNPRINTABLE_CHAR); | |
| 269 #endif /* CURL_DOES_CONVERSIONS */ | |
| 270 /* check again for 0D0A, to avoid an extra \n if it's at width */ | |
| 271 if((tracetype == TRACE_ASCII) && | |
| 272 (i + c + 2 < size) && (ptr[i + c + 1] == 0x0D) && | |
| 273 (ptr[i + c + 2] == 0x0A)) { | |
| 274 i += (c + 3 - width); | |
| 275 break; | |
| 276 } | |
| 277 } | |
| 278 fputc('\n', stream); /* newline */ | |
| 279 } | |
| 280 fflush(stream); | |
| 281 } |
