getinfo.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
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" /* Curl_getconnectinfo() */
00032 #include "progress.h"
00033 
00034 /* The last #include files should be: */
00035 #include "curl_memory.h"
00036 #include "memdebug.h"
00037 
00038 /*
00039  * Initialize statistical and informational data.
00040  *
00041  * This function is called in curl_easy_reset, curl_easy_duphandle and at the
00042  * beginning of a perform session. It must reset the session-info variables,
00043  * in particular all variables in struct PureInfo.
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; /* -1 is an illegal time and thus means unknown */
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     /* Return the entrypath string from the most recent connection.
00106        This pointer was copied from the connectdata structure by FTP.
00107        The actual string may be free()ed by subsequent libcurl calls so
00108        it must be copied to a safer area before the next libcurl call.
00109        Callers must never free it themselves. */
00110     *param_charp = data->state.most_recent_ftp_entrypath;
00111     break;
00112   case CURLINFO_REDIRECT_URL:
00113     /* Return the URL this request would have been redirected to if that
00114        option had been enabled! */
00115     *param_charp = data->info.wouldredirect;
00116     break;
00117   case CURLINFO_PRIMARY_IP:
00118     /* Return the ip address of the most recent (primary) connection */
00119     *param_charp = data->info.conn_primary_ip;
00120     break;
00121   case CURLINFO_LOCAL_IP:
00122     /* Return the source/local ip address of the most recent (primary)
00123        connection */
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     /* note: this is not a good conversion for systems with 64 bit sockets and
00193        32 bit longs */
00194     if(sockfd != CURL_SOCKET_BAD)
00195       *param_longp = (long)sockfd;
00196     else
00197       /* this interface is documented to return -1 in case of badness, which
00198          may not be the same as the CURL_SOCKET_BAD value */
00199       *param_longp = -1;
00200     break;
00201   case CURLINFO_PRIMARY_PORT:
00202     /* Return the (remote) port of the most recent (primary) connection */
00203     *param_longp = data->info.conn_primary_port;
00204     break;
00205   case CURLINFO_LOCAL_PORT:
00206     /* Return the local port of the most recent (primary) connection */
00207     *param_longp = data->info.conn_local_port;
00208     break;
00209   case CURLINFO_CONDITION_UNMET:
00210     /* return if the condition prevented the document to get transferred */
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     /* Return the a pointer to the certinfo struct. Not really an slist
00319        pointer but we can pretend it is here */
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             /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
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 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:02