VirtualBox

source: vbox/trunk/src/libs/curl-7.64.0/lib/getinfo.c@ 86643

Last change on this file since 86643 was 85671, checked in by vboxsync, 4 years ago

Export out internal curl copy to make it a lot simpler to build VBox (OSE) on Windows. bugref:9814

  • Property svn:eol-style set to native
File size: 13.7 KB
Line 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2019, Daniel Stenberg, <[email protected]>, 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
23#include "curl_setup.h"
24
25#include <curl/curl.h>
26
27#include "urldata.h"
28#include "getinfo.h"
29
30#include "vtls/vtls.h"
31#include "connect.h" /* Curl_getconnectinfo() */
32#include "progress.h"
33
34/* The last #include files should be: */
35#include "curl_memory.h"
36#include "memdebug.h"
37
38/*
39 * Initialize statistical and informational data.
40 *
41 * This function is called in curl_easy_reset, curl_easy_duphandle and at the
42 * beginning of a perform session. It must reset the session-info variables,
43 * in particular all variables in struct PureInfo.
44 */
45CURLcode Curl_initinfo(struct Curl_easy *data)
46{
47 struct Progress *pro = &data->progress;
48 struct PureInfo *info = &data->info;
49
50 pro->t_nslookup = 0;
51 pro->t_connect = 0;
52 pro->t_appconnect = 0;
53 pro->t_pretransfer = 0;
54 pro->t_starttransfer = 0;
55 pro->timespent = 0;
56 pro->t_redirect = 0;
57 pro->is_t_startransfer_set = false;
58
59 info->httpcode = 0;
60 info->httpproxycode = 0;
61 info->httpversion = 0;
62 info->filetime = -1; /* -1 is an illegal time and thus means unknown */
63 info->timecond = FALSE;
64
65 info->header_size = 0;
66 info->request_size = 0;
67 info->proxyauthavail = 0;
68 info->httpauthavail = 0;
69 info->numconnects = 0;
70
71 free(info->contenttype);
72 info->contenttype = NULL;
73
74 free(info->wouldredirect);
75 info->wouldredirect = NULL;
76
77 info->conn_primary_ip[0] = '\0';
78 info->conn_local_ip[0] = '\0';
79 info->conn_primary_port = 0;
80 info->conn_local_port = 0;
81
82 info->conn_scheme = 0;
83 info->conn_protocol = 0;
84
85#ifdef USE_SSL
86 Curl_ssl_free_certinfo(data);
87#endif
88 return CURLE_OK;
89}
90
91static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
92 const char **param_charp)
93{
94 switch(info) {
95 case CURLINFO_EFFECTIVE_URL:
96 *param_charp = data->change.url?data->change.url:(char *)"";
97 break;
98 case CURLINFO_CONTENT_TYPE:
99 *param_charp = data->info.contenttype;
100 break;
101 case CURLINFO_PRIVATE:
102 *param_charp = (char *) data->set.private_data;
103 break;
104 case CURLINFO_FTP_ENTRY_PATH:
105 /* Return the entrypath string from the most recent connection.
106 This pointer was copied from the connectdata structure by FTP.
107 The actual string may be free()ed by subsequent libcurl calls so
108 it must be copied to a safer area before the next libcurl call.
109 Callers must never free it themselves. */
110 *param_charp = data->state.most_recent_ftp_entrypath;
111 break;
112 case CURLINFO_REDIRECT_URL:
113 /* Return the URL this request would have been redirected to if that
114 option had been enabled! */
115 *param_charp = data->info.wouldredirect;
116 break;
117 case CURLINFO_PRIMARY_IP:
118 /* Return the ip address of the most recent (primary) connection */
119 *param_charp = data->info.conn_primary_ip;
120 break;
121 case CURLINFO_LOCAL_IP:
122 /* Return the source/local ip address of the most recent (primary)
123 connection */
124 *param_charp = data->info.conn_local_ip;
125 break;
126 case CURLINFO_RTSP_SESSION_ID:
127 *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
128 break;
129 case CURLINFO_SCHEME:
130 *param_charp = data->info.conn_scheme;
131 break;
132
133 default:
134 return CURLE_UNKNOWN_OPTION;
135 }
136
137 return CURLE_OK;
138}
139
140static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
141 long *param_longp)
142{
143 curl_socket_t sockfd;
144
145 union {
146 unsigned long *to_ulong;
147 long *to_long;
148 } lptr;
149
150 switch(info) {
151 case CURLINFO_RESPONSE_CODE:
152 *param_longp = data->info.httpcode;
153 break;
154 case CURLINFO_HTTP_CONNECTCODE:
155 *param_longp = data->info.httpproxycode;
156 break;
157 case CURLINFO_FILETIME:
158 if(data->info.filetime > LONG_MAX)
159 *param_longp = LONG_MAX;
160 else if(data->info.filetime < LONG_MIN)
161 *param_longp = LONG_MIN;
162 else
163 *param_longp = (long)data->info.filetime;
164 break;
165 case CURLINFO_HEADER_SIZE:
166 *param_longp = data->info.header_size;
167 break;
168 case CURLINFO_REQUEST_SIZE:
169 *param_longp = data->info.request_size;
170 break;
171 case CURLINFO_SSL_VERIFYRESULT:
172 *param_longp = data->set.ssl.certverifyresult;
173 break;
174 case CURLINFO_PROXY_SSL_VERIFYRESULT:
175 *param_longp = data->set.proxy_ssl.certverifyresult;
176 break;
177 case CURLINFO_REDIRECT_COUNT:
178 *param_longp = data->set.followlocation;
179 break;
180 case CURLINFO_HTTPAUTH_AVAIL:
181 lptr.to_long = param_longp;
182 *lptr.to_ulong = data->info.httpauthavail;
183 break;
184 case CURLINFO_PROXYAUTH_AVAIL:
185 lptr.to_long = param_longp;
186 *lptr.to_ulong = data->info.proxyauthavail;
187 break;
188 case CURLINFO_OS_ERRNO:
189 *param_longp = data->state.os_errno;
190 break;
191 case CURLINFO_NUM_CONNECTS:
192 *param_longp = data->info.numconnects;
193 break;
194 case CURLINFO_LASTSOCKET:
195 sockfd = Curl_getconnectinfo(data, NULL);
196
197 /* note: this is not a good conversion for systems with 64 bit sockets and
198 32 bit longs */
199 if(sockfd != CURL_SOCKET_BAD)
200 *param_longp = (long)sockfd;
201 else
202 /* this interface is documented to return -1 in case of badness, which
203 may not be the same as the CURL_SOCKET_BAD value */
204 *param_longp = -1;
205 break;
206 case CURLINFO_PRIMARY_PORT:
207 /* Return the (remote) port of the most recent (primary) connection */
208 *param_longp = data->info.conn_primary_port;
209 break;
210 case CURLINFO_LOCAL_PORT:
211 /* Return the local port of the most recent (primary) connection */
212 *param_longp = data->info.conn_local_port;
213 break;
214 case CURLINFO_CONDITION_UNMET:
215 /* return if the condition prevented the document to get transferred */
216 *param_longp = data->info.timecond ? 1L : 0L;
217 break;
218 case CURLINFO_RTSP_CLIENT_CSEQ:
219 *param_longp = data->state.rtsp_next_client_CSeq;
220 break;
221 case CURLINFO_RTSP_SERVER_CSEQ:
222 *param_longp = data->state.rtsp_next_server_CSeq;
223 break;
224 case CURLINFO_RTSP_CSEQ_RECV:
225 *param_longp = data->state.rtsp_CSeq_recv;
226 break;
227 case CURLINFO_HTTP_VERSION:
228 switch(data->info.httpversion) {
229 case 10:
230 *param_longp = CURL_HTTP_VERSION_1_0;
231 break;
232 case 11:
233 *param_longp = CURL_HTTP_VERSION_1_1;
234 break;
235 case 20:
236 *param_longp = CURL_HTTP_VERSION_2_0;
237 break;
238 default:
239 *param_longp = CURL_HTTP_VERSION_NONE;
240 break;
241 }
242 break;
243 case CURLINFO_PROTOCOL:
244 *param_longp = data->info.conn_protocol;
245 break;
246
247 default:
248 return CURLE_UNKNOWN_OPTION;
249 }
250
251 return CURLE_OK;
252}
253
254#define DOUBLE_SECS(x) (double)(x)/1000000
255
256static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
257 curl_off_t *param_offt)
258{
259 switch(info) {
260 case CURLINFO_FILETIME_T:
261 *param_offt = (curl_off_t)data->info.filetime;
262 break;
263 case CURLINFO_SIZE_UPLOAD_T:
264 *param_offt = data->progress.uploaded;
265 break;
266 case CURLINFO_SIZE_DOWNLOAD_T:
267 *param_offt = data->progress.downloaded;
268 break;
269 case CURLINFO_SPEED_DOWNLOAD_T:
270 *param_offt = data->progress.dlspeed;
271 break;
272 case CURLINFO_SPEED_UPLOAD_T:
273 *param_offt = data->progress.ulspeed;
274 break;
275 case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T:
276 *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
277 data->progress.size_dl:-1;
278 break;
279 case CURLINFO_CONTENT_LENGTH_UPLOAD_T:
280 *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
281 data->progress.size_ul:-1;
282 break;
283 case CURLINFO_TOTAL_TIME_T:
284 *param_offt = data->progress.timespent;
285 break;
286 case CURLINFO_NAMELOOKUP_TIME_T:
287 *param_offt = data->progress.t_nslookup;
288 break;
289 case CURLINFO_CONNECT_TIME_T:
290 *param_offt = data->progress.t_connect;
291 break;
292 case CURLINFO_APPCONNECT_TIME_T:
293 *param_offt = data->progress.t_appconnect;
294 break;
295 case CURLINFO_PRETRANSFER_TIME_T:
296 *param_offt = data->progress.t_pretransfer;
297 break;
298 case CURLINFO_STARTTRANSFER_TIME_T:
299 *param_offt = data->progress.t_starttransfer;
300 break;
301 case CURLINFO_REDIRECT_TIME_T:
302 *param_offt = data->progress.t_redirect;
303 break;
304
305 default:
306 return CURLE_UNKNOWN_OPTION;
307 }
308
309 return CURLE_OK;
310}
311
312static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
313 double *param_doublep)
314{
315 switch(info) {
316 case CURLINFO_TOTAL_TIME:
317 *param_doublep = DOUBLE_SECS(data->progress.timespent);
318 break;
319 case CURLINFO_NAMELOOKUP_TIME:
320 *param_doublep = DOUBLE_SECS(data->progress.t_nslookup);
321 break;
322 case CURLINFO_CONNECT_TIME:
323 *param_doublep = DOUBLE_SECS(data->progress.t_connect);
324 break;
325 case CURLINFO_APPCONNECT_TIME:
326 *param_doublep = DOUBLE_SECS(data->progress.t_appconnect);
327 break;
328 case CURLINFO_PRETRANSFER_TIME:
329 *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer);
330 break;
331 case CURLINFO_STARTTRANSFER_TIME:
332 *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
333 break;
334 case CURLINFO_SIZE_UPLOAD:
335 *param_doublep = (double)data->progress.uploaded;
336 break;
337 case CURLINFO_SIZE_DOWNLOAD:
338 *param_doublep = (double)data->progress.downloaded;
339 break;
340 case CURLINFO_SPEED_DOWNLOAD:
341 *param_doublep = (double)data->progress.dlspeed;
342 break;
343 case CURLINFO_SPEED_UPLOAD:
344 *param_doublep = (double)data->progress.ulspeed;
345 break;
346 case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
347 *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
348 (double)data->progress.size_dl:-1;
349 break;
350 case CURLINFO_CONTENT_LENGTH_UPLOAD:
351 *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
352 (double)data->progress.size_ul:-1;
353 break;
354 case CURLINFO_REDIRECT_TIME:
355 *param_doublep = DOUBLE_SECS(data->progress.t_redirect);
356 break;
357
358 default:
359 return CURLE_UNKNOWN_OPTION;
360 }
361
362 return CURLE_OK;
363}
364
365static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
366 struct curl_slist **param_slistp)
367{
368 union {
369 struct curl_certinfo *to_certinfo;
370 struct curl_slist *to_slist;
371 } ptr;
372
373 switch(info) {
374 case CURLINFO_SSL_ENGINES:
375 *param_slistp = Curl_ssl_engines_list(data);
376 break;
377 case CURLINFO_COOKIELIST:
378 *param_slistp = Curl_cookie_list(data);
379 break;
380 case CURLINFO_CERTINFO:
381 /* Return the a pointer to the certinfo struct. Not really an slist
382 pointer but we can pretend it is here */
383 ptr.to_certinfo = &data->info.certs;
384 *param_slistp = ptr.to_slist;
385 break;
386 case CURLINFO_TLS_SESSION:
387 case CURLINFO_TLS_SSL_PTR:
388 {
389 struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
390 param_slistp;
391 struct curl_tlssessioninfo *tsi = &data->tsi;
392#ifdef USE_SSL
393 struct connectdata *conn = data->conn;
394#endif
395
396 *tsip = tsi;
397 tsi->backend = Curl_ssl_backend();
398 tsi->internals = NULL;
399
400#ifdef USE_SSL
401 if(conn && tsi->backend != CURLSSLBACKEND_NONE) {
402 unsigned int i;
403 for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) {
404 if(conn->ssl[i].use) {
405 tsi->internals = Curl_ssl->get_internals(&conn->ssl[i], info);
406 break;
407 }
408 }
409 }
410#endif
411 }
412 break;
413 default:
414 return CURLE_UNKNOWN_OPTION;
415 }
416
417 return CURLE_OK;
418}
419
420static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info,
421 curl_socket_t *param_socketp)
422{
423 switch(info) {
424 case CURLINFO_ACTIVESOCKET:
425 *param_socketp = Curl_getconnectinfo(data, NULL);
426 break;
427 default:
428 return CURLE_UNKNOWN_OPTION;
429 }
430
431 return CURLE_OK;
432}
433
434CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
435{
436 va_list arg;
437 long *param_longp = NULL;
438 double *param_doublep = NULL;
439 curl_off_t *param_offt = NULL;
440 const char **param_charp = NULL;
441 struct curl_slist **param_slistp = NULL;
442 curl_socket_t *param_socketp = NULL;
443 int type;
444 CURLcode result = CURLE_UNKNOWN_OPTION;
445
446 if(!data)
447 return result;
448
449 va_start(arg, info);
450
451 type = CURLINFO_TYPEMASK & (int)info;
452 switch(type) {
453 case CURLINFO_STRING:
454 param_charp = va_arg(arg, const char **);
455 if(param_charp)
456 result = getinfo_char(data, info, param_charp);
457 break;
458 case CURLINFO_LONG:
459 param_longp = va_arg(arg, long *);
460 if(param_longp)
461 result = getinfo_long(data, info, param_longp);
462 break;
463 case CURLINFO_DOUBLE:
464 param_doublep = va_arg(arg, double *);
465 if(param_doublep)
466 result = getinfo_double(data, info, param_doublep);
467 break;
468 case CURLINFO_OFF_T:
469 param_offt = va_arg(arg, curl_off_t *);
470 if(param_offt)
471 result = getinfo_offt(data, info, param_offt);
472 break;
473 case CURLINFO_SLIST:
474 param_slistp = va_arg(arg, struct curl_slist **);
475 if(param_slistp)
476 result = getinfo_slist(data, info, param_slistp);
477 break;
478 case CURLINFO_SOCKET:
479 param_socketp = va_arg(arg, curl_socket_t *);
480 if(param_socketp)
481 result = getinfo_socket(data, info, param_socketp);
482 break;
483 default:
484 break;
485 }
486
487 va_end(arg);
488
489 return result;
490}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette