00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tool_setup.h"
00023 #define ENABLE_CURLX_PRINTF
00024
00025 #include "curlx.h"
00026 #include "tool_cfgable.h"
00027 #include "tool_writeout.h"
00028
00029 #include "memdebug.h"
00030
00031 typedef enum {
00032 VAR_NONE,
00033 VAR_TOTAL_TIME,
00034 VAR_NAMELOOKUP_TIME,
00035 VAR_CONNECT_TIME,
00036 VAR_APPCONNECT_TIME,
00037 VAR_PRETRANSFER_TIME,
00038 VAR_STARTTRANSFER_TIME,
00039 VAR_SIZE_DOWNLOAD,
00040 VAR_SIZE_UPLOAD,
00041 VAR_SPEED_DOWNLOAD,
00042 VAR_SPEED_UPLOAD,
00043 VAR_HTTP_CODE,
00044 VAR_HTTP_CODE_PROXY,
00045 VAR_HEADER_SIZE,
00046 VAR_REQUEST_SIZE,
00047 VAR_EFFECTIVE_URL,
00048 VAR_CONTENT_TYPE,
00049 VAR_NUM_CONNECTS,
00050 VAR_REDIRECT_TIME,
00051 VAR_REDIRECT_COUNT,
00052 VAR_FTP_ENTRY_PATH,
00053 VAR_REDIRECT_URL,
00054 VAR_SSL_VERIFY_RESULT,
00055 VAR_PROXY_SSL_VERIFY_RESULT,
00056 VAR_EFFECTIVE_FILENAME,
00057 VAR_PRIMARY_IP,
00058 VAR_PRIMARY_PORT,
00059 VAR_LOCAL_IP,
00060 VAR_LOCAL_PORT,
00061 VAR_HTTP_VERSION,
00062 VAR_SCHEME,
00063 VAR_NUM_OF_VARS
00064 } replaceid;
00065
00066 struct variable {
00067 const char *name;
00068 replaceid id;
00069 };
00070
00071
00072 static const struct variable replacements[]={
00073 {"url_effective", VAR_EFFECTIVE_URL},
00074 {"http_code", VAR_HTTP_CODE},
00075 {"response_code", VAR_HTTP_CODE},
00076 {"http_connect", VAR_HTTP_CODE_PROXY},
00077 {"time_total", VAR_TOTAL_TIME},
00078 {"time_namelookup", VAR_NAMELOOKUP_TIME},
00079 {"time_connect", VAR_CONNECT_TIME},
00080 {"time_appconnect", VAR_APPCONNECT_TIME},
00081 {"time_pretransfer", VAR_PRETRANSFER_TIME},
00082 {"time_starttransfer", VAR_STARTTRANSFER_TIME},
00083 {"size_header", VAR_HEADER_SIZE},
00084 {"size_request", VAR_REQUEST_SIZE},
00085 {"size_download", VAR_SIZE_DOWNLOAD},
00086 {"size_upload", VAR_SIZE_UPLOAD},
00087 {"speed_download", VAR_SPEED_DOWNLOAD},
00088 {"speed_upload", VAR_SPEED_UPLOAD},
00089 {"content_type", VAR_CONTENT_TYPE},
00090 {"num_connects", VAR_NUM_CONNECTS},
00091 {"time_redirect", VAR_REDIRECT_TIME},
00092 {"num_redirects", VAR_REDIRECT_COUNT},
00093 {"ftp_entry_path", VAR_FTP_ENTRY_PATH},
00094 {"redirect_url", VAR_REDIRECT_URL},
00095 {"ssl_verify_result", VAR_SSL_VERIFY_RESULT},
00096 {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT},
00097 {"filename_effective", VAR_EFFECTIVE_FILENAME},
00098 {"remote_ip", VAR_PRIMARY_IP},
00099 {"remote_port", VAR_PRIMARY_PORT},
00100 {"local_ip", VAR_LOCAL_IP},
00101 {"local_port", VAR_LOCAL_PORT},
00102 {"http_version", VAR_HTTP_VERSION},
00103 {"scheme", VAR_SCHEME},
00104 {NULL, VAR_NONE}
00105 };
00106
00107 void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
00108 {
00109 FILE *stream = stdout;
00110 const char *ptr = writeinfo;
00111 char *stringp = NULL;
00112 long longinfo;
00113 double doubleinfo;
00114
00115 while(ptr && *ptr) {
00116 if('%' == *ptr) {
00117 if('%' == ptr[1]) {
00118
00119 fputc('%', stream);
00120 ptr += 2;
00121 }
00122 else {
00123
00124 char *end;
00125 char keepit;
00126 int i;
00127 if('{' == ptr[1]) {
00128 bool match = FALSE;
00129 end = strchr(ptr, '}');
00130 ptr += 2;
00131 if(!end) {
00132 fputs("%{", stream);
00133 continue;
00134 }
00135 keepit = *end;
00136 *end = 0;
00137 for(i = 0; replacements[i].name; i++) {
00138 if(curl_strequal(ptr, replacements[i].name)) {
00139 match = TRUE;
00140 switch(replacements[i].id) {
00141 case VAR_EFFECTIVE_URL:
00142 if((CURLE_OK ==
00143 curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &stringp))
00144 && stringp)
00145 fputs(stringp, stream);
00146 break;
00147 case VAR_HTTP_CODE:
00148 if(CURLE_OK ==
00149 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &longinfo))
00150 fprintf(stream, "%03ld", longinfo);
00151 break;
00152 case VAR_HTTP_CODE_PROXY:
00153 if(CURLE_OK ==
00154 curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE,
00155 &longinfo))
00156 fprintf(stream, "%03ld", longinfo);
00157 break;
00158 case VAR_HEADER_SIZE:
00159 if(CURLE_OK ==
00160 curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &longinfo))
00161 fprintf(stream, "%ld", longinfo);
00162 break;
00163 case VAR_REQUEST_SIZE:
00164 if(CURLE_OK ==
00165 curl_easy_getinfo(curl, CURLINFO_REQUEST_SIZE, &longinfo))
00166 fprintf(stream, "%ld", longinfo);
00167 break;
00168 case VAR_NUM_CONNECTS:
00169 if(CURLE_OK ==
00170 curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &longinfo))
00171 fprintf(stream, "%ld", longinfo);
00172 break;
00173 case VAR_REDIRECT_COUNT:
00174 if(CURLE_OK ==
00175 curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &longinfo))
00176 fprintf(stream, "%ld", longinfo);
00177 break;
00178 case VAR_REDIRECT_TIME:
00179 if(CURLE_OK ==
00180 curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME,
00181 &doubleinfo))
00182 fprintf(stream, "%.6f", doubleinfo);
00183 break;
00184 case VAR_TOTAL_TIME:
00185 if(CURLE_OK ==
00186 curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &doubleinfo))
00187 fprintf(stream, "%.6f", doubleinfo);
00188 break;
00189 case VAR_NAMELOOKUP_TIME:
00190 if(CURLE_OK ==
00191 curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME,
00192 &doubleinfo))
00193 fprintf(stream, "%.6f", doubleinfo);
00194 break;
00195 case VAR_CONNECT_TIME:
00196 if(CURLE_OK ==
00197 curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &doubleinfo))
00198 fprintf(stream, "%.6f", doubleinfo);
00199 break;
00200 case VAR_APPCONNECT_TIME:
00201 if(CURLE_OK ==
00202 curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME,
00203 &doubleinfo))
00204 fprintf(stream, "%.6f", doubleinfo);
00205 break;
00206 case VAR_PRETRANSFER_TIME:
00207 if(CURLE_OK ==
00208 curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME,
00209 &doubleinfo))
00210 fprintf(stream, "%.6f", doubleinfo);
00211 break;
00212 case VAR_STARTTRANSFER_TIME:
00213 if(CURLE_OK ==
00214 curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
00215 &doubleinfo))
00216 fprintf(stream, "%.6f", doubleinfo);
00217 break;
00218 case VAR_SIZE_UPLOAD:
00219 if(CURLE_OK ==
00220 curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &doubleinfo))
00221 fprintf(stream, "%.0f", doubleinfo);
00222 break;
00223 case VAR_SIZE_DOWNLOAD:
00224 if(CURLE_OK ==
00225 curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD,
00226 &doubleinfo))
00227 fprintf(stream, "%.0f", doubleinfo);
00228 break;
00229 case VAR_SPEED_DOWNLOAD:
00230 if(CURLE_OK ==
00231 curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD,
00232 &doubleinfo))
00233 fprintf(stream, "%.3f", doubleinfo);
00234 break;
00235 case VAR_SPEED_UPLOAD:
00236 if(CURLE_OK ==
00237 curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &doubleinfo))
00238 fprintf(stream, "%.3f", doubleinfo);
00239 break;
00240 case VAR_CONTENT_TYPE:
00241 if((CURLE_OK ==
00242 curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &stringp))
00243 && stringp)
00244 fputs(stringp, stream);
00245 break;
00246 case VAR_FTP_ENTRY_PATH:
00247 if((CURLE_OK ==
00248 curl_easy_getinfo(curl, CURLINFO_FTP_ENTRY_PATH, &stringp))
00249 && stringp)
00250 fputs(stringp, stream);
00251 break;
00252 case VAR_REDIRECT_URL:
00253 if((CURLE_OK ==
00254 curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &stringp))
00255 && stringp)
00256 fputs(stringp, stream);
00257 break;
00258 case VAR_SSL_VERIFY_RESULT:
00259 if(CURLE_OK ==
00260 curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT,
00261 &longinfo))
00262 fprintf(stream, "%ld", longinfo);
00263 break;
00264 case VAR_PROXY_SSL_VERIFY_RESULT:
00265 if(CURLE_OK ==
00266 curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT,
00267 &longinfo))
00268 fprintf(stream, "%ld", longinfo);
00269 break;
00270 case VAR_EFFECTIVE_FILENAME:
00271 if(outs->filename)
00272 fprintf(stream, "%s", outs->filename);
00273 break;
00274 case VAR_PRIMARY_IP:
00275 if(CURLE_OK ==
00276 curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
00277 &stringp))
00278 fprintf(stream, "%s", stringp);
00279 break;
00280 case VAR_PRIMARY_PORT:
00281 if(CURLE_OK ==
00282 curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT,
00283 &longinfo))
00284 fprintf(stream, "%ld", longinfo);
00285 break;
00286 case VAR_LOCAL_IP:
00287 if(CURLE_OK ==
00288 curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
00289 &stringp))
00290 fprintf(stream, "%s", stringp);
00291 break;
00292 case VAR_LOCAL_PORT:
00293 if(CURLE_OK ==
00294 curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT,
00295 &longinfo))
00296 fprintf(stream, "%ld", longinfo);
00297 break;
00298 case VAR_HTTP_VERSION:
00299 if(CURLE_OK ==
00300 curl_easy_getinfo(curl, CURLINFO_HTTP_VERSION,
00301 &longinfo)) {
00302 const char *version = "0";
00303 switch(longinfo) {
00304 case CURL_HTTP_VERSION_1_0:
00305 version = "1.0";
00306 break;
00307 case CURL_HTTP_VERSION_1_1:
00308 version = "1.1";
00309 break;
00310 case CURL_HTTP_VERSION_2_0:
00311 version = "2";
00312 break;
00313 }
00314
00315 fprintf(stream, version);
00316 }
00317 break;
00318 case VAR_SCHEME:
00319 if(CURLE_OK ==
00320 curl_easy_getinfo(curl, CURLINFO_SCHEME,
00321 &stringp))
00322 fprintf(stream, "%s", stringp);
00323 break;
00324 default:
00325 break;
00326 }
00327 break;
00328 }
00329 }
00330 if(!match) {
00331 fprintf(stderr, "curl: unknown --write-out variable: '%s'\n", ptr);
00332 }
00333 ptr = end + 1;
00334 *end = keepit;
00335 }
00336 else {
00337
00338 fputc('%', stream);
00339 fputc(ptr[1], stream);
00340 ptr += 2;
00341 }
00342 }
00343 }
00344 else if('\\' == *ptr) {
00345 switch(ptr[1]) {
00346 case 'r':
00347 fputc('\r', stream);
00348 break;
00349 case 'n':
00350 fputc('\n', stream);
00351 break;
00352 case 't':
00353 fputc('\t', stream);
00354 break;
00355 default:
00356
00357 fputc(*ptr, stream);
00358 fputc(ptr[1], stream);
00359 break;
00360 }
00361 ptr += 2;
00362 }
00363 else {
00364 fputc(*ptr, stream);
00365 ptr++;
00366 }
00367 }
00368
00369 }