1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2009, 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 http://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  * $Id: getinfo.c,v 1.67 2009-02-23 18:45:00 bagder Exp $
22  ***************************************************************************/
23 
24 #include "setup.h"
25 
26 #include <curl/curl.h>
27 
28 #include "urldata.h"
29 #include "getinfo.h"
30 
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdarg.h>
34 #include <stdlib.h>
35 #include "memory.h"
36 #include "sslgen.h"
37 #include "connect.h" /* Curl_getconnectinfo() */
38 #include "progress.h"
39 
40 /* Make this the last #include */
41 #include "memdebug.h"
42 
43 /*
44  * This is supposed to be called in the beginning of a perform() session
45  * and should reset all session-info variables
46  */
Curl_initinfo(struct SessionHandle * data)47 CURLcode Curl_initinfo(struct SessionHandle *data)
48 {
49   struct Progress *pro = &data->progress;
50   struct PureInfo *info =&data->info;
51 
52   pro->t_nslookup = 0;
53   pro->t_connect = 0;
54   pro->t_pretransfer = 0;
55   pro->t_starttransfer = 0;
56   pro->timespent = 0;
57   pro->t_redirect = 0;
58 
59   info->httpcode = 0;
60   info->httpversion=0;
61   info->filetime=-1; /* -1 is an illegal time and thus means unknown */
62 
63   if(info->contenttype)
64     free(info->contenttype);
65   info->contenttype = NULL;
66 
67   info->header_size = 0;
68   info->request_size = 0;
69   info->numconnects = 0;
70   return CURLE_OK;
71 }
72 
Curl_getinfo(struct SessionHandle * data,CURLINFO info,...)73 CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
74 {
75   va_list arg;
76   long *param_longp=NULL;
77   double *param_doublep=NULL;
78   char **param_charp=NULL;
79   struct curl_slist **param_slistp=NULL;
80   int type;
81 
82   union {
83     struct curl_certinfo * to_certinfo;
84     struct curl_slist    * to_slist;
85   } ptr;
86 
87   if(!data)
88     return CURLE_BAD_FUNCTION_ARGUMENT;
89 
90   va_start(arg, info);
91 
92   type = CURLINFO_TYPEMASK & (int)info;
93   switch(type) {
94   case CURLINFO_STRING:
95     param_charp = va_arg(arg, char **);
96     if(NULL == param_charp)
97       return CURLE_BAD_FUNCTION_ARGUMENT;
98     break;
99   case CURLINFO_LONG:
100     param_longp = va_arg(arg, long *);
101     if(NULL == param_longp)
102       return CURLE_BAD_FUNCTION_ARGUMENT;
103     break;
104   case CURLINFO_DOUBLE:
105     param_doublep = va_arg(arg, double *);
106     if(NULL == param_doublep)
107       return CURLE_BAD_FUNCTION_ARGUMENT;
108     break;
109   case CURLINFO_SLIST:
110     param_slistp = va_arg(arg, struct curl_slist **);
111     if(NULL == param_slistp)
112       return CURLE_BAD_FUNCTION_ARGUMENT;
113     break;
114   default:
115     return CURLE_BAD_FUNCTION_ARGUMENT;
116   }
117 
118   switch(info) {
119   case CURLINFO_EFFECTIVE_URL:
120     *param_charp = data->change.url?data->change.url:(char *)"";
121     break;
122   case CURLINFO_RESPONSE_CODE:
123     *param_longp = data->info.httpcode;
124     break;
125   case CURLINFO_HTTP_CONNECTCODE:
126     *param_longp = data->info.httpproxycode;
127     break;
128   case CURLINFO_FILETIME:
129     *param_longp = data->info.filetime;
130     break;
131   case CURLINFO_HEADER_SIZE:
132     *param_longp = data->info.header_size;
133     break;
134   case CURLINFO_REQUEST_SIZE:
135     *param_longp = data->info.request_size;
136     break;
137   case CURLINFO_TOTAL_TIME:
138     *param_doublep = data->progress.timespent;
139     break;
140   case CURLINFO_NAMELOOKUP_TIME:
141     *param_doublep = data->progress.t_nslookup;
142     break;
143   case CURLINFO_CONNECT_TIME:
144     *param_doublep = data->progress.t_connect;
145     break;
146   case CURLINFO_APPCONNECT_TIME:
147     *param_doublep = data->progress.t_appconnect;
148     break;
149   case CURLINFO_PRETRANSFER_TIME:
150     *param_doublep =  data->progress.t_pretransfer;
151     break;
152   case CURLINFO_STARTTRANSFER_TIME:
153     *param_doublep = data->progress.t_starttransfer;
154     break;
155   case CURLINFO_SIZE_UPLOAD:
156     *param_doublep =  (double)data->progress.uploaded;
157     break;
158   case CURLINFO_SIZE_DOWNLOAD:
159     *param_doublep = (double)data->progress.downloaded;
160     break;
161   case CURLINFO_SPEED_DOWNLOAD:
162     *param_doublep =  (double)data->progress.dlspeed;
163     break;
164   case CURLINFO_SPEED_UPLOAD:
165     *param_doublep = (double)data->progress.ulspeed;
166     break;
167   case CURLINFO_SSL_VERIFYRESULT:
168     *param_longp = data->set.ssl.certverifyresult;
169     break;
170   case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
171     *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
172       (double)data->progress.size_dl:-1;
173     break;
174   case CURLINFO_CONTENT_LENGTH_UPLOAD:
175     *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
176       (double)data->progress.size_ul:-1;
177     break;
178   case CURLINFO_REDIRECT_TIME:
179     *param_doublep =  data->progress.t_redirect;
180     break;
181   case CURLINFO_REDIRECT_COUNT:
182     *param_longp = data->set.followlocation;
183     break;
184   case CURLINFO_CONTENT_TYPE:
185     *param_charp = data->info.contenttype;
186     break;
187   case CURLINFO_PRIVATE:
188     *param_charp = (char *) data->set.private_data;
189     break;
190   case CURLINFO_HTTPAUTH_AVAIL:
191     *param_longp = data->info.httpauthavail;
192     break;
193   case CURLINFO_PROXYAUTH_AVAIL:
194     *param_longp = data->info.proxyauthavail;
195     break;
196   case CURLINFO_OS_ERRNO:
197     *param_longp = data->state.os_errno;
198     break;
199   case CURLINFO_NUM_CONNECTS:
200     *param_longp = data->info.numconnects;
201     break;
202   case CURLINFO_SSL_ENGINES:
203     *param_slistp = Curl_ssl_engines_list(data);
204     break;
205   case CURLINFO_COOKIELIST:
206     *param_slistp = Curl_cookie_list(data);
207     break;
208   case CURLINFO_FTP_ENTRY_PATH:
209     /* Return the entrypath string from the most recent connection.
210        This pointer was copied from the connectdata structure by FTP.
211        The actual string may be free()ed by subsequent libcurl calls so
212        it must be copied to a safer area before the next libcurl call.
213        Callers must never free it themselves. */
214     *param_charp = data->state.most_recent_ftp_entrypath;
215     break;
216   case CURLINFO_LASTSOCKET:
217     (void)Curl_getconnectinfo(data, param_longp, NULL);
218     break;
219   case CURLINFO_REDIRECT_URL:
220     /* Return the URL this request would have been redirected to if that
221        option had been enabled! */
222     *param_charp = data->info.wouldredirect;
223     break;
224   case CURLINFO_PRIMARY_IP:
225     /* Return the ip address of the most recent (primary) connection */
226     *param_charp = data->info.ip;
227     break;
228   case CURLINFO_CERTINFO:
229     /* Return the a pointer to the certinfo struct. Not really an slist
230        pointer but we can pretend it is here */
231     ptr.to_certinfo = &data->info.certs;
232     *param_slistp = ptr.to_slist;
233     break;
234   case CURLINFO_CONDITION_UNMET:
235     /* return if the condition prevented the document to get transfered */
236     *param_longp = data->info.timecond;
237     break;
238   default:
239     return CURLE_BAD_FUNCTION_ARGUMENT;
240   }
241   return CURLE_OK;
242 }
243