113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#include <curl/curl.h> 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci#include "urldata.h" 3013498266Sopenharmony_ci#include "getinfo.h" 3113498266Sopenharmony_ci 3213498266Sopenharmony_ci#include "vtls/vtls.h" 3313498266Sopenharmony_ci#include "connect.h" /* Curl_getconnectinfo() */ 3413498266Sopenharmony_ci#include "progress.h" 3513498266Sopenharmony_ci 3613498266Sopenharmony_ci/* The last #include files should be: */ 3713498266Sopenharmony_ci#include "curl_memory.h" 3813498266Sopenharmony_ci#include "memdebug.h" 3913498266Sopenharmony_ci 4013498266Sopenharmony_ci/* 4113498266Sopenharmony_ci * Initialize statistical and informational data. 4213498266Sopenharmony_ci * 4313498266Sopenharmony_ci * This function is called in curl_easy_reset, curl_easy_duphandle and at the 4413498266Sopenharmony_ci * beginning of a perform session. It must reset the session-info variables, 4513498266Sopenharmony_ci * in particular all variables in struct PureInfo. 4613498266Sopenharmony_ci */ 4713498266Sopenharmony_ciCURLcode Curl_initinfo(struct Curl_easy *data) 4813498266Sopenharmony_ci{ 4913498266Sopenharmony_ci struct Progress *pro = &data->progress; 5013498266Sopenharmony_ci struct PureInfo *info = &data->info; 5113498266Sopenharmony_ci 5213498266Sopenharmony_ci pro->t_nslookup = 0; 5313498266Sopenharmony_ci pro->t_connect = 0; 5413498266Sopenharmony_ci pro->t_appconnect = 0; 5513498266Sopenharmony_ci pro->t_pretransfer = 0; 5613498266Sopenharmony_ci pro->t_starttransfer = 0; 5713498266Sopenharmony_ci pro->timespent = 0; 5813498266Sopenharmony_ci pro->t_redirect = 0; 5913498266Sopenharmony_ci pro->is_t_startransfer_set = false; 6013498266Sopenharmony_ci 6113498266Sopenharmony_ci info->httpcode = 0; 6213498266Sopenharmony_ci info->httpproxycode = 0; 6313498266Sopenharmony_ci info->httpversion = 0; 6413498266Sopenharmony_ci info->filetime = -1; /* -1 is an illegal time and thus means unknown */ 6513498266Sopenharmony_ci info->timecond = FALSE; 6613498266Sopenharmony_ci 6713498266Sopenharmony_ci info->header_size = 0; 6813498266Sopenharmony_ci info->request_size = 0; 6913498266Sopenharmony_ci info->proxyauthavail = 0; 7013498266Sopenharmony_ci info->httpauthavail = 0; 7113498266Sopenharmony_ci info->numconnects = 0; 7213498266Sopenharmony_ci 7313498266Sopenharmony_ci free(info->contenttype); 7413498266Sopenharmony_ci info->contenttype = NULL; 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci free(info->wouldredirect); 7713498266Sopenharmony_ci info->wouldredirect = NULL; 7813498266Sopenharmony_ci 7913498266Sopenharmony_ci info->conn_primary_ip[0] = '\0'; 8013498266Sopenharmony_ci info->conn_local_ip[0] = '\0'; 8113498266Sopenharmony_ci info->conn_primary_port = 0; 8213498266Sopenharmony_ci info->conn_local_port = 0; 8313498266Sopenharmony_ci info->retry_after = 0; 8413498266Sopenharmony_ci 8513498266Sopenharmony_ci info->conn_scheme = 0; 8613498266Sopenharmony_ci info->conn_protocol = 0; 8713498266Sopenharmony_ci 8813498266Sopenharmony_ci#ifdef USE_SSL 8913498266Sopenharmony_ci Curl_ssl_free_certinfo(data); 9013498266Sopenharmony_ci#endif 9113498266Sopenharmony_ci return CURLE_OK; 9213498266Sopenharmony_ci} 9313498266Sopenharmony_ci 9413498266Sopenharmony_cistatic CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info, 9513498266Sopenharmony_ci const char **param_charp) 9613498266Sopenharmony_ci{ 9713498266Sopenharmony_ci switch(info) { 9813498266Sopenharmony_ci case CURLINFO_EFFECTIVE_URL: 9913498266Sopenharmony_ci *param_charp = data->state.url?data->state.url:(char *)""; 10013498266Sopenharmony_ci break; 10113498266Sopenharmony_ci case CURLINFO_EFFECTIVE_METHOD: { 10213498266Sopenharmony_ci const char *m = data->set.str[STRING_CUSTOMREQUEST]; 10313498266Sopenharmony_ci if(!m) { 10413498266Sopenharmony_ci if(data->set.opt_no_body) 10513498266Sopenharmony_ci m = "HEAD"; 10613498266Sopenharmony_ci#ifndef CURL_DISABLE_HTTP 10713498266Sopenharmony_ci else { 10813498266Sopenharmony_ci switch(data->state.httpreq) { 10913498266Sopenharmony_ci case HTTPREQ_POST: 11013498266Sopenharmony_ci case HTTPREQ_POST_FORM: 11113498266Sopenharmony_ci case HTTPREQ_POST_MIME: 11213498266Sopenharmony_ci m = "POST"; 11313498266Sopenharmony_ci break; 11413498266Sopenharmony_ci case HTTPREQ_PUT: 11513498266Sopenharmony_ci m = "PUT"; 11613498266Sopenharmony_ci break; 11713498266Sopenharmony_ci default: /* this should never happen */ 11813498266Sopenharmony_ci case HTTPREQ_GET: 11913498266Sopenharmony_ci m = "GET"; 12013498266Sopenharmony_ci break; 12113498266Sopenharmony_ci case HTTPREQ_HEAD: 12213498266Sopenharmony_ci m = "HEAD"; 12313498266Sopenharmony_ci break; 12413498266Sopenharmony_ci } 12513498266Sopenharmony_ci } 12613498266Sopenharmony_ci#endif 12713498266Sopenharmony_ci } 12813498266Sopenharmony_ci *param_charp = m; 12913498266Sopenharmony_ci } 13013498266Sopenharmony_ci break; 13113498266Sopenharmony_ci case CURLINFO_CONTENT_TYPE: 13213498266Sopenharmony_ci *param_charp = data->info.contenttype; 13313498266Sopenharmony_ci break; 13413498266Sopenharmony_ci case CURLINFO_PRIVATE: 13513498266Sopenharmony_ci *param_charp = (char *) data->set.private_data; 13613498266Sopenharmony_ci break; 13713498266Sopenharmony_ci case CURLINFO_FTP_ENTRY_PATH: 13813498266Sopenharmony_ci /* Return the entrypath string from the most recent connection. 13913498266Sopenharmony_ci This pointer was copied from the connectdata structure by FTP. 14013498266Sopenharmony_ci The actual string may be free()ed by subsequent libcurl calls so 14113498266Sopenharmony_ci it must be copied to a safer area before the next libcurl call. 14213498266Sopenharmony_ci Callers must never free it themselves. */ 14313498266Sopenharmony_ci *param_charp = data->state.most_recent_ftp_entrypath; 14413498266Sopenharmony_ci break; 14513498266Sopenharmony_ci case CURLINFO_REDIRECT_URL: 14613498266Sopenharmony_ci /* Return the URL this request would have been redirected to if that 14713498266Sopenharmony_ci option had been enabled! */ 14813498266Sopenharmony_ci *param_charp = data->info.wouldredirect; 14913498266Sopenharmony_ci break; 15013498266Sopenharmony_ci case CURLINFO_REFERER: 15113498266Sopenharmony_ci /* Return the referrer header for this request, or NULL if unset */ 15213498266Sopenharmony_ci *param_charp = data->state.referer; 15313498266Sopenharmony_ci break; 15413498266Sopenharmony_ci case CURLINFO_PRIMARY_IP: 15513498266Sopenharmony_ci /* Return the ip address of the most recent (primary) connection */ 15613498266Sopenharmony_ci *param_charp = data->info.conn_primary_ip; 15713498266Sopenharmony_ci break; 15813498266Sopenharmony_ci case CURLINFO_LOCAL_IP: 15913498266Sopenharmony_ci /* Return the source/local ip address of the most recent (primary) 16013498266Sopenharmony_ci connection */ 16113498266Sopenharmony_ci *param_charp = data->info.conn_local_ip; 16213498266Sopenharmony_ci break; 16313498266Sopenharmony_ci case CURLINFO_RTSP_SESSION_ID: 16413498266Sopenharmony_ci *param_charp = data->set.str[STRING_RTSP_SESSION_ID]; 16513498266Sopenharmony_ci break; 16613498266Sopenharmony_ci case CURLINFO_SCHEME: 16713498266Sopenharmony_ci *param_charp = data->info.conn_scheme; 16813498266Sopenharmony_ci break; 16913498266Sopenharmony_ci case CURLINFO_CAPATH: 17013498266Sopenharmony_ci#ifdef CURL_CA_PATH 17113498266Sopenharmony_ci *param_charp = CURL_CA_PATH; 17213498266Sopenharmony_ci#else 17313498266Sopenharmony_ci *param_charp = NULL; 17413498266Sopenharmony_ci#endif 17513498266Sopenharmony_ci break; 17613498266Sopenharmony_ci case CURLINFO_CAINFO: 17713498266Sopenharmony_ci#ifdef CURL_CA_BUNDLE 17813498266Sopenharmony_ci *param_charp = CURL_CA_BUNDLE; 17913498266Sopenharmony_ci#else 18013498266Sopenharmony_ci *param_charp = NULL; 18113498266Sopenharmony_ci#endif 18213498266Sopenharmony_ci break; 18313498266Sopenharmony_ci 18413498266Sopenharmony_ci default: 18513498266Sopenharmony_ci return CURLE_UNKNOWN_OPTION; 18613498266Sopenharmony_ci } 18713498266Sopenharmony_ci 18813498266Sopenharmony_ci return CURLE_OK; 18913498266Sopenharmony_ci} 19013498266Sopenharmony_ci 19113498266Sopenharmony_cistatic CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, 19213498266Sopenharmony_ci long *param_longp) 19313498266Sopenharmony_ci{ 19413498266Sopenharmony_ci curl_socket_t sockfd; 19513498266Sopenharmony_ci 19613498266Sopenharmony_ci union { 19713498266Sopenharmony_ci unsigned long *to_ulong; 19813498266Sopenharmony_ci long *to_long; 19913498266Sopenharmony_ci } lptr; 20013498266Sopenharmony_ci 20113498266Sopenharmony_ci#ifdef DEBUGBUILD 20213498266Sopenharmony_ci char *timestr = getenv("CURL_TIME"); 20313498266Sopenharmony_ci if(timestr) { 20413498266Sopenharmony_ci unsigned long val = strtol(timestr, NULL, 10); 20513498266Sopenharmony_ci switch(info) { 20613498266Sopenharmony_ci case CURLINFO_LOCAL_PORT: 20713498266Sopenharmony_ci *param_longp = (long)val; 20813498266Sopenharmony_ci return CURLE_OK; 20913498266Sopenharmony_ci default: 21013498266Sopenharmony_ci break; 21113498266Sopenharmony_ci } 21213498266Sopenharmony_ci } 21313498266Sopenharmony_ci /* use another variable for this to allow different values */ 21413498266Sopenharmony_ci timestr = getenv("CURL_DEBUG_SIZE"); 21513498266Sopenharmony_ci if(timestr) { 21613498266Sopenharmony_ci unsigned long val = strtol(timestr, NULL, 10); 21713498266Sopenharmony_ci switch(info) { 21813498266Sopenharmony_ci case CURLINFO_HEADER_SIZE: 21913498266Sopenharmony_ci case CURLINFO_REQUEST_SIZE: 22013498266Sopenharmony_ci *param_longp = (long)val; 22113498266Sopenharmony_ci return CURLE_OK; 22213498266Sopenharmony_ci default: 22313498266Sopenharmony_ci break; 22413498266Sopenharmony_ci } 22513498266Sopenharmony_ci } 22613498266Sopenharmony_ci#endif 22713498266Sopenharmony_ci 22813498266Sopenharmony_ci switch(info) { 22913498266Sopenharmony_ci case CURLINFO_RESPONSE_CODE: 23013498266Sopenharmony_ci *param_longp = data->info.httpcode; 23113498266Sopenharmony_ci break; 23213498266Sopenharmony_ci case CURLINFO_HTTP_CONNECTCODE: 23313498266Sopenharmony_ci *param_longp = data->info.httpproxycode; 23413498266Sopenharmony_ci break; 23513498266Sopenharmony_ci case CURLINFO_FILETIME: 23613498266Sopenharmony_ci if(data->info.filetime > LONG_MAX) 23713498266Sopenharmony_ci *param_longp = LONG_MAX; 23813498266Sopenharmony_ci else if(data->info.filetime < LONG_MIN) 23913498266Sopenharmony_ci *param_longp = LONG_MIN; 24013498266Sopenharmony_ci else 24113498266Sopenharmony_ci *param_longp = (long)data->info.filetime; 24213498266Sopenharmony_ci break; 24313498266Sopenharmony_ci case CURLINFO_HEADER_SIZE: 24413498266Sopenharmony_ci *param_longp = (long)data->info.header_size; 24513498266Sopenharmony_ci break; 24613498266Sopenharmony_ci case CURLINFO_REQUEST_SIZE: 24713498266Sopenharmony_ci *param_longp = (long)data->info.request_size; 24813498266Sopenharmony_ci break; 24913498266Sopenharmony_ci case CURLINFO_SSL_VERIFYRESULT: 25013498266Sopenharmony_ci *param_longp = data->set.ssl.certverifyresult; 25113498266Sopenharmony_ci break; 25213498266Sopenharmony_ci#ifndef CURL_DISABLE_PROXY 25313498266Sopenharmony_ci case CURLINFO_PROXY_SSL_VERIFYRESULT: 25413498266Sopenharmony_ci *param_longp = data->set.proxy_ssl.certverifyresult; 25513498266Sopenharmony_ci break; 25613498266Sopenharmony_ci#endif 25713498266Sopenharmony_ci case CURLINFO_REDIRECT_COUNT: 25813498266Sopenharmony_ci *param_longp = data->state.followlocation; 25913498266Sopenharmony_ci break; 26013498266Sopenharmony_ci case CURLINFO_HTTPAUTH_AVAIL: 26113498266Sopenharmony_ci lptr.to_long = param_longp; 26213498266Sopenharmony_ci *lptr.to_ulong = data->info.httpauthavail; 26313498266Sopenharmony_ci break; 26413498266Sopenharmony_ci case CURLINFO_PROXYAUTH_AVAIL: 26513498266Sopenharmony_ci lptr.to_long = param_longp; 26613498266Sopenharmony_ci *lptr.to_ulong = data->info.proxyauthavail; 26713498266Sopenharmony_ci break; 26813498266Sopenharmony_ci case CURLINFO_OS_ERRNO: 26913498266Sopenharmony_ci *param_longp = data->state.os_errno; 27013498266Sopenharmony_ci break; 27113498266Sopenharmony_ci case CURLINFO_NUM_CONNECTS: 27213498266Sopenharmony_ci *param_longp = data->info.numconnects; 27313498266Sopenharmony_ci break; 27413498266Sopenharmony_ci case CURLINFO_LASTSOCKET: 27513498266Sopenharmony_ci sockfd = Curl_getconnectinfo(data, NULL); 27613498266Sopenharmony_ci 27713498266Sopenharmony_ci /* note: this is not a good conversion for systems with 64 bit sockets and 27813498266Sopenharmony_ci 32 bit longs */ 27913498266Sopenharmony_ci if(sockfd != CURL_SOCKET_BAD) 28013498266Sopenharmony_ci *param_longp = (long)sockfd; 28113498266Sopenharmony_ci else 28213498266Sopenharmony_ci /* this interface is documented to return -1 in case of badness, which 28313498266Sopenharmony_ci may not be the same as the CURL_SOCKET_BAD value */ 28413498266Sopenharmony_ci *param_longp = -1; 28513498266Sopenharmony_ci break; 28613498266Sopenharmony_ci case CURLINFO_PRIMARY_PORT: 28713498266Sopenharmony_ci /* Return the (remote) port of the most recent (primary) connection */ 28813498266Sopenharmony_ci *param_longp = data->info.conn_primary_port; 28913498266Sopenharmony_ci break; 29013498266Sopenharmony_ci case CURLINFO_LOCAL_PORT: 29113498266Sopenharmony_ci /* Return the local port of the most recent (primary) connection */ 29213498266Sopenharmony_ci *param_longp = data->info.conn_local_port; 29313498266Sopenharmony_ci break; 29413498266Sopenharmony_ci case CURLINFO_PROXY_ERROR: 29513498266Sopenharmony_ci *param_longp = (long)data->info.pxcode; 29613498266Sopenharmony_ci break; 29713498266Sopenharmony_ci case CURLINFO_CONDITION_UNMET: 29813498266Sopenharmony_ci if(data->info.httpcode == 304) 29913498266Sopenharmony_ci *param_longp = 1L; 30013498266Sopenharmony_ci else 30113498266Sopenharmony_ci /* return if the condition prevented the document to get transferred */ 30213498266Sopenharmony_ci *param_longp = data->info.timecond ? 1L : 0L; 30313498266Sopenharmony_ci break; 30413498266Sopenharmony_ci#ifndef CURL_DISABLE_RTSP 30513498266Sopenharmony_ci case CURLINFO_RTSP_CLIENT_CSEQ: 30613498266Sopenharmony_ci *param_longp = data->state.rtsp_next_client_CSeq; 30713498266Sopenharmony_ci break; 30813498266Sopenharmony_ci case CURLINFO_RTSP_SERVER_CSEQ: 30913498266Sopenharmony_ci *param_longp = data->state.rtsp_next_server_CSeq; 31013498266Sopenharmony_ci break; 31113498266Sopenharmony_ci case CURLINFO_RTSP_CSEQ_RECV: 31213498266Sopenharmony_ci *param_longp = data->state.rtsp_CSeq_recv; 31313498266Sopenharmony_ci break; 31413498266Sopenharmony_ci#endif 31513498266Sopenharmony_ci case CURLINFO_HTTP_VERSION: 31613498266Sopenharmony_ci switch(data->info.httpversion) { 31713498266Sopenharmony_ci case 10: 31813498266Sopenharmony_ci *param_longp = CURL_HTTP_VERSION_1_0; 31913498266Sopenharmony_ci break; 32013498266Sopenharmony_ci case 11: 32113498266Sopenharmony_ci *param_longp = CURL_HTTP_VERSION_1_1; 32213498266Sopenharmony_ci break; 32313498266Sopenharmony_ci case 20: 32413498266Sopenharmony_ci *param_longp = CURL_HTTP_VERSION_2_0; 32513498266Sopenharmony_ci break; 32613498266Sopenharmony_ci case 30: 32713498266Sopenharmony_ci *param_longp = CURL_HTTP_VERSION_3; 32813498266Sopenharmony_ci break; 32913498266Sopenharmony_ci default: 33013498266Sopenharmony_ci *param_longp = CURL_HTTP_VERSION_NONE; 33113498266Sopenharmony_ci break; 33213498266Sopenharmony_ci } 33313498266Sopenharmony_ci break; 33413498266Sopenharmony_ci case CURLINFO_PROTOCOL: 33513498266Sopenharmony_ci *param_longp = data->info.conn_protocol; 33613498266Sopenharmony_ci break; 33713498266Sopenharmony_ci default: 33813498266Sopenharmony_ci return CURLE_UNKNOWN_OPTION; 33913498266Sopenharmony_ci } 34013498266Sopenharmony_ci 34113498266Sopenharmony_ci return CURLE_OK; 34213498266Sopenharmony_ci} 34313498266Sopenharmony_ci 34413498266Sopenharmony_ci#define DOUBLE_SECS(x) (double)(x)/1000000 34513498266Sopenharmony_ci 34613498266Sopenharmony_cistatic CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, 34713498266Sopenharmony_ci curl_off_t *param_offt) 34813498266Sopenharmony_ci{ 34913498266Sopenharmony_ci#ifdef DEBUGBUILD 35013498266Sopenharmony_ci char *timestr = getenv("CURL_TIME"); 35113498266Sopenharmony_ci if(timestr) { 35213498266Sopenharmony_ci unsigned long val = strtol(timestr, NULL, 10); 35313498266Sopenharmony_ci switch(info) { 35413498266Sopenharmony_ci case CURLINFO_TOTAL_TIME_T: 35513498266Sopenharmony_ci case CURLINFO_NAMELOOKUP_TIME_T: 35613498266Sopenharmony_ci case CURLINFO_CONNECT_TIME_T: 35713498266Sopenharmony_ci case CURLINFO_APPCONNECT_TIME_T: 35813498266Sopenharmony_ci case CURLINFO_PRETRANSFER_TIME_T: 35913498266Sopenharmony_ci case CURLINFO_STARTTRANSFER_TIME_T: 36013498266Sopenharmony_ci case CURLINFO_REDIRECT_TIME_T: 36113498266Sopenharmony_ci case CURLINFO_SPEED_DOWNLOAD_T: 36213498266Sopenharmony_ci case CURLINFO_SPEED_UPLOAD_T: 36313498266Sopenharmony_ci *param_offt = (curl_off_t)val; 36413498266Sopenharmony_ci return CURLE_OK; 36513498266Sopenharmony_ci default: 36613498266Sopenharmony_ci break; 36713498266Sopenharmony_ci } 36813498266Sopenharmony_ci } 36913498266Sopenharmony_ci#endif 37013498266Sopenharmony_ci switch(info) { 37113498266Sopenharmony_ci case CURLINFO_FILETIME_T: 37213498266Sopenharmony_ci *param_offt = (curl_off_t)data->info.filetime; 37313498266Sopenharmony_ci break; 37413498266Sopenharmony_ci case CURLINFO_SIZE_UPLOAD_T: 37513498266Sopenharmony_ci *param_offt = data->progress.uploaded; 37613498266Sopenharmony_ci break; 37713498266Sopenharmony_ci case CURLINFO_SIZE_DOWNLOAD_T: 37813498266Sopenharmony_ci *param_offt = data->progress.downloaded; 37913498266Sopenharmony_ci break; 38013498266Sopenharmony_ci case CURLINFO_SPEED_DOWNLOAD_T: 38113498266Sopenharmony_ci *param_offt = data->progress.dlspeed; 38213498266Sopenharmony_ci break; 38313498266Sopenharmony_ci case CURLINFO_SPEED_UPLOAD_T: 38413498266Sopenharmony_ci *param_offt = data->progress.ulspeed; 38513498266Sopenharmony_ci break; 38613498266Sopenharmony_ci case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T: 38713498266Sopenharmony_ci *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? 38813498266Sopenharmony_ci data->progress.size_dl:-1; 38913498266Sopenharmony_ci break; 39013498266Sopenharmony_ci case CURLINFO_CONTENT_LENGTH_UPLOAD_T: 39113498266Sopenharmony_ci *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? 39213498266Sopenharmony_ci data->progress.size_ul:-1; 39313498266Sopenharmony_ci break; 39413498266Sopenharmony_ci case CURLINFO_TOTAL_TIME_T: 39513498266Sopenharmony_ci *param_offt = data->progress.timespent; 39613498266Sopenharmony_ci break; 39713498266Sopenharmony_ci case CURLINFO_NAMELOOKUP_TIME_T: 39813498266Sopenharmony_ci *param_offt = data->progress.t_nslookup; 39913498266Sopenharmony_ci break; 40013498266Sopenharmony_ci case CURLINFO_CONNECT_TIME_T: 40113498266Sopenharmony_ci *param_offt = data->progress.t_connect; 40213498266Sopenharmony_ci break; 40313498266Sopenharmony_ci case CURLINFO_APPCONNECT_TIME_T: 40413498266Sopenharmony_ci *param_offt = data->progress.t_appconnect; 40513498266Sopenharmony_ci break; 40613498266Sopenharmony_ci case CURLINFO_PRETRANSFER_TIME_T: 40713498266Sopenharmony_ci *param_offt = data->progress.t_pretransfer; 40813498266Sopenharmony_ci break; 40913498266Sopenharmony_ci case CURLINFO_STARTTRANSFER_TIME_T: 41013498266Sopenharmony_ci *param_offt = data->progress.t_starttransfer; 41113498266Sopenharmony_ci break; 41213498266Sopenharmony_ci case CURLINFO_QUEUE_TIME_T: 41313498266Sopenharmony_ci *param_offt = data->progress.t_postqueue; 41413498266Sopenharmony_ci break; 41513498266Sopenharmony_ci case CURLINFO_REDIRECT_TIME_T: 41613498266Sopenharmony_ci *param_offt = data->progress.t_redirect; 41713498266Sopenharmony_ci break; 41813498266Sopenharmony_ci case CURLINFO_RETRY_AFTER: 41913498266Sopenharmony_ci *param_offt = data->info.retry_after; 42013498266Sopenharmony_ci break; 42113498266Sopenharmony_ci case CURLINFO_XFER_ID: 42213498266Sopenharmony_ci *param_offt = data->id; 42313498266Sopenharmony_ci break; 42413498266Sopenharmony_ci case CURLINFO_CONN_ID: 42513498266Sopenharmony_ci *param_offt = data->conn? 42613498266Sopenharmony_ci data->conn->connection_id : data->state.recent_conn_id; 42713498266Sopenharmony_ci break; 42813498266Sopenharmony_ci default: 42913498266Sopenharmony_ci return CURLE_UNKNOWN_OPTION; 43013498266Sopenharmony_ci } 43113498266Sopenharmony_ci 43213498266Sopenharmony_ci return CURLE_OK; 43313498266Sopenharmony_ci} 43413498266Sopenharmony_ci 43513498266Sopenharmony_cistatic CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info, 43613498266Sopenharmony_ci double *param_doublep) 43713498266Sopenharmony_ci{ 43813498266Sopenharmony_ci#ifdef DEBUGBUILD 43913498266Sopenharmony_ci char *timestr = getenv("CURL_TIME"); 44013498266Sopenharmony_ci if(timestr) { 44113498266Sopenharmony_ci unsigned long val = strtol(timestr, NULL, 10); 44213498266Sopenharmony_ci switch(info) { 44313498266Sopenharmony_ci case CURLINFO_TOTAL_TIME: 44413498266Sopenharmony_ci case CURLINFO_NAMELOOKUP_TIME: 44513498266Sopenharmony_ci case CURLINFO_CONNECT_TIME: 44613498266Sopenharmony_ci case CURLINFO_APPCONNECT_TIME: 44713498266Sopenharmony_ci case CURLINFO_PRETRANSFER_TIME: 44813498266Sopenharmony_ci case CURLINFO_STARTTRANSFER_TIME: 44913498266Sopenharmony_ci case CURLINFO_REDIRECT_TIME: 45013498266Sopenharmony_ci case CURLINFO_SPEED_DOWNLOAD: 45113498266Sopenharmony_ci case CURLINFO_SPEED_UPLOAD: 45213498266Sopenharmony_ci *param_doublep = (double)val; 45313498266Sopenharmony_ci return CURLE_OK; 45413498266Sopenharmony_ci default: 45513498266Sopenharmony_ci break; 45613498266Sopenharmony_ci } 45713498266Sopenharmony_ci } 45813498266Sopenharmony_ci#endif 45913498266Sopenharmony_ci switch(info) { 46013498266Sopenharmony_ci case CURLINFO_TOTAL_TIME: 46113498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.timespent); 46213498266Sopenharmony_ci break; 46313498266Sopenharmony_ci case CURLINFO_NAMELOOKUP_TIME: 46413498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.t_nslookup); 46513498266Sopenharmony_ci break; 46613498266Sopenharmony_ci case CURLINFO_CONNECT_TIME: 46713498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.t_connect); 46813498266Sopenharmony_ci break; 46913498266Sopenharmony_ci case CURLINFO_APPCONNECT_TIME: 47013498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.t_appconnect); 47113498266Sopenharmony_ci break; 47213498266Sopenharmony_ci case CURLINFO_PRETRANSFER_TIME: 47313498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer); 47413498266Sopenharmony_ci break; 47513498266Sopenharmony_ci case CURLINFO_STARTTRANSFER_TIME: 47613498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer); 47713498266Sopenharmony_ci break; 47813498266Sopenharmony_ci case CURLINFO_SIZE_UPLOAD: 47913498266Sopenharmony_ci *param_doublep = (double)data->progress.uploaded; 48013498266Sopenharmony_ci break; 48113498266Sopenharmony_ci case CURLINFO_SIZE_DOWNLOAD: 48213498266Sopenharmony_ci *param_doublep = (double)data->progress.downloaded; 48313498266Sopenharmony_ci break; 48413498266Sopenharmony_ci case CURLINFO_SPEED_DOWNLOAD: 48513498266Sopenharmony_ci *param_doublep = (double)data->progress.dlspeed; 48613498266Sopenharmony_ci break; 48713498266Sopenharmony_ci case CURLINFO_SPEED_UPLOAD: 48813498266Sopenharmony_ci *param_doublep = (double)data->progress.ulspeed; 48913498266Sopenharmony_ci break; 49013498266Sopenharmony_ci case CURLINFO_CONTENT_LENGTH_DOWNLOAD: 49113498266Sopenharmony_ci *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? 49213498266Sopenharmony_ci (double)data->progress.size_dl:-1; 49313498266Sopenharmony_ci break; 49413498266Sopenharmony_ci case CURLINFO_CONTENT_LENGTH_UPLOAD: 49513498266Sopenharmony_ci *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? 49613498266Sopenharmony_ci (double)data->progress.size_ul:-1; 49713498266Sopenharmony_ci break; 49813498266Sopenharmony_ci case CURLINFO_REDIRECT_TIME: 49913498266Sopenharmony_ci *param_doublep = DOUBLE_SECS(data->progress.t_redirect); 50013498266Sopenharmony_ci break; 50113498266Sopenharmony_ci 50213498266Sopenharmony_ci default: 50313498266Sopenharmony_ci return CURLE_UNKNOWN_OPTION; 50413498266Sopenharmony_ci } 50513498266Sopenharmony_ci 50613498266Sopenharmony_ci return CURLE_OK; 50713498266Sopenharmony_ci} 50813498266Sopenharmony_ci 50913498266Sopenharmony_cistatic CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info, 51013498266Sopenharmony_ci struct curl_slist **param_slistp) 51113498266Sopenharmony_ci{ 51213498266Sopenharmony_ci union { 51313498266Sopenharmony_ci struct curl_certinfo *to_certinfo; 51413498266Sopenharmony_ci struct curl_slist *to_slist; 51513498266Sopenharmony_ci } ptr; 51613498266Sopenharmony_ci 51713498266Sopenharmony_ci switch(info) { 51813498266Sopenharmony_ci case CURLINFO_SSL_ENGINES: 51913498266Sopenharmony_ci *param_slistp = Curl_ssl_engines_list(data); 52013498266Sopenharmony_ci break; 52113498266Sopenharmony_ci case CURLINFO_COOKIELIST: 52213498266Sopenharmony_ci *param_slistp = Curl_cookie_list(data); 52313498266Sopenharmony_ci break; 52413498266Sopenharmony_ci case CURLINFO_CERTINFO: 52513498266Sopenharmony_ci /* Return the a pointer to the certinfo struct. Not really an slist 52613498266Sopenharmony_ci pointer but we can pretend it is here */ 52713498266Sopenharmony_ci ptr.to_certinfo = &data->info.certs; 52813498266Sopenharmony_ci *param_slistp = ptr.to_slist; 52913498266Sopenharmony_ci break; 53013498266Sopenharmony_ci case CURLINFO_TLS_SESSION: 53113498266Sopenharmony_ci case CURLINFO_TLS_SSL_PTR: 53213498266Sopenharmony_ci { 53313498266Sopenharmony_ci struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **) 53413498266Sopenharmony_ci param_slistp; 53513498266Sopenharmony_ci struct curl_tlssessioninfo *tsi = &data->tsi; 53613498266Sopenharmony_ci#ifdef USE_SSL 53713498266Sopenharmony_ci struct connectdata *conn = data->conn; 53813498266Sopenharmony_ci#endif 53913498266Sopenharmony_ci 54013498266Sopenharmony_ci *tsip = tsi; 54113498266Sopenharmony_ci tsi->backend = Curl_ssl_backend(); 54213498266Sopenharmony_ci tsi->internals = NULL; 54313498266Sopenharmony_ci 54413498266Sopenharmony_ci#ifdef USE_SSL 54513498266Sopenharmony_ci if(conn && tsi->backend != CURLSSLBACKEND_NONE) { 54613498266Sopenharmony_ci tsi->internals = Curl_ssl_get_internals(data, FIRSTSOCKET, info, 0); 54713498266Sopenharmony_ci } 54813498266Sopenharmony_ci#endif 54913498266Sopenharmony_ci } 55013498266Sopenharmony_ci break; 55113498266Sopenharmony_ci default: 55213498266Sopenharmony_ci return CURLE_UNKNOWN_OPTION; 55313498266Sopenharmony_ci } 55413498266Sopenharmony_ci 55513498266Sopenharmony_ci return CURLE_OK; 55613498266Sopenharmony_ci} 55713498266Sopenharmony_ci 55813498266Sopenharmony_cistatic CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info, 55913498266Sopenharmony_ci curl_socket_t *param_socketp) 56013498266Sopenharmony_ci{ 56113498266Sopenharmony_ci switch(info) { 56213498266Sopenharmony_ci case CURLINFO_ACTIVESOCKET: 56313498266Sopenharmony_ci *param_socketp = Curl_getconnectinfo(data, NULL); 56413498266Sopenharmony_ci break; 56513498266Sopenharmony_ci default: 56613498266Sopenharmony_ci return CURLE_UNKNOWN_OPTION; 56713498266Sopenharmony_ci } 56813498266Sopenharmony_ci 56913498266Sopenharmony_ci return CURLE_OK; 57013498266Sopenharmony_ci} 57113498266Sopenharmony_ci 57213498266Sopenharmony_ciCURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...) 57313498266Sopenharmony_ci{ 57413498266Sopenharmony_ci va_list arg; 57513498266Sopenharmony_ci long *param_longp = NULL; 57613498266Sopenharmony_ci double *param_doublep = NULL; 57713498266Sopenharmony_ci curl_off_t *param_offt = NULL; 57813498266Sopenharmony_ci const char **param_charp = NULL; 57913498266Sopenharmony_ci struct curl_slist **param_slistp = NULL; 58013498266Sopenharmony_ci curl_socket_t *param_socketp = NULL; 58113498266Sopenharmony_ci int type; 58213498266Sopenharmony_ci CURLcode result = CURLE_UNKNOWN_OPTION; 58313498266Sopenharmony_ci 58413498266Sopenharmony_ci if(!data) 58513498266Sopenharmony_ci return CURLE_BAD_FUNCTION_ARGUMENT; 58613498266Sopenharmony_ci 58713498266Sopenharmony_ci va_start(arg, info); 58813498266Sopenharmony_ci 58913498266Sopenharmony_ci type = CURLINFO_TYPEMASK & (int)info; 59013498266Sopenharmony_ci switch(type) { 59113498266Sopenharmony_ci case CURLINFO_STRING: 59213498266Sopenharmony_ci param_charp = va_arg(arg, const char **); 59313498266Sopenharmony_ci if(param_charp) 59413498266Sopenharmony_ci result = getinfo_char(data, info, param_charp); 59513498266Sopenharmony_ci break; 59613498266Sopenharmony_ci case CURLINFO_LONG: 59713498266Sopenharmony_ci param_longp = va_arg(arg, long *); 59813498266Sopenharmony_ci if(param_longp) 59913498266Sopenharmony_ci result = getinfo_long(data, info, param_longp); 60013498266Sopenharmony_ci break; 60113498266Sopenharmony_ci case CURLINFO_DOUBLE: 60213498266Sopenharmony_ci param_doublep = va_arg(arg, double *); 60313498266Sopenharmony_ci if(param_doublep) 60413498266Sopenharmony_ci result = getinfo_double(data, info, param_doublep); 60513498266Sopenharmony_ci break; 60613498266Sopenharmony_ci case CURLINFO_OFF_T: 60713498266Sopenharmony_ci param_offt = va_arg(arg, curl_off_t *); 60813498266Sopenharmony_ci if(param_offt) 60913498266Sopenharmony_ci result = getinfo_offt(data, info, param_offt); 61013498266Sopenharmony_ci break; 61113498266Sopenharmony_ci case CURLINFO_SLIST: 61213498266Sopenharmony_ci param_slistp = va_arg(arg, struct curl_slist **); 61313498266Sopenharmony_ci if(param_slistp) 61413498266Sopenharmony_ci result = getinfo_slist(data, info, param_slistp); 61513498266Sopenharmony_ci break; 61613498266Sopenharmony_ci case CURLINFO_SOCKET: 61713498266Sopenharmony_ci param_socketp = va_arg(arg, curl_socket_t *); 61813498266Sopenharmony_ci if(param_socketp) 61913498266Sopenharmony_ci result = getinfo_socket(data, info, param_socketp); 62013498266Sopenharmony_ci break; 62113498266Sopenharmony_ci default: 62213498266Sopenharmony_ci break; 62313498266Sopenharmony_ci } 62413498266Sopenharmony_ci 62513498266Sopenharmony_ci va_end(arg); 62613498266Sopenharmony_ci 62713498266Sopenharmony_ci return result; 62813498266Sopenharmony_ci} 629