source: azure_iot_hub/trunk/curl-7.57.0/lib/getinfo.c@ 389

Last change on this file since 389 was 389, checked in by coas-nagasima, 5 years ago

ビルドが通るよう更新

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