Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #include <curl/curl.h>
00026
00027 #include "urldata.h"
00028 #include "getinfo.h"
00029
00030 #include "vtls/vtls.h"
00031 #include "connect.h"
00032 #include "progress.h"
00033
00034
00035 #include "curl_memory.h"
00036 #include "memdebug.h"
00037
00038
00039
00040
00041
00042
00043
00044
00045 CURLcode Curl_initinfo(struct Curl_easy *data)
00046 {
00047 struct Progress *pro = &data->progress;
00048 struct PureInfo *info = &data->info;
00049
00050 pro->t_nslookup = 0;
00051 pro->t_connect = 0;
00052 pro->t_appconnect = 0;
00053 pro->t_pretransfer = 0;
00054 pro->t_starttransfer = 0;
00055 pro->timespent = 0;
00056 pro->t_redirect = 0;
00057
00058 info->httpcode = 0;
00059 info->httpproxycode = 0;
00060 info->httpversion = 0;
00061 info->filetime = -1;
00062 info->timecond = FALSE;
00063
00064 info->header_size = 0;
00065 info->request_size = 0;
00066 info->proxyauthavail = 0;
00067 info->httpauthavail = 0;
00068 info->numconnects = 0;
00069
00070 free(info->contenttype);
00071 info->contenttype = NULL;
00072
00073 free(info->wouldredirect);
00074 info->wouldredirect = NULL;
00075
00076 info->conn_primary_ip[0] = '\0';
00077 info->conn_local_ip[0] = '\0';
00078 info->conn_primary_port = 0;
00079 info->conn_local_port = 0;
00080
00081 info->conn_scheme = 0;
00082 info->conn_protocol = 0;
00083
00084 #ifdef USE_SSL
00085 Curl_ssl_free_certinfo(data);
00086 #endif
00087
00088 return CURLE_OK;
00089 }
00090
00091 static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
00092 const char **param_charp)
00093 {
00094 switch(info) {
00095 case CURLINFO_EFFECTIVE_URL:
00096 *param_charp = data->change.url?data->change.url:(char *)"";
00097 break;
00098 case CURLINFO_CONTENT_TYPE:
00099 *param_charp = data->info.contenttype;
00100 break;
00101 case CURLINFO_PRIVATE:
00102 *param_charp = (char *) data->set.private_data;
00103 break;
00104 case CURLINFO_FTP_ENTRY_PATH:
00105
00106
00107
00108
00109
00110 *param_charp = data->state.most_recent_ftp_entrypath;
00111 break;
00112 case CURLINFO_REDIRECT_URL:
00113
00114
00115 *param_charp = data->info.wouldredirect;
00116 break;
00117 case CURLINFO_PRIMARY_IP:
00118
00119 *param_charp = data->info.conn_primary_ip;
00120 break;
00121 case CURLINFO_LOCAL_IP:
00122
00123
00124 *param_charp = data->info.conn_local_ip;
00125 break;
00126 case CURLINFO_RTSP_SESSION_ID:
00127 *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
00128 break;
00129 case CURLINFO_SCHEME:
00130 *param_charp = data->info.conn_scheme;
00131 break;
00132
00133 default:
00134 return CURLE_UNKNOWN_OPTION;
00135 }
00136
00137 return CURLE_OK;
00138 }
00139
00140 static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
00141 long *param_longp)
00142 {
00143 curl_socket_t sockfd;
00144
00145 union {
00146 unsigned long *to_ulong;
00147 long *to_long;
00148 } lptr;
00149
00150 switch(info) {
00151 case CURLINFO_RESPONSE_CODE:
00152 *param_longp = data->info.httpcode;
00153 break;
00154 case CURLINFO_HTTP_CONNECTCODE:
00155 *param_longp = data->info.httpproxycode;
00156 break;
00157 case CURLINFO_FILETIME:
00158 *param_longp = data->info.filetime;
00159 break;
00160 case CURLINFO_HEADER_SIZE:
00161 *param_longp = data->info.header_size;
00162 break;
00163 case CURLINFO_REQUEST_SIZE:
00164 *param_longp = data->info.request_size;
00165 break;
00166 case CURLINFO_SSL_VERIFYRESULT:
00167 *param_longp = data->set.ssl.certverifyresult;
00168 break;
00169 case CURLINFO_PROXY_SSL_VERIFYRESULT:
00170 *param_longp = data->set.proxy_ssl.certverifyresult;
00171 break;
00172 case CURLINFO_REDIRECT_COUNT:
00173 *param_longp = data->set.followlocation;
00174 break;
00175 case CURLINFO_HTTPAUTH_AVAIL:
00176 lptr.to_long = param_longp;
00177 *lptr.to_ulong = data->info.httpauthavail;
00178 break;
00179 case CURLINFO_PROXYAUTH_AVAIL:
00180 lptr.to_long = param_longp;
00181 *lptr.to_ulong = data->info.proxyauthavail;
00182 break;
00183 case CURLINFO_OS_ERRNO:
00184 *param_longp = data->state.os_errno;
00185 break;
00186 case CURLINFO_NUM_CONNECTS:
00187 *param_longp = data->info.numconnects;
00188 break;
00189 case CURLINFO_LASTSOCKET:
00190 sockfd = Curl_getconnectinfo(data, NULL);
00191
00192
00193
00194 if(sockfd != CURL_SOCKET_BAD)
00195 *param_longp = (long)sockfd;
00196 else
00197
00198
00199 *param_longp = -1;
00200 break;
00201 case CURLINFO_PRIMARY_PORT:
00202
00203 *param_longp = data->info.conn_primary_port;
00204 break;
00205 case CURLINFO_LOCAL_PORT:
00206
00207 *param_longp = data->info.conn_local_port;
00208 break;
00209 case CURLINFO_CONDITION_UNMET:
00210
00211 *param_longp = data->info.timecond ? 1L : 0L;
00212 break;
00213 case CURLINFO_RTSP_CLIENT_CSEQ:
00214 *param_longp = data->state.rtsp_next_client_CSeq;
00215 break;
00216 case CURLINFO_RTSP_SERVER_CSEQ:
00217 *param_longp = data->state.rtsp_next_server_CSeq;
00218 break;
00219 case CURLINFO_RTSP_CSEQ_RECV:
00220 *param_longp = data->state.rtsp_CSeq_recv;
00221 break;
00222 case CURLINFO_HTTP_VERSION:
00223 switch(data->info.httpversion) {
00224 case 10:
00225 *param_longp = CURL_HTTP_VERSION_1_0;
00226 break;
00227 case 11:
00228 *param_longp = CURL_HTTP_VERSION_1_1;
00229 break;
00230 case 20:
00231 *param_longp = CURL_HTTP_VERSION_2_0;
00232 break;
00233 default:
00234 *param_longp = CURL_HTTP_VERSION_NONE;
00235 break;
00236 }
00237 break;
00238 case CURLINFO_PROTOCOL:
00239 *param_longp = data->info.conn_protocol;
00240 break;
00241
00242 default:
00243 return CURLE_UNKNOWN_OPTION;
00244 }
00245
00246 return CURLE_OK;
00247 }
00248
00249 static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
00250 double *param_doublep)
00251 {
00252 switch(info) {
00253 case CURLINFO_TOTAL_TIME:
00254 *param_doublep = data->progress.timespent;
00255 break;
00256 case CURLINFO_NAMELOOKUP_TIME:
00257 *param_doublep = data->progress.t_nslookup;
00258 break;
00259 case CURLINFO_CONNECT_TIME:
00260 *param_doublep = data->progress.t_connect;
00261 break;
00262 case CURLINFO_APPCONNECT_TIME:
00263 *param_doublep = data->progress.t_appconnect;
00264 break;
00265 case CURLINFO_PRETRANSFER_TIME:
00266 *param_doublep = data->progress.t_pretransfer;
00267 break;
00268 case CURLINFO_STARTTRANSFER_TIME:
00269 *param_doublep = data->progress.t_starttransfer;
00270 break;
00271 case CURLINFO_SIZE_UPLOAD:
00272 *param_doublep = (double)data->progress.uploaded;
00273 break;
00274 case CURLINFO_SIZE_DOWNLOAD:
00275 *param_doublep = (double)data->progress.downloaded;
00276 break;
00277 case CURLINFO_SPEED_DOWNLOAD:
00278 *param_doublep = (double)data->progress.dlspeed;
00279 break;
00280 case CURLINFO_SPEED_UPLOAD:
00281 *param_doublep = (double)data->progress.ulspeed;
00282 break;
00283 case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
00284 *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
00285 (double)data->progress.size_dl:-1;
00286 break;
00287 case CURLINFO_CONTENT_LENGTH_UPLOAD:
00288 *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
00289 (double)data->progress.size_ul:-1;
00290 break;
00291 case CURLINFO_REDIRECT_TIME:
00292 *param_doublep = data->progress.t_redirect;
00293 break;
00294
00295 default:
00296 return CURLE_UNKNOWN_OPTION;
00297 }
00298
00299 return CURLE_OK;
00300 }
00301
00302 static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
00303 struct curl_slist **param_slistp)
00304 {
00305 union {
00306 struct curl_certinfo *to_certinfo;
00307 struct curl_slist *to_slist;
00308 } ptr;
00309
00310 switch(info) {
00311 case CURLINFO_SSL_ENGINES:
00312 *param_slistp = Curl_ssl_engines_list(data);
00313 break;
00314 case CURLINFO_COOKIELIST:
00315 *param_slistp = Curl_cookie_list(data);
00316 break;
00317 case CURLINFO_CERTINFO:
00318
00319
00320 ptr.to_certinfo = &data->info.certs;
00321 *param_slistp = ptr.to_slist;
00322 break;
00323 case CURLINFO_TLS_SESSION:
00324 case CURLINFO_TLS_SSL_PTR:
00325 {
00326 struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
00327 param_slistp;
00328 struct curl_tlssessioninfo *tsi = &data->tsi;
00329 struct connectdata *conn = data->easy_conn;
00330
00331 *tsip = tsi;
00332 tsi->backend = Curl_ssl_backend();
00333 tsi->internals = NULL;
00334
00335 if(conn && tsi->backend != CURLSSLBACKEND_NONE) {
00336 unsigned int i;
00337 for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) {
00338 if(conn->ssl[i].use) {
00339 #if defined(USE_AXTLS)
00340 tsi->internals = (void *)conn->ssl[i].ssl;
00341 #elif defined(USE_CYASSL)
00342 tsi->internals = (void *)conn->ssl[i].handle;
00343 #elif defined(USE_DARWINSSL)
00344 tsi->internals = (void *)conn->ssl[i].ssl_ctx;
00345 #elif defined(USE_GNUTLS)
00346 tsi->internals = (void *)conn->ssl[i].session;
00347 #elif defined(USE_GSKIT)
00348 tsi->internals = (void *)conn->ssl[i].handle;
00349 #elif defined(USE_MBEDTLS)
00350 tsi->internals = (void *)&conn->ssl[i].ssl;
00351 #elif defined(USE_NSS)
00352 tsi->internals = (void *)conn->ssl[i].handle;
00353 #elif defined(USE_OPENSSL)
00354
00355 tsi->internals = ((info == CURLINFO_TLS_SESSION) ?
00356 (void *)conn->ssl[i].ctx :
00357 (void *)conn->ssl[i].handle);
00358 #elif defined(USE_POLARSSL)
00359 tsi->internals = (void *)&conn->ssl[i].ssl;
00360 #elif defined(USE_SCHANNEL)
00361 tsi->internals = (void *)&conn->ssl[i].ctxt->ctxt_handle;
00362 #elif defined(USE_SSL)
00363 #error "SSL backend specific information missing for CURLINFO_TLS_SSL_PTR"
00364 #endif
00365 break;
00366 }
00367 }
00368 }
00369 }
00370 break;
00371 default:
00372 return CURLE_UNKNOWN_OPTION;
00373 }
00374
00375 return CURLE_OK;
00376 }
00377
00378 static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info,
00379 curl_socket_t *param_socketp)
00380 {
00381 switch(info) {
00382 case CURLINFO_ACTIVESOCKET:
00383 *param_socketp = Curl_getconnectinfo(data, NULL);
00384 break;
00385 default:
00386 return CURLE_UNKNOWN_OPTION;
00387 }
00388
00389 return CURLE_OK;
00390 }
00391
00392 CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
00393 {
00394 va_list arg;
00395 long *param_longp = NULL;
00396 double *param_doublep = NULL;
00397 const char **param_charp = NULL;
00398 struct curl_slist **param_slistp = NULL;
00399 curl_socket_t *param_socketp = NULL;
00400 int type;
00401 CURLcode result = CURLE_UNKNOWN_OPTION;
00402
00403 if(!data)
00404 return result;
00405
00406 va_start(arg, info);
00407
00408 type = CURLINFO_TYPEMASK & (int)info;
00409 switch(type) {
00410 case CURLINFO_STRING:
00411 param_charp = va_arg(arg, const char **);
00412 if(param_charp)
00413 result = getinfo_char(data, info, param_charp);
00414 break;
00415 case CURLINFO_LONG:
00416 param_longp = va_arg(arg, long *);
00417 if(param_longp)
00418 result = getinfo_long(data, info, param_longp);
00419 break;
00420 case CURLINFO_DOUBLE:
00421 param_doublep = va_arg(arg, double *);
00422 if(param_doublep)
00423 result = getinfo_double(data, info, param_doublep);
00424 break;
00425 case CURLINFO_SLIST:
00426 param_slistp = va_arg(arg, struct curl_slist **);
00427 if(param_slistp)
00428 result = getinfo_slist(data, info, param_slistp);
00429 break;
00430 case CURLINFO_SOCKET:
00431 param_socketp = va_arg(arg, curl_socket_t *);
00432 if(param_socketp)
00433 result = getinfo_socket(data, info, param_socketp);
00434 break;
00435 default:
00436 break;
00437 }
00438
00439 va_end(arg);
00440
00441 return result;
00442 }