doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
url.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2004, 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: url.c,v 1.350 2004/03/12 08:55:51 bagder Exp $
22  ***************************************************************************/
23 
24 /* -- WIN32 approved -- */
25 
26 #include "setup.h"
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 
36 #include <errno.h>
37 
38 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
39 #include <time.h>
40 #include <io.h>
41 #else
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
44 #endif
45 #include <netinet/in.h>
46 #include <sys/time.h>
47 #ifdef HAVE_UNISTD_H
48 #include <unistd.h>
49 #endif
50 #include <netdb.h>
51 #ifdef HAVE_ARPA_INET_H
52 #include <arpa/inet.h>
53 #endif
54 #ifdef HAVE_NET_IF_H
55 #include <net/if.h>
56 #endif
57 #include <sys/ioctl.h>
58 #include <signal.h>
59 
60 #ifdef HAVE_SYS_PARAM_H
61 #include <sys/param.h>
62 #endif
63 
64 #ifdef HAVE_SYS_SELECT_H
65 #include <sys/select.h>
66 #endif
67 
68 #ifdef VMS
69 #include <in.h>
70 #include <inet.h>
71 #endif
72 
73 #ifdef HAVE_SETJMP_H
74 #include <setjmp.h>
75 #endif
76 
77 #ifndef HAVE_SELECT
78 #error "We can't compile without select() support!"
79 #endif
80 #ifndef HAVE_SOCKET
81 #error "We can't compile without socket() support!"
82 #endif
83 
84 
85 #endif
86 
87 #ifdef HAVE_OPENSSL_ENGINE_H
88 #include <openssl/engine.h>
89 #endif
90 #include "urldata.h"
91 #include "netrc.h"
92 
93 #include "formdata.h"
94 #include "base64.h"
95 #include "ssluse.h"
96 #include "hostip.h"
97 #include "if2ip.h"
98 #include "transfer.h"
99 #include "sendf.h"
100 #include "progress.h"
101 #include "cookie.h"
102 #include "strequal.h"
103 #include "escape.h"
104 #include "strtok.h"
105 #include "share.h"
106 #include "content_encoding.h"
107 #include "http_digest.h"
108 #include "http_negotiate.h"
109 
110 /* And now for the protocols */
111 #include "ftp.h"
112 #include "dict.h"
113 #include "telnet.h"
114 #include "http.h"
115 #include "file.h"
116 #include "ldap.h"
117 #include "url.h"
118 #include "connect.h"
119 //#include <ca-bundle.h>
120 
121 #include <curl/types.h>
122 
123 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
124 #include "inet_ntoa_r.h"
125 #endif
126 
127 #define _MPRINTF_REPLACE /* use our functions only */
128 #include <curl/mprintf.h>
129 
130 #ifdef HAVE_KRB4
131 #include "security.h"
132 #endif
133 
134 /* The last #include file should be: */
135 #ifdef CURLDEBUG
136 #include "memdebug.h"
137 #endif
138 
139 /* Local static prototypes */
140 static int ConnectionKillOne(struct SessionHandle *data);
141 static bool ConnectionExists(struct SessionHandle *data,
142  struct connectdata *needle,
143  struct connectdata **usethis);
144 static unsigned int ConnectionStore(struct SessionHandle *data,
145  struct connectdata *conn);
146 static bool safe_strequal(char* str1, char* str2);
147 
148 #ifndef USE_ARES
149 /* not for Win32, unless it is cygwin
150  not for ares builds */
151 #if !defined(WIN32) || defined(__CYGWIN32__)
152 
153 #ifndef RETSIGTYPE
154 #define RETSIGTYPE void
155 #endif
156 #ifdef HAVE_SIGSETJMP
157 extern sigjmp_buf curl_jmpenv;
158 #endif
159 static
160 RETSIGTYPE alarmfunc(int sig)
161 {
162  /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
163  (void)sig;
164 #ifdef HAVE_SIGSETJMP
165  siglongjmp(curl_jmpenv, 1);
166 #endif
167  return;
168 }
169 #endif
170 #endif /* USE_ARES */
171 
172 void Curl_safefree(void *ptr)
173 {
174  if(ptr)
175  free(ptr);
176 }
177 
178 /*
179  * This is the internal function curl_easy_cleanup() calls. This should
180  * cleanup and free all resources associated with this sessionhandle.
181  *
182  * NOTE: if we ever add something that attempts to write to a socket or
183  * similar here, we must ignore SIGPIPE first. It is currently only done
184  * when curl_easy_perform() is invoked.
185  */
186 
188 {
189  /* Loop through all open connections and kill them one by one */
190  while(-1 != ConnectionKillOne(data));
191 
192 #ifdef USE_SSLEAY
193  /* Close down all open SSL info and sessions */
194  Curl_SSL_Close_All(data);
195 #endif
196 
197  if(data->change.cookielist) /* clean up list if any */
199 
201  Curl_safefree(data->state.scratch);
202 
203  if(data->change.proxy_alloc)
204  free(data->change.proxy);
205 
206  if(data->change.referer_alloc)
207  free(data->change.referer);
208 
209  if(data->change.url_alloc)
210  free(data->change.url);
211 
213 
214 #ifndef CURL_DISABLE_HTTP
216  if(data->set.cookiejar) {
217  /* we have a "destination" for all the cookies to get dumped to */
218  if(Curl_cookie_output(data->cookies, data->set.cookiejar))
219  infof(data, "WARNING: failed to save cookies in %s\n",
220  data->set.cookiejar);
221  }
222 
223  if( !data->share || (data->cookies != data->share->cookies) ) {
225  }
227 #endif
228 
229  /* free the connection cache */
230  free(data->state.connects);
231 
233 
234  Curl_digest_cleanup(data);
235 
236 #ifdef USE_ARES
237  /* this destroys the channel and we cannot use it anymore after this */
238  ares_destroy(data->state.areschannel);
239 #endif
240 
241  /* No longer a dirty share, if it exists */
242  if (data->share)
243  data->share->dirty--;
244 
245  free(data);
246  return CURLE_OK;
247 }
248 
250 {
251  /* We don't yet support specifying the URL at this point */
252  struct SessionHandle *data;
253  /* Very simple start-up: alloc the struct, init it with zeroes and return */
254  data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle));
255  if(!data)
256  /* this is a very serious error */
257  return CURLE_OUT_OF_MEMORY;
258 
259  memset(data, 0, sizeof(struct SessionHandle));
260 
261 #ifdef USE_ARES
262  if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
263  free(data);
264  return CURLE_FAILED_INIT;
265  }
266  /* make sure that all other returns from this function should destroy the
267  ares channel before returning error! */
268 #endif
269 
270  /* We do some initial setup here, all those fields that can't be just 0 */
271 
272  data->state.headerbuff=(char*)malloc(HEADERSIZE);
273  if(!data->state.headerbuff) {
274  free(data); /* free the memory again */
275  return CURLE_OUT_OF_MEMORY;
276  }
277 
279 
280  data->set.out = stdout; /* default output to stdout */
281  data->set.in = stdin; /* default input from stdin */
282  data->set.err = stderr; /* default stderr to stderr */
283 
284  /* use fwrite as default function to store output */
286 
287  /* use fread as default function to read input */
289 
290  data->set.infilesize = -1; /* we don't know any size */
291 
292  data->state.current_speed = -1; /* init to negative == impossible */
293 
294  data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
295  data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
296  data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
297 
298  data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
299 
300  /* make libcurl quiet by default: */
301  data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
302  data->progress.flags |= PGRS_HIDE;
303 
304  /* Set the default size of the SSL session ID cache */
305  data->set.ssl.numsessions = 5;
306 
307  data->set.proxyport = 1080;
308 
309  data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
310 
311  data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic authentication */
312  data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic authentication */
313 
314  /* create an array with connection data struct pointers */
315  data->state.numconnects = 5; /* hard-coded right now */
316  data->state.connects = (struct connectdata **)
317  malloc(sizeof(struct connectdata *) * data->state.numconnects);
318 
319  if(!data->state.connects) {
320  free(data->state.headerbuff);
321  free(data);
322  return CURLE_OUT_OF_MEMORY;
323  }
324 
325  /*
326  * libcurl 7.10 introduces SSL verification *by default*! This needs to be
327  * switched off unless wanted.
328  */
329  data->set.ssl.verifypeer = TRUE;
330  data->set.ssl.verifyhost = 2;
331 #ifdef CURL_CA_BUNDLE
332  /* This is our prefered CA cert bundle since install time */
333  data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
334 #endif
335 
336  memset(data->state.connects, 0,
337  sizeof(struct connectdata *)*data->state.numconnects);
338 
339  *curl = data;
340  return CURLE_OK;
341 }
342 
344 {
345  va_list param;
346  char *cookiefile;
347 
348  va_start(param, option);
349 
350  switch(option) {
351  case CURLOPT_DNS_CACHE_TIMEOUT:
352  data->set.dns_cache_timeout = va_arg(param, int);
353  break;
354  case CURLOPT_DNS_USE_GLOBAL_CACHE:
355  {
356  int use_cache = va_arg(param, int);
357  if (use_cache) {
359  }
360 
361  data->set.global_dns_cache = use_cache;
362  }
363  break;
364  case CURLOPT_SSL_CIPHER_LIST:
365  /* set a list of cipher we want to use in the SSL connection */
366  data->set.ssl.cipher_list = va_arg(param, char *);
367  break;
368 
369  case CURLOPT_RANDOM_FILE:
370  /*
371  * This is the path name to a file that contains random data to seed
372  * the random SSL stuff with. The file is only used for reading.
373  */
374  data->set.ssl.random_file = va_arg(param, char *);
375  break;
376  case CURLOPT_EGDSOCKET:
377  /*
378  * The Entropy Gathering Daemon socket pathname
379  */
380  data->set.ssl.egdsocket = va_arg(param, char *);
381  break;
382  case CURLOPT_MAXCONNECTS:
383  /*
384  * Set the absolute number of maximum simultaneous alive connection that
385  * libcurl is allowed to have.
386  */
387  {
388  long newconnects= va_arg(param, long);
389  struct connectdata **newptr;
390 
391  if(newconnects < data->state.numconnects) {
392  /* Since this number is *decreased* from the existing number, we must
393  close the possibly open connections that live on the indexes that
394  are being removed! */
395  int i;
396  for(i=newconnects; i< data->state.numconnects; i++)
397  Curl_disconnect(data->state.connects[i]);
398  }
399  if(newconnects) {
400  int i;
401  newptr= (struct connectdata **)
402  realloc(data->state.connects,
403  sizeof(struct connectdata *) * newconnects);
404  if(!newptr)
405  /* we closed a few connections in vain, but so what? */
406  return CURLE_OUT_OF_MEMORY;
407 
408  /* nullify the newly added pointers */
409  for(i=data->state.numconnects; i<newconnects; i++) {
410  newptr[i] = NULL;
411  }
412 
413  data->state.connects = newptr;
414  data->state.numconnects = newconnects;
415  }
416  else {
417  /* zero makes NO cache at all */
418  if(data->state.connects)
419  free(data->state.connects);
420  data->state.connects=NULL;
421  data->state.numconnects=0;
422  }
423  }
424  break;
425  case CURLOPT_FORBID_REUSE:
426  /*
427  * When this transfer is done, it must not be left to be reused by a
428  * subsequent transfer but shall be closed immediately.
429  */
430  data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
431  break;
432  case CURLOPT_FRESH_CONNECT:
433  /*
434  * This transfer shall not use a previously cached connection but
435  * should be made with a fresh new connect!
436  */
437  data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
438  break;
439  case CURLOPT_VERBOSE:
440  /*
441  * Verbose means infof() calls that give a lot of information about
442  * the connection and transfer procedures as well as internal choices.
443  */
444  data->set.verbose = va_arg(param, long)?TRUE:FALSE;
445  break;
446  case CURLOPT_HEADER:
447  /*
448  * Set to include the header in the general data output stream.
449  */
450  data->set.http_include_header = va_arg(param, long)?TRUE:FALSE;
451  break;
452  case CURLOPT_NOPROGRESS:
453  /*
454  * Shut off the internal supported progress meter
455  */
456  data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
457  if(data->set.hide_progress)
458  data->progress.flags |= PGRS_HIDE;
459  else
460  data->progress.flags &= ~PGRS_HIDE;
461  break;
462  case CURLOPT_NOBODY:
463  /*
464  * Do not include the body part in the output data stream.
465  */
466  data->set.no_body = va_arg(param, long)?TRUE:FALSE;
467  break;
468  case CURLOPT_FAILONERROR:
469  /*
470  * Don't output the >=300 error code HTML-page, but instead only
471  * return error.
472  */
473  data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
474  break;
475  case CURLOPT_UPLOAD:
476  /*
477  * We want to sent data to the remote host
478  */
479  data->set.upload = va_arg(param, long)?TRUE:FALSE;
480  if(data->set.upload)
481  /* If this is HTTP, PUT is what's needed to "upload" */
482  data->set.httpreq = HTTPREQ_PUT;
483  break;
484  case CURLOPT_FILETIME:
485  /*
486  * Try to get the file time of the remote document. The time will
487  * later (possibly) become available using curl_easy_getinfo().
488  */
489  data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
490  break;
491  case CURLOPT_FTP_CREATE_MISSING_DIRS:
492  /*
493  * An FTP option that modifies an upload to create missing directories on
494  * the server.
495  */
496  data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
497  break;
498  case CURLOPT_FTP_RESPONSE_TIMEOUT:
499  /*
500  * An FTP option that specifies how quickly an FTP response must be
501  * obtained before it is considered failure.
502  */
503  data->set.ftp_response_timeout = va_arg( param , long );
504  break;
505  case CURLOPT_FTPLISTONLY:
506  /*
507  * An FTP option that changes the command to one that asks for a list
508  * only, no file info details.
509  */
510  data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
511  break;
512  case CURLOPT_FTPAPPEND:
513  /*
514  * We want to upload and append to an existing (FTP) file.
515  */
516  data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
517  break;
518  case CURLOPT_NETRC:
519  /*
520  * Parse the $HOME/.netrc file
521  */
522  data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
523  break;
524  case CURLOPT_NETRC_FILE:
525  /*
526  * Use this file instead of the $HOME/.netrc file
527  */
528  data->set.netrc_file = va_arg(param, char *);
529  break;
530  case CURLOPT_FOLLOWLOCATION:
531  /*
532  * Follow Location: header hints on a HTTP-server.
533  */
534  data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
535  break;
536  case CURLOPT_UNRESTRICTED_AUTH:
537  /*
538  * Send authentication (user+password) when following locations, even when
539  * hostname changed.
540  */
542  va_arg(param, long)?TRUE:FALSE;
543  break;
544  case CURLOPT_HTTP_VERSION:
545  /*
546  * This sets a requested HTTP version to be used. The value is one of
547  * the listed enums in curl/curl.h.
548  */
549  data->set.httpversion = va_arg(param, long);
550  break;
551  case CURLOPT_TRANSFERTEXT:
552  /*
553  * This option was previously named 'FTPASCII'. Renamed to work with
554  * more protocols than merely FTP.
555  *
556  * Transfer using ASCII (instead of BINARY).
557  */
558  data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
559  break;
560  case CURLOPT_PUT:
561  /*
562  * Use the HTTP PUT request to transfer data if this is TRUE. If this is
563  * FALSE, don't set the httpreq. We can't know what to revert it to!
564  */
565  if(va_arg(param, long))
566  data->set.httpreq = HTTPREQ_PUT;
567  break;
568  case CURLOPT_TIMECONDITION:
569  /*
570  * Set HTTP time condition. This must be one of the defines in the
571  * curl/curl.h header file.
572  */
573  data->set.timecondition = (curl_TimeCond)va_arg(param, long);
574  break;
575  case CURLOPT_TIMEVALUE:
576  /*
577  * This is the value to compare with the remote document with the
578  * method set with CURLOPT_TIMECONDITION
579  */
580  data->set.timevalue = va_arg(param, long);
581  break;
582  case CURLOPT_SSLVERSION:
583  /*
584  * Set explicit SSL version to try to connect with, as some SSL
585  * implementations are lame.
586  */
587  data->set.ssl.version = va_arg(param, long);
588  break;
589 
590  case CURLOPT_COOKIESESSION:
591  /*
592  * Set this option to TRUE to start a new "cookie session". It will
593  * prevent the forthcoming read-cookies-from-file actions to accept
594  * cookies that are marked as being session cookies, as they belong to a
595  * previous session.
596  *
597  * In the original Netscape cookie spec, "session cookies" are cookies
598  * with no expire date set. RFC2109 describes the same action if no
599  * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
600  * a 'Discard' action that can enforce the discard even for cookies that
601  * have a Max-Age.
602  *
603  * We run mostly with the original cookie spec, as hardly anyone implements
604  * anything else.
605  */
606  data->set.cookiesession = (bool)va_arg(param, long);
607  break;
608 
609 #ifndef CURL_DISABLE_HTTP
610  case CURLOPT_COOKIEFILE:
611  /*
612  * Set cookie file to read and parse. Can be used multiple times.
613  */
614  cookiefile = (char *)va_arg(param, void *);
615  if(cookiefile)
616  /* append the cookie file name to the list of file names, and deal with
617  them later */
618  data->change.cookielist =
619  curl_slist_append(data->change.cookielist, cookiefile);
620  break;
621 
622  case CURLOPT_COOKIEJAR:
623  /*
624  * Set cookie file name to dump all cookies to when we're done.
625  */
626  data->set.cookiejar = (char *)va_arg(param, void *);
627 
628  /*
629  * Activate the cookie parser. This may or may not already
630  * have been made.
631  */
632  data->cookies = Curl_cookie_init(data, NULL, data->cookies,
633  data->set.cookiesession);
634  break;
635 #endif
636 
637  case CURLOPT_WRITEHEADER:
638  /*
639  * Custom pointer to pass the header write callback function
640  */
641  data->set.writeheader = (void *)va_arg(param, void *);
642  break;
643  case CURLOPT_COOKIE:
644  /*
645  * Cookie string to send to the remote server in the request.
646  */
647  data->set.cookie = va_arg(param, char *);
648  break;
649  case CURLOPT_ERRORBUFFER:
650  /*
651  * Error buffer provided by the caller to get the human readable
652  * error string in.
653  */
654  data->set.errorbuffer = va_arg(param, char *);
655  break;
656  case CURLOPT_FILE:
657  /*
658  * FILE pointer to write to or include in the data write callback
659  */
660  data->set.out = va_arg(param, FILE *);
661  break;
662  case CURLOPT_FTPPORT:
663  /*
664  * Use FTP PORT, this also specifies which IP address to use
665  */
666  data->set.ftpport = va_arg(param, char *);
667  data->set.ftp_use_port = data->set.ftpport?1:0;
668  break;
669 
670  case CURLOPT_FTP_USE_EPRT:
671  data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
672  break;
673 
674  case CURLOPT_FTP_USE_EPSV:
675  data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
676  break;
677 
678  case CURLOPT_HTTPHEADER:
679  /*
680  * Set a list with HTTP headers to use (or replace internals with)
681  */
682  data->set.headers = va_arg(param, struct curl_slist *);
683  break;
684  case CURLOPT_CUSTOMREQUEST:
685  /*
686  * Set a custom string to use as request
687  */
688  data->set.customrequest = va_arg(param, char *);
689 
690  /* we don't set
691  data->set.httpreq = HTTPREQ_CUSTOM;
692  here, we continue as if we were using the already set type
693  and this just changes the actual request keyword */
694  break;
695  case CURLOPT_HTTPPOST:
696  /*
697  * Set to make us do HTTP POST
698  */
699  data->set.httppost = va_arg(param, struct curl_httppost *);
700  if(data->set.httppost)
701  data->set.httpreq = HTTPREQ_POST_FORM;
702  break;
703 
704  case CURLOPT_HTTPGET:
705  /*
706  * Set to force us do HTTP GET
707  */
708  if(va_arg(param, long)) {
709  data->set.httpreq = HTTPREQ_GET;
710  data->set.upload = FALSE; /* switch off upload */
711  }
712  break;
713 
714  case CURLOPT_INFILE:
715  /*
716  * FILE pointer to read the file to be uploaded from. Or possibly
717  * used as argument to the read callback.
718  */
719  data->set.in = va_arg(param, FILE *);
720  break;
721  case CURLOPT_INFILESIZE:
722  /*
723  * If known, this should inform curl about the file size of the
724  * to-be-uploaded file.
725  */
726  data->set.infilesize = va_arg(param, long);
727  break;
728  case CURLOPT_INFILESIZE_LARGE:
729  /*
730  * If known, this should inform curl about the file size of the
731  * to-be-uploaded file.
732  */
733  data->set.infilesize = va_arg(param, curl_off_t);
734  break;
735  case CURLOPT_LOW_SPEED_LIMIT:
736  /*
737  * The low speed limit that if transfers are below this for
738  * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
739  */
740  data->set.low_speed_limit=va_arg(param, long);
741  break;
742  case CURLOPT_LOW_SPEED_TIME:
743  /*
744  * The low speed time that if transfers are below the set
745  * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
746  */
747  data->set.low_speed_time=va_arg(param, long);
748  break;
749  case CURLOPT_URL:
750  /*
751  * The URL to fetch.
752  */
753  if(data->change.url_alloc) {
754  /* the already set URL is allocated, free it first! */
755  free(data->change.url);
756  data->change.url_alloc=FALSE;
757  }
758  data->set.set_url = va_arg(param, char *);
759  data->change.url = data->set.set_url;
760  data->change.url_changed = TRUE;
761  break;
762  case CURLOPT_PORT:
763  /*
764  * The port number to use when getting the URL
765  */
766  data->set.use_port = va_arg(param, long);
767  break;
768  case CURLOPT_POST:
769  /* Does this option serve a purpose anymore? Yes it does, when
770  CURLOPT_POSTFIELDS isn't used and the POST data is read off the
771  callback! */
772  if(va_arg(param, long))
773  data->set.httpreq = HTTPREQ_POST;
774  break;
775  case CURLOPT_POSTFIELDS:
776  /*
777  * A string with POST data. Makes curl HTTP POST.
778  */
779  data->set.postfields = va_arg(param, char *);
780  if(data->set.postfields)
781  data->set.httpreq = HTTPREQ_POST;
782  break;
783  case CURLOPT_POSTFIELDSIZE:
784  /*
785  * The size of the POSTFIELD data to prevent libcurl to do strlen() to
786  * figure it out. Enables binary posts.
787  */
788  data->set.postfieldsize = va_arg(param, long);
789  break;
790  case CURLOPT_POSTFIELDSIZE_LARGE:
791  /*
792  * The size of the POSTFIELD data to prevent libcurl to do strlen() to
793  * figure it out. Enables binary posts.
794  */
795  data->set.postfieldsize = va_arg(param, curl_off_t);
796  break;
797  case CURLOPT_REFERER:
798  /*
799  * String to set in the HTTP Referer: field.
800  */
801  if(data->change.referer_alloc) {
802  free(data->change.referer);
803  data->change.referer_alloc = FALSE;
804  }
805  data->set.set_referer = va_arg(param, char *);
806  data->change.referer = data->set.set_referer;
807  break;
808  case CURLOPT_AUTOREFERER:
809  /*
810  * Switch on automatic referer that gets set if curl follows locations.
811  */
812  data->set.http_auto_referer = va_arg(param, long)?1:0;
813  break;
814  case CURLOPT_PROXY:
815  /*
816  * Set proxy server:port to use as HTTP proxy.
817  *
818  * If the proxy is set to "" we explicitly say that we don't want to use a
819  * proxy (even though there might be environment variables saying so).
820  *
821  * Setting it to NULL, means no proxy but allows the environment variables
822  * to decide for us.
823  */
824  if(data->change.proxy_alloc) {
825  /*
826  * The already set string is allocated, free that first
827  */
828  data->change.proxy_alloc=FALSE;;
829  free(data->change.proxy);
830  }
831  data->set.set_proxy = va_arg(param, char *);
832  data->change.proxy = data->set.set_proxy;
833  break;
834  case CURLOPT_HTTPPROXYTUNNEL:
835  /*
836  * Tunnel operations through the proxy instead of normal proxy use
837  */
838  data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
839  break;
840  case CURLOPT_PROXYPORT:
841  /*
842  * Explicitly set HTTP proxy port number.
843  */
844  data->set.proxyport = va_arg(param, long);
845  break;
846  case CURLOPT_TIMEOUT:
847  /*
848  * The maximum time you allow curl to use for a single transfer
849  * operation.
850  */
851  data->set.timeout = va_arg(param, long);
852  break;
853  case CURLOPT_CONNECTTIMEOUT:
854  /*
855  * The maximum time you allow curl to use to connect.
856  */
857  data->set.connecttimeout = va_arg(param, long);
858  break;
859  case CURLOPT_MAXREDIRS:
860  /*
861  * The maximum amount of hops you allow curl to follow Location:
862  * headers. This should mostly be used to detect never-ending loops.
863  */
864  data->set.maxredirs = va_arg(param, long);
865  break;
866  case CURLOPT_USERAGENT:
867  /*
868  * String to use in the HTTP User-Agent field
869  */
870  data->set.useragent = va_arg(param, char *);
871  break;
872  case CURLOPT_ENCODING:
873  /*
874  * String to use at the value of Accept-Encoding header. 08/28/02 jhrg
875  *
876  * If the encoding is set to "" we use an Accept-Encoding header that
877  * encompasses all the encodings we support.
878  * If the encoding is set to NULL we don't send an Accept-Encoding header
879  * and ignore an received Content-Encoding header.
880  *
881  */
882  data->set.encoding = va_arg(param, char *);
883  if(data->set.encoding && !*data->set.encoding)
884  data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
885  break;
886 
887  case CURLOPT_HTTPAUTH:
888  /*
889  * Set HTTP Authentication type BITMASK.
890  */
891  {
892  long auth = va_arg(param, long);
893  /* switch off bits we can't support */
894 #ifndef USE_SSLEAY
895  auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
896 #endif
897 #ifndef HAVE_GSSAPI
898  auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
899 #endif
900  if(!auth)
901  return CURLE_FAILED_INIT; /* no supported types left! */
902 
903  data->set.httpauth = auth;
904  }
905  break;
906 
907  case CURLOPT_PROXYAUTH:
908  /*
909  * Set HTTP Authentication type BITMASK.
910  */
911  {
912  long auth = va_arg(param, long);
913  /* switch off bits we can't support */
914 #ifndef USE_SSLEAY
915  auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
916 #endif
917 #ifndef HAVE_GSSAPI
918  auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
919 #endif
920  if(!auth)
921  return CURLE_FAILED_INIT; /* no supported types left! */
922 
923  data->set.proxyauth = auth;
924  }
925  break;
926 
927  case CURLOPT_USERPWD:
928  /*
929  * user:password to use in the operation
930  */
931  data->set.userpwd = va_arg(param, char *);
932  break;
933  case CURLOPT_POSTQUOTE:
934  /*
935  * List of RAW FTP commands to use after a transfer
936  */
937  data->set.postquote = va_arg(param, struct curl_slist *);
938  break;
939  case CURLOPT_PREQUOTE:
940  /*
941  * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
942  */
943  data->set.prequote = va_arg(param, struct curl_slist *);
944  break;
945  case CURLOPT_QUOTE:
946  /*
947  * List of RAW FTP commands to use before a transfer
948  */
949  data->set.quote = va_arg(param, struct curl_slist *);
950  break;
951  case CURLOPT_PROGRESSFUNCTION:
952  /*
953  * Progress callback function
954  */
955  data->set.fprogress = va_arg(param, curl_progress_callback);
956  if(data->set.fprogress)
957  data->progress.callback = TRUE; /* no longer internal */
958  else
959  data->progress.callback = FALSE; /* NULL enforces internal */
960 
961  break;
962  case CURLOPT_PROGRESSDATA:
963  /*
964  * Custom client data to pass to the progress callback
965  */
966  data->set.progress_client = va_arg(param, void *);
967  break;
968  case CURLOPT_PROXYUSERPWD:
969  /*
970  * user:password needed to use the proxy
971  */
972  data->set.proxyuserpwd = va_arg(param, char *);
973  break;
974  case CURLOPT_RANGE:
975  /*
976  * What range of the file you want to transfer
977  */
978  data->set.set_range = va_arg(param, char *);
979  break;
980  case CURLOPT_RESUME_FROM:
981  /*
982  * Resume transfer at the give file position
983  */
984  data->set.set_resume_from = va_arg(param, long);
985  break;
986  case CURLOPT_RESUME_FROM_LARGE:
987  /*
988  * Resume transfer at the give file position
989  */
990  data->set.set_resume_from = va_arg(param, curl_off_t);
991  break;
992  case CURLOPT_DEBUGFUNCTION:
993  /*
994  * stderr write callback.
995  */
996  data->set.fdebug = va_arg(param, curl_debug_callback);
997  /*
998  * if the callback provided is NULL, it'll use the default callback
999  */
1000  break;
1001  case CURLOPT_DEBUGDATA:
1002  /*
1003  * Set to a void * that should receive all error writes. This
1004  * defaults to CURLOPT_STDERR for normal operations.
1005  */
1006  data->set.debugdata = va_arg(param, void *);
1007  break;
1008  case CURLOPT_STDERR:
1009  /*
1010  * Set to a FILE * that should receive all error writes. This
1011  * defaults to stderr for normal operations.
1012  */
1013  data->set.err = va_arg(param, FILE *);
1014  if(!data->set.err)
1015  data->set.err = stderr;
1016  break;
1017  case CURLOPT_HEADERFUNCTION:
1018  /*
1019  * Set header write callback
1020  */
1021  data->set.fwrite_header = va_arg(param, curl_write_callback);
1022  break;
1023  case CURLOPT_WRITEFUNCTION:
1024  /*
1025  * Set data write callback
1026  */
1027  data->set.fwrite = va_arg(param, curl_write_callback);
1028  if(!data->set.fwrite)
1029  /* When set to NULL, reset to our internal default function */
1031  break;
1032  case CURLOPT_READFUNCTION:
1033  /*
1034  * Read data callback
1035  */
1036  data->set.fread = va_arg(param, curl_read_callback);
1037  if(!data->set.fread)
1038  /* When set to NULL, reset to our internal default function */
1039  data->set.fread = (curl_read_callback)fread;
1040  break;
1041  case CURLOPT_SSLCERT:
1042  /*
1043  * String that holds file name of the SSL certificate to use
1044  */
1045  data->set.cert = va_arg(param, char *);
1046  break;
1047  case CURLOPT_SSLCERTTYPE:
1048  /*
1049  * String that holds file type of the SSL certificate to use
1050  */
1051  data->set.cert_type = va_arg(param, char *);
1052  break;
1053  case CURLOPT_SSLKEY:
1054  /*
1055  * String that holds file name of the SSL certificate to use
1056  */
1057  data->set.key = va_arg(param, char *);
1058  break;
1059  case CURLOPT_SSLKEYTYPE:
1060  /*
1061  * String that holds file type of the SSL certificate to use
1062  */
1063  data->set.key_type = va_arg(param, char *);
1064  break;
1065  case CURLOPT_SSLKEYPASSWD:
1066  /*
1067  * String that holds the SSL private key password.
1068  */
1069  data->set.key_passwd = va_arg(param, char *);
1070  break;
1071  case CURLOPT_SSLENGINE:
1072  /*
1073  * String that holds the SSL crypto engine.
1074  */
1075 #ifdef HAVE_OPENSSL_ENGINE_H
1076  {
1077  const char *cpTemp = va_arg(param, char *);
1078  ENGINE *e;
1079  if (cpTemp && cpTemp[0]) {
1080  e = ENGINE_by_id(cpTemp);
1081  if (e) {
1082  if (data->engine) {
1083  ENGINE_free(data->engine);
1084  }
1085  data->engine = e;
1086  }
1087  else {
1088  failf(data, "SSL Engine '%s' not found", cpTemp);
1090  }
1091  }
1092  }
1093  break;
1094 #else
1096 #endif
1097  case CURLOPT_SSLENGINE_DEFAULT:
1098  /*
1099  * flag to set engine as default.
1100  */
1101 #ifdef HAVE_OPENSSL_ENGINE_H
1102  if (data->engine) {
1103  if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) {
1104 #ifdef DEBUG
1105  fprintf(stderr,"set default crypto engine\n");
1106 #endif
1107  }
1108  else {
1109 #ifdef DEBUG
1110  failf(data, "set default crypto engine failed");
1111 #endif
1113  }
1114  }
1115 #endif
1116  break;
1117  case CURLOPT_CRLF:
1118  /*
1119  * Kludgy option to enable CRLF convertions. Subject for removal.
1120  */
1121  data->set.crlf = va_arg(param, long)?TRUE:FALSE;
1122  break;
1123  case CURLOPT_INTERFACE:
1124  /*
1125  * Set what interface to bind to when performing an operation and thus
1126  * what from-IP your connection will use.
1127  */
1128  data->set.device = va_arg(param, char *);
1129  break;
1130  case CURLOPT_KRB4LEVEL:
1131  /*
1132  * A string that defines the krb4 security level.
1133  */
1134  data->set.krb4_level = va_arg(param, char *);
1135  data->set.krb4=data->set.krb4_level?TRUE:FALSE;
1136  break;
1137  case CURLOPT_SSL_VERIFYPEER:
1138  /*
1139  * Enable peer SSL verifying.
1140  */
1141  data->set.ssl.verifypeer = va_arg(param, long);
1142  break;
1143  case CURLOPT_SSL_VERIFYHOST:
1144  /*
1145  * Enable verification of the CN contained in the peer certificate
1146  */
1147  data->set.ssl.verifyhost = va_arg(param, long);
1148  break;
1149  case CURLOPT_SSL_CTX_FUNCTION:
1150  /*
1151  * Set a SSL_CTX callback
1152  */
1153  data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1154  break;
1155  case CURLOPT_SSL_CTX_DATA:
1156  /*
1157  * Set a SSL_CTX callback parameter pointer
1158  */
1159  data->set.ssl.fsslctxp = va_arg(param, void *);
1160  break;
1161  case CURLOPT_CAINFO:
1162  /*
1163  * Set CA info for SSL connection. Specify file name of the CA certificate
1164  */
1165  data->set.ssl.CAfile = va_arg(param, char *);
1166  break;
1167  case CURLOPT_CAPATH:
1168  /*
1169  * Set CA path info for SSL connection. Specify directory name of the CA
1170  * certificates which have been prepared using openssl c_rehash utility.
1171  */
1172  /* This does not work on windows. */
1173  data->set.ssl.CApath = va_arg(param, char *);
1174  break;
1175  case CURLOPT_TELNETOPTIONS:
1176  /*
1177  * Set a linked list of telnet options
1178  */
1179  data->set.telnet_options = va_arg(param, struct curl_slist *);
1180  break;
1181 
1182  case CURLOPT_BUFFERSIZE:
1183  /*
1184  * The application kindly asks for a differently sized receive buffer.
1185  * If it seems reasonable, we'll use it.
1186  */
1187  data->set.buffer_size = va_arg(param, long);
1188 
1189  if((data->set.buffer_size> (BUFSIZE -1 )) ||
1190  (data->set.buffer_size < 1))
1191  data->set.buffer_size = 0; /* huge internal default */
1192 
1193  break;
1194 
1195  case CURLOPT_NOSIGNAL:
1196  /*
1197  * The application asks not to set any signal() or alarm() handlers,
1198  * even when using a timeout.
1199  */
1200  data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
1201  break;
1202 
1203  case CURLOPT_SHARE:
1204  {
1205  struct Curl_share *set;
1206  set = va_arg(param, struct Curl_share *);
1207 
1208  /* disconnect from old share, if any */
1209  if(data->share) {
1211 
1212  if(data->share->hostcache == data->hostcache)
1213  data->hostcache = NULL;
1214 
1215  if(data->share->cookies == data->cookies)
1216  data->cookies = NULL;
1217 
1218  data->share->dirty--;
1219 
1221  data->share = NULL;
1222  }
1223 
1224  /* use new share if it set */
1225  data->share = set;
1226  if(data->share) {
1227 
1229 
1230  data->share->dirty++;
1231 
1232  if(data->share->hostcache) {
1233  /* use shared host cache, first free own one if any */
1234  if(data->hostcache)
1236 
1237  data->hostcache = data->share->hostcache;
1238  }
1239 
1240  if(data->share->cookies) {
1241  /* use shared cookie list, first free own one if any */
1242  if (data->cookies)
1244  data->cookies = data->share->cookies;
1245  }
1246 
1248 
1249  }
1250 
1251  /* check cookie list is set */
1252  if(!data->cookies)
1253  data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1254 
1255  /* check for host cache not needed,
1256  * it will be done by curl_easy_perform */
1257  }
1258  break;
1259 
1260  case CURLOPT_PROXYTYPE:
1261  /*
1262  * Set proxy type. HTTP/SOCKS4/SOCKS5
1263  */
1264  data->set.proxytype = (curl_proxytype)va_arg(param, long);
1265  break;
1266 
1267  case CURLOPT_PRIVATE:
1268  /*
1269  * Set private data pointer.
1270  */
1271  data->set.private = va_arg(param, char *);
1272  break;
1273 
1274  case CURLOPT_HTTP200ALIASES:
1275  /*
1276  * Set a list of aliases for HTTP 200 in response header
1277  */
1278  data->set.http200aliases = va_arg(param, struct curl_slist *);
1279  break;
1280 
1281  case CURLOPT_MAXFILESIZE:
1282  /*
1283  * Set the maximum size of a file to download.
1284  */
1285  data->set.max_filesize = va_arg(param, long);
1286  break;
1287 
1288  case CURLOPT_FTP_SSL:
1289  /*
1290  * Make FTP transfers attempt to use SSL/TLS.
1291  */
1292  data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1293  break;
1294 
1295  case CURLOPT_IPRESOLVE:
1296  data->set.ip_version = va_arg(param, long);
1297  break;
1298 
1299  case CURLOPT_MAXFILESIZE_LARGE:
1300  /*
1301  * Set the maximum size of a file to download.
1302  */
1303  data->set.max_filesize = va_arg(param, curl_off_t);
1304  break;
1305 
1306  default:
1307  /* unknown tag and its companion, just ignore: */
1308  return CURLE_FAILED_INIT; /* correct this */
1309  }
1310  return CURLE_OK;
1311 }
1312 
1314 {
1315  if(!conn)
1316  return CURLE_OK; /* this is closed and fine already */
1317 
1318  /*
1319  * The range string is usually freed in curl_done(), but we might
1320  * get here *instead* if we fail prematurely. Thus we need to be able
1321  * to free this resource here as well.
1322  */
1323  if(conn->bits.rangestringalloc) {
1324  free(conn->range);
1325  conn->bits.rangestringalloc = FALSE;
1326  }
1327 
1328  if((conn->ntlm.state != NTLMSTATE_NONE) ||
1329  (conn->proxyntlm.state != NTLMSTATE_NONE))
1330  /* Authentication data is a mix of connection-related and sessionhandle-
1331  related stuff. NTLM is connection-related so when we close the shop
1332  we shall forget. */
1333  conn->data->state.authstage = 0;
1334 
1335  if(conn->curl_disconnect)
1336  /* This is set if protocol-specific cleanups should be made */
1337  conn->curl_disconnect(conn);
1338 
1339  if(-1 != conn->connectindex) {
1340  /* unlink ourselves! */
1341  infof(conn->data, "Closing connection #%d\n", conn->connectindex);
1342  conn->data->state.connects[conn->connectindex] = NULL;
1343  }
1344 
1345  Curl_safefree(conn->proto.generic);
1346  Curl_safefree(conn->newurl);
1347  Curl_safefree(conn->path); /* the URL path part */
1348  Curl_SSL_Close(conn);
1349 
1350  /* close possibly still open sockets */
1351  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1352  sclose(conn->sock[SECONDARYSOCKET]);
1353  if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1354  sclose(conn->sock[FIRSTSOCKET]);
1355 
1356  Curl_safefree(conn->user);
1357  Curl_safefree(conn->passwd);
1358  Curl_safefree(conn->proxyuser);
1359  Curl_safefree(conn->proxypasswd);
1361  Curl_safefree(conn->allocptr.uagent);
1365  Curl_safefree(conn->allocptr.ref);
1366  Curl_safefree(conn->allocptr.cookie);
1367  Curl_safefree(conn->allocptr.host);
1369  Curl_safefree(conn->proxyhost);
1370 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
1371  /* possible left-overs from the async name resolve */
1372  Curl_safefree(conn->async.hostname);
1373  Curl_safefree(conn->async.os_specific);
1374 #endif
1375 
1377 
1378  free(conn); /* free all the connection oriented data */
1379 
1380  return CURLE_OK;
1381 }
1382 
1383 /*
1384  * This function should return TRUE if the socket is to be assumed to
1385  * be dead. Most commonly this happens when the server has closed the
1386  * connection due to inactivity.
1387  */
1388 static bool SocketIsDead(curl_socket_t sock)
1389 {
1390  int sval;
1391  bool ret_val = TRUE;
1392  fd_set check_set;
1393  struct timeval to;
1394 
1395  FD_ZERO(&check_set);
1396  FD_SET(sock, &check_set);
1397 
1398  to.tv_sec = 0;
1399  to.tv_usec = 0;
1400 
1401  sval = select(sock + 1, &check_set, 0, 0, &to);
1402  if(sval == 0)
1403  /* timeout */
1404  ret_val = FALSE;
1405 
1406  return ret_val;
1407 }
1408 
1409 /*
1410  * Given one filled in connection struct (named needle), this function should
1411  * detect if there already is one that have all the significant details
1412  * exactly the same and thus should be used instead.
1413  */
1414 static bool
1415 ConnectionExists(struct SessionHandle *data,
1416  struct connectdata *needle,
1417  struct connectdata **usethis)
1418 {
1419  long i;
1420  struct connectdata *check;
1421 
1422  for(i=0; i< data->state.numconnects; i++) {
1423  bool match = FALSE;
1424  /*
1425  * Note that if we use a HTTP proxy, we check connections to that
1426  * proxy and not to the actual remote server.
1427  */
1428  check = data->state.connects[i];
1429  if(!check)
1430  /* NULL pointer means not filled-in entry */
1431  continue;
1432 
1433  if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
1434  /* don't do mixed SSL and non-SSL connections */
1435  continue;
1436 
1437  if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1438  /* The requested connection does not use a HTTP proxy or it
1439  uses SSL. */
1440 
1441  if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1442  /* we don't do SSL but the cached connection has a proxy,
1443  then don't match this */
1444  continue;
1445 
1446  if(strequal(needle->protostr, check->protostr) &&
1447  strequal(needle->name, check->name) &&
1448  (needle->remote_port == check->remote_port) ) {
1449  if(needle->protocol & PROT_SSL) {
1450  /* This is SSL, verify that we're using the same
1451  ssl options as well */
1452  if(!Curl_ssl_config_matches(&needle->ssl_config,
1453  &check->ssl_config)) {
1454  continue;
1455  }
1456  }
1457  if((needle->protocol & PROT_FTP) ||
1458  ((needle->protocol & PROT_HTTP) &&
1459  (needle->data->state.authwant==CURLAUTH_NTLM))) {
1460  /* This is FTP or HTTP+NTLM, verify that we're using the same name
1461  and password as well */
1462  if(!strequal(needle->user, check->user) ||
1463  !strequal(needle->passwd, check->passwd)) {
1464  /* one of them was different */
1465  continue;
1466  }
1467  }
1468  match = TRUE;
1469  }
1470  }
1471  else { /* The requested needle connection is using a proxy,
1472  is the checked one using the same? */
1473  if(check->bits.httpproxy &&
1474  strequal(needle->proxyhost, check->proxyhost) &&
1475  needle->port == check->port) {
1476  /* This is the same proxy connection, use it! */
1477  match = TRUE;
1478  }
1479  }
1480 
1481  if(match) {
1482  bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
1483  if(dead) {
1484  /*
1485  */
1486  infof(data, "Connection %d seems to be dead!\n", i);
1487  Curl_disconnect(check); /* disconnect resources */
1488  data->state.connects[i]=NULL; /* nothing here */
1489 
1490  /* There's no need to continue searching, because we only store
1491  one connection for each unique set of identifiers */
1492  return FALSE;
1493  }
1494 
1495  *usethis = check;
1496  return TRUE; /* yes, we found one to use! */
1497  }
1498  }
1499  return FALSE; /* no matching connecting exists */
1500 }
1501 
1502 /*
1503  * This function frees/closes a connection in the connection cache. This
1504  * should take the previously set policy into account when deciding which
1505  * of the connections to kill.
1506  */
1507 static int
1508 ConnectionKillOne(struct SessionHandle *data)
1509 {
1510  long i;
1511  struct connectdata *conn;
1512  int highscore=-1;
1513  int connindex=-1;
1514  int score;
1515  struct timeval now;
1516 
1517  now = Curl_tvnow();
1518 
1519  for(i=0; i< data->state.numconnects; i++) {
1520  conn = data->state.connects[i];
1521 
1522  if(!conn)
1523  continue;
1524 
1525  /*
1526  * By using the set policy, we score each connection.
1527  */
1528  switch(data->set.closepolicy) {
1530  default:
1531  /*
1532  * Set higher score for the age passed since the connection
1533  * was used.
1534  */
1535  score = Curl_tvdiff(now, conn->now);
1536  break;
1538  /*
1539  * Set higher score for the age passed since the connection
1540  * was created.
1541  */
1542  score = Curl_tvdiff(now, conn->created);
1543  break;
1544  }
1545 
1546  if(score > highscore) {
1547  highscore = score;
1548  connindex = i;
1549  }
1550  }
1551  if(connindex >= 0) {
1552 
1553  /* the winner gets the honour of being disconnected */
1554  (void) Curl_disconnect(data->state.connects[connindex]);
1555 
1556  /* clean the array entry */
1557  data->state.connects[connindex] = NULL;
1558  }
1559 
1560  return connindex; /* return the available index or -1 */
1561 }
1562 
1563 /*
1564  * The given input connection struct pointer is to be stored. If the "cache"
1565  * is already full, we must clean out the most suitable using the previously
1566  * set policy.
1567  *
1568  * The given connection should be unique. That must've been checked prior to
1569  * this call.
1570  */
1571 static unsigned int
1572 ConnectionStore(struct SessionHandle *data,
1573  struct connectdata *conn)
1574 {
1575  long i;
1576  for(i=0; i< data->state.numconnects; i++) {
1577  if(!data->state.connects[i])
1578  break;
1579  }
1580  if(i == data->state.numconnects) {
1581  /* there was no room available, kill one */
1582  i = ConnectionKillOne(data);
1583  infof(data, "Connection (#%d) was killed to make room\n", i);
1584  }
1585 
1586  if(-1 != i) {
1587  /* only do this if a true index was returned, if -1 was returned there
1588  is no room in the cache for an unknown reason and we cannot store
1589  this there. */
1590  data->state.connects[i] = conn; /* fill in this */
1591  conn->connectindex = i; /* make the child know where the pointer to this
1592  particular data is stored */
1593  }
1594  return i;
1595 }
1596 
1597 /*
1598  * This function logs in to a SOCKS5 proxy and sends the specifies the final
1599  * desitination server.
1600  */
1601 static int handleSock5Proxy(const char *proxy_name,
1602  const char *proxy_password,
1603  struct connectdata *conn)
1604 {
1605  /*
1606  According to the RFC1928, section "6. Replies". This is what a SOCK5
1607  replies:
1608 
1609  +----+-----+-------+------+----------+----------+
1610  |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
1611  +----+-----+-------+------+----------+----------+
1612  | 1 | 1 | X'00' | 1 | Variable | 2 |
1613  +----+-----+-------+------+----------+----------+
1614 
1615  Where:
1616 
1617  o VER protocol version: X'05'
1618  o REP Reply field:
1619  o X'00' succeeded
1620  */
1621 
1622  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
1623  ssize_t actualread;
1624  ssize_t written;
1625  int result;
1626  CURLcode code;
1627  int sock = conn->sock[FIRSTSOCKET];
1628 
1629  Curl_nonblock(sock, FALSE);
1630 
1631  socksreq[0] = 5; /* version */
1632  socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
1633  socksreq[2] = 0; /* no authentication */
1634  socksreq[3] = 2; /* username/password */
1635 
1636  code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
1637  &written);
1638  if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
1639  failf(conn->data, "Unable to send initial SOCKS5 request.");
1640  return 1;
1641  }
1642 
1643  result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1644  if ((result != CURLE_OK) || (actualread != 2)) {
1645  failf(conn->data, "Unable to receive initial SOCKS5 response.");
1646  return 1;
1647  }
1648 
1649  if (socksreq[0] != 5) {
1650  failf(conn->data, "Received invalid version in initial SOCKS5 response.");
1651  return 1;
1652  }
1653  if (socksreq[1] == 0) {
1654  /* Nothing to do, no authentication needed */
1655  ;
1656  }
1657  else if (socksreq[1] == 2) {
1658  /* Needs user name and password */
1659  int userlen, pwlen, len;
1660 
1661  userlen = strlen(proxy_name);
1662  pwlen = proxy_password?strlen(proxy_password):0;
1663 
1664  /* username/password request looks like
1665  * +----+------+----------+------+----------+
1666  * |VER | ULEN | UNAME | PLEN | PASSWD |
1667  * +----+------+----------+------+----------+
1668  * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
1669  * +----+------+----------+------+----------+
1670  */
1671  len = 0;
1672  socksreq[len++] = 1; /* username/pw subnegotiation version */
1673  socksreq[len++] = (char) userlen;
1674  memcpy(socksreq + len, proxy_name, (int) userlen);
1675  len += userlen;
1676  socksreq[len++] = (char) pwlen;
1677  memcpy(socksreq + len, proxy_password, (int) pwlen);
1678  len += pwlen;
1679 
1680  code = Curl_write(conn, sock, (char *)socksreq, len, &written);
1681  if ((code != CURLE_OK) || (len != written)) {
1682  failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
1683  return 1;
1684  }
1685 
1686  result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1687  if ((result != CURLE_OK) || (actualread != 2)) {
1688  failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
1689  return 1;
1690  }
1691 
1692  if ((socksreq[0] != 5) || /* version */
1693  (socksreq[1] != 0)) { /* status */
1694  failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
1695  socksreq[0], socksreq[1]);
1696  return 1;
1697  }
1698 
1699  /* Everything is good so far, user was authenticated! */
1700  }
1701  else {
1702  /* error */
1703  if (socksreq[1] == 1) {
1704  failf(conn->data,
1705  "SOCKS5 GSSAPI per-message authentication is not supported.");
1706  return 1;
1707  }
1708  else if (socksreq[1] == 255) {
1709  if (proxy_name[0] == 0) {
1710  failf(conn->data,
1711  "No authentication method was acceptable. (It is quite likely"
1712  " that the SOCKS5 server wanted a username/password, since none"
1713  " was supplied to the server on this connection.)");
1714  }
1715  else {
1716  failf(conn->data, "No authentication method was acceptable.");
1717  }
1718  return 1;
1719  }
1720  else {
1721  failf(conn->data,
1722  "Undocumented SOCKS5 mode attempted to be used by server.");
1723  return 1;
1724  }
1725  }
1726 
1727  /* Authentication is complete, now specify destination to the proxy */
1728  socksreq[0] = 5; /* version (SOCKS5) */
1729  socksreq[1] = 1; /* connect */
1730  socksreq[2] = 0; /* must be zero */
1731  socksreq[3] = 1; /* IPv4 = 1 */
1732 
1733  {
1734 #ifndef ENABLE_IPV6
1735  struct Curl_dns_entry *dns;
1736  Curl_addrinfo *hp=NULL;
1737  int rc = Curl_resolv(conn, conn->hostname, conn->remote_port, &dns);
1738 
1739  if(rc == -1)
1740  return 1;
1741 
1742  if(rc == 1)
1743  /* this requires that we're in "wait for resolve" state */
1744  rc = Curl_wait_for_resolv(conn, &dns);
1745 
1746  /*
1747  * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
1748  * returns a Curl_addrinfo pointer that may not always look the same.
1749  */
1750  if(dns)
1751  hp=dns->addr;
1752  if (hp && hp->h_addr_list[0]) {
1753  socksreq[4] = ((char*)hp->h_addr_list[0])[0];
1754  socksreq[5] = ((char*)hp->h_addr_list[0])[1];
1755  socksreq[6] = ((char*)hp->h_addr_list[0])[2];
1756  socksreq[7] = ((char*)hp->h_addr_list[0])[3];
1757 
1758  Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
1759  }
1760  else {
1761  failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
1762  conn->hostname);
1763  return 1;
1764  }
1765 #else
1766  failf(conn->data,
1767  "%s:%d has an internal error an needs to be fixed to work",
1768  __FILE__, __LINE__);
1769  return 1;
1770 #endif
1771  }
1772 
1773  *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
1774 
1775  {
1776  const int packetsize = 10;
1777 
1778  code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
1779  if ((code != CURLE_OK) || (written != packetsize)) {
1780  failf(conn->data, "Failed to send SOCKS5 connect request.");
1781  return 1;
1782  }
1783 
1784  result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
1785  if ((result != CURLE_OK) || (actualread != packetsize)) {
1786  failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
1787  return 1;
1788  }
1789 
1790  if (socksreq[0] != 5) { /* version */
1791  failf(conn->data,
1792  "SOCKS5 reply has wrong version, version should be 5.");
1793  return 1;
1794  }
1795  if (socksreq[1] != 0) { /* Anything besides 0 is an error */
1796  failf(conn->data,
1797  "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
1798  (unsigned char)socksreq[4], (unsigned char)socksreq[5],
1799  (unsigned char)socksreq[6], (unsigned char)socksreq[7],
1800  (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
1801  socksreq[1]);
1802  return 1;
1803  }
1804  }
1805 
1806  Curl_nonblock(sock, TRUE);
1807  return 0; /* Proxy was successful! */
1808 }
1809 
1810 static CURLcode ConnectPlease(struct connectdata *conn,
1811  struct Curl_dns_entry *hostaddr,
1812  bool *connected)
1813 {
1814  CURLcode result;
1816 
1817  /*************************************************************
1818  * Connect to server/proxy
1819  *************************************************************/
1820  result= Curl_connecthost(conn,
1821  hostaddr,
1822  conn->port,
1823  &conn->sock[FIRSTSOCKET],
1824  &addr,
1825  connected);
1826  if(CURLE_OK == result) {
1827  /* All is cool, then we store the current information from the hostaddr
1828  struct to the serv_addr, as it might be needed later. The address
1829  returned from the function above is crucial here. */
1830  conn->connect_addr = hostaddr;
1831 
1832 #ifdef ENABLE_IPV6
1833  conn->serv_addr = addr;
1834 #else
1835  memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
1836  memcpy((char *)&(conn->serv_addr.sin_addr),
1837  (struct in_addr *)addr, sizeof(struct in_addr));
1838  conn->serv_addr.sin_family = hostaddr->addr->h_addrtype;
1839  conn->serv_addr.sin_port = htons((unsigned short)conn->port);
1840 #endif
1841 
1842  if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
1843  return handleSock5Proxy(conn->proxyuser,
1844  conn->proxypasswd,
1845  conn) ?
1847  }
1848  else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
1849  /* do nothing here. handled later. */
1850  }
1851  else {
1852  failf(conn->data, "unknown proxytype option given");
1853  return CURLE_COULDNT_CONNECT;
1854  }
1855  }
1856 
1857  return result;
1858 }
1859 
1860 /*
1861  * ALERT! The 'dns' pointer being passed in here might be NULL at times.
1862  */
1863 static void verboseconnect(struct connectdata *conn,
1864  struct Curl_dns_entry *dns)
1865 {
1866  struct SessionHandle *data = conn->data;
1867 
1868  /* Figure out the ip-number and display the first host name it shows: */
1869 #ifdef ENABLE_IPV6
1870  {
1871  char hbuf[NI_MAXHOST];
1872 #ifdef NI_WITHSCOPEID
1873 #define NIFLAGS NI_NUMERICHOST | NI_WITHSCOPEID
1874 #else
1875 #define NIFLAGS NI_NUMERICHOST
1876 #endif
1877  if(dns) {
1878  struct addrinfo *ai = dns->addr;
1879 
1880  /* Lookup the name of the given address. This should probably be remade
1881  to use the DNS cache instead, as the host name is most likely cached
1882  already. */
1883  if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
1884  NIFLAGS)) {
1885  snprintf(hbuf, sizeof(hbuf), "unknown");
1886  }
1887  else {
1888  if (ai->ai_canonname) {
1889  infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf,
1890  conn->port);
1891  return;
1892  }
1893  }
1894  }
1895  else {
1896  snprintf(hbuf, sizeof(hbuf), "same host");
1897  }
1898 
1899  infof(data, "Connected to %s port %d\n", hbuf, conn->port);
1900  }
1901 #else
1902  {
1903 #ifdef HAVE_INET_NTOA_R
1904  char ntoa_buf[64];
1905 #endif
1906  Curl_addrinfo *hostaddr=dns?dns->addr:NULL;
1907  struct in_addr in;
1908  (void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
1909  infof(data, "Connected to %s (%s) port %d\n",
1910  hostaddr?hostaddr->h_name:"",
1911 #if defined(HAVE_INET_NTOA_R)
1912  inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),
1913 #else
1914  inet_ntoa(in),
1915 #endif
1916  conn->port);
1917  }
1918 #endif
1919 }
1920 
1921 /*
1922  * We have discovered that the TCP connection has been successful, we can now
1923  * proceed with some action.
1924  *
1925  * If we're using the multi interface, this host address pointer is most
1926  * likely NULL at this point as we can't keep the resolved info around. This
1927  * may call for some reworking, like a reference counter in the struct or
1928  * something. The hostaddr is not used for very much though, we have the
1929  * 'serv_addr' field in the connectdata struct for most of it.
1930  */
1932  struct Curl_dns_entry *hostaddr)
1933 {
1934  struct SessionHandle *data = conn->data;
1935  CURLcode result=CURLE_OK;
1936 
1937  if(conn->bits.tcpconnect)
1938  /* We already are connected, get back. This may happen when the connect
1939  worked fine in the first call, like when we connect to a local server
1940  or proxy. */
1941  return CURLE_OK;
1942 
1943  Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
1944 
1945  if(data->set.verbose)
1946  verboseconnect(conn, hostaddr);
1947 
1948  if(conn->curl_connect) {
1949  /* is there a protocol-specific connect() procedure? */
1950 
1951  /* set start time here for timeout purposes in the
1952  * connect procedure, it is later set again for the
1953  * progress meter purpose */
1954  conn->now = Curl_tvnow();
1955 
1956  /* Call the protocol-specific connect function */
1957  result = conn->curl_connect(conn);
1958  }
1959 
1960  return result; /* pass back status */
1961 }
1962 
1963 /*
1964  * CreateConnection() sets up a new connectdata struct, or re-uses an already
1965  * existing one, and resolves host name.
1966  *
1967  * if this function returns CURLE_OK and *async is set to TRUE, the resolve
1968  * response will be coming asynchronously. If *async is FALSE, the name is
1969  * already resolved.
1970  */
1971 
1972 static CURLcode CreateConnection(struct SessionHandle *data,
1973  struct connectdata **in_connect,
1974  struct Curl_dns_entry **addr,
1975  bool *async)
1976 {
1977  char *tmp;
1978  CURLcode result=CURLE_OK;
1979  char resumerange[40]="";
1980  struct connectdata *conn;
1981  struct connectdata *conn_temp;
1982  int urllen;
1983  struct Curl_dns_entry *hostaddr;
1984 #ifdef HAVE_ALARM
1985  unsigned int prev_alarm=0;
1986 #endif
1987  char endbracket;
1988  char user[MAX_CURL_USER_LENGTH];
1989  char passwd[MAX_CURL_PASSWORD_LENGTH];
1990  int rc;
1991  bool reuse;
1992 
1993 #ifdef HAVE_SIGACTION
1994  struct sigaction keep_sigact; /* store the old struct here */
1995  bool keep_copysig=FALSE; /* did copy it? */
1996 #else
1997 #ifdef HAVE_SIGNAL
1998  void *keep_sigact; /* store the old handler here */
1999 #endif
2000 #endif
2001 
2002  *addr = NULL; /* nothing yet */
2003  *async = FALSE;
2004 
2005  /*************************************************************
2006  * Check input data
2007  *************************************************************/
2008 
2009  if(!data->change.url)
2010  return CURLE_URL_MALFORMAT;
2011 
2012  /* First, split up the current URL in parts so that we can use the
2013  parts for checking against the already present connections. In order
2014  to not have to modify everything at once, we allocate a temporary
2015  connection data struct and fill in for comparison purposes. */
2016 
2017  conn = (struct connectdata *)malloc(sizeof(struct connectdata));
2018  if(!conn) {
2019  *in_connect = NULL; /* clear the pointer */
2020  return CURLE_OUT_OF_MEMORY;
2021  }
2022  /* We must set the return variable as soon as possible, so that our
2023  parent can cleanup any possible allocs we may have done before
2024  any failure */
2025  *in_connect = conn;
2026 
2027  /* we have to init the struct */
2028  memset(conn, 0, sizeof(struct connectdata));
2029 
2030  /* and we setup a few fields in case we end up actually using this struct */
2031  conn->data = data; /* remember our daddy */
2032  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2033  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2034  conn->connectindex = -1; /* no index */
2035  conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
2036  (data->set.proxytype == CURLPROXY_HTTP))?
2037  TRUE:FALSE; /* http proxy or not */
2038 
2039  /* Default protocol-independent behavior doesn't support persistant
2040  connections, so we set this to force-close. Protocols that support
2041  this need to set this to FALSE in their "curl_do" functions. */
2042  conn->bits.close = TRUE;
2043 
2044  /* maxdownload must be -1 on init, as 0 is a valid value! */
2045  conn->maxdownload = -1; /* might have been used previously! */
2046 
2047  /* Store creation time to help future close decision making */
2048  conn->created = Curl_tvnow();
2049 
2050  conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
2051  conn->range = data->set.set_range; /* clone the range setting */
2052  conn->resume_from = data->set.set_resume_from; /* inherite resume_from */
2053 
2054  /* Set the start time temporary to this creation time to allow easier
2055  timeout checks before the transfer has started for real. The start time
2056  is later set "for real" using Curl_pgrsStartNow(). */
2057  conn->data->progress.start = conn->created;
2058 
2059  conn->bits.user_passwd = data->set.userpwd?1:0;
2060  conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
2061 
2062  /* This initing continues below, see the comment "Continue connectdata
2063  * initialization here" */
2064 
2065  /***********************************************************
2066  * We need to allocate memory to store the path in. We get the size of the
2067  * full URL to be sure, and we need to make it at least 256 bytes since
2068  * other parts of the code will rely on this fact
2069  ***********************************************************/
2070 #define LEAST_PATH_ALLOC 256
2071  urllen=strlen(data->change.url);
2072  if(urllen < LEAST_PATH_ALLOC)
2073  urllen=LEAST_PATH_ALLOC;
2074 
2075  conn->path=(char *)malloc(urllen);
2076  if(NULL == conn->path)
2077  return CURLE_OUT_OF_MEMORY; /* really bad error */
2078 
2079  /*************************************************************
2080  * Parse the URL.
2081  *
2082  * We need to parse the url even when using the proxy, because we will need
2083  * the hostname and port in case we are trying to SSL connect through the
2084  * proxy -- and we don't know if we will need to use SSL until we parse the
2085  * url ...
2086  ************************************************************/
2087  if((2 == sscanf(data->change.url, "%64[^:]:%[^\n]",
2088  conn->protostr,
2089  conn->path)) && strequal(conn->protostr, "file")) {
2090  if(conn->path[0] == '/' && conn->path[1] == '/') {
2091  /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
2092  * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2093  * file://localhost/<path> is similar to how other schemes treat missing
2094  * hostnames. See RFC 1808. */
2095 
2096  /* This cannot be done with strcpy() in a portable manner, since the
2097  memory areas overlap! */
2098  memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1);
2099  }
2100  /*
2101  * we deal with file://<host>/<path> differently since it supports no
2102  * hostname other than "localhost" and "127.0.0.1", which is unique among
2103  * the URL protocols specified in RFC 1738
2104  */
2105  if(conn->path[0] != '/') {
2106  /* the URL included a host name, we ignore host names in file:// URLs
2107  as the standards don't define what to do with them */
2108  char *ptr=strchr(conn->path, '/');
2109  if(ptr) {
2110  /* there was a slash present
2111 
2112  RFC1738 (section 3.1, page 5) says:
2113 
2114  The rest of the locator consists of data specific to the scheme,
2115  and is known as the "url-path". It supplies the details of how the
2116  specified resource can be accessed. Note that the "/" between the
2117  host (or port) and the url-path is NOT part of the url-path.
2118 
2119  As most agents use file://localhost/foo to get '/foo' although the
2120  slash preceeding foo is a separator and not a slash for the path,
2121  a URL as file://localhost//foo must be valid as well, to refer to
2122  the same file with an absolute path.
2123  */
2124 
2125  if(ptr[1] && ('/' == ptr[1]))
2126  /* if there was two slashes, we skip the first one as that is then
2127  used truly as a separator */
2128  ptr++;
2129 
2130  /* This cannot be made with strcpy, as the memory chunks overlap! */
2131  memmove(conn->path, ptr, strlen(ptr)+1);
2132  }
2133  }
2134 
2135  strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2136  }
2137  else {
2138  /* Set default host and default path */
2139  strcpy(conn->gname, "curl.haxx.se");
2140  strcpy(conn->path, "/");
2141  /* We need to search for '/' OR '?' - whichever comes first after host
2142  * name but before the path. We need to change that to handle things like
2143  * http://example.com?param= (notice the missing '/'). Later we'll insert
2144  * that missing slash at the beginning of the path.
2145  */
2146  if (2 > sscanf(data->change.url,
2147  "%64[^\n:]://%512[^\n/?]%[^\n]",
2148  conn->protostr, conn->gname, conn->path)) {
2149 
2150  /*
2151  * The URL was badly formatted, let's try the browser-style _without_
2152  * protocol specified like 'http://'.
2153  */
2154  if((1 > sscanf(data->change.url, "%512[^\n/?]%[^\n]",
2155  conn->gname, conn->path)) ) {
2156  /*
2157  * We couldn't even get this format.
2158  */
2159  failf(data, "<url> malformed");
2160  return CURLE_URL_MALFORMAT;
2161  }
2162 
2163  /*
2164  * Since there was no protocol part specified, we guess what protocol it
2165  * is based on the first letters of the server name.
2166  */
2167 
2168  /* Note: if you add a new protocol, please update the list in
2169  * lib/version.c too! */
2170 
2171  if(checkprefix("GOPHER", conn->gname))
2172  strcpy(conn->protostr, "gopher");
2173 #ifdef USE_SSLEAY
2174  else if(checkprefix("HTTPS", conn->gname))
2175  strcpy(conn->protostr, "https");
2176  else if(checkprefix("FTPS", conn->gname))
2177  strcpy(conn->protostr, "ftps");
2178 #endif /* USE_SSLEAY */
2179  else if(checkprefix("FTP", conn->gname))
2180  strcpy(conn->protostr, "ftp");
2181  else if(checkprefix("TELNET", conn->gname))
2182  strcpy(conn->protostr, "telnet");
2183  else if (checkprefix("DICT", conn->gname))
2184  strcpy(conn->protostr, "DICT");
2185  else if (checkprefix("LDAP", conn->gname))
2186  strcpy(conn->protostr, "LDAP");
2187  else {
2188  strcpy(conn->protostr, "http");
2189  }
2190 
2191  conn->protocol |= PROT_MISSING; /* not given in URL */
2192  }
2193  }
2194 
2195  /* If the URL is malformatted (missing a '/' after hostname before path) we
2196  * insert a slash here. The only letter except '/' we accept to start a path
2197  * is '?'.
2198  */
2199  if(conn->path[0] == '?') {
2200  /* We need this function to deal with overlapping memory areas. We know
2201  that the memory area 'path' points to is 'urllen' bytes big and that
2202  is bigger than the path. Use +1 to move the zero byte too. */
2203  memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
2204  conn->path[0] = '/';
2205  }
2206 
2207  /*
2208  * So if the URL was A://B/C,
2209  * conn->protostr is A
2210  * conn->gname is B
2211  * conn->path is /C
2212  */
2213 
2214  /*************************************************************
2215  * Take care of proxy authentication stuff
2216  *************************************************************/
2217  if(conn->bits.proxy_user_passwd) {
2220 
2221  sscanf(data->set.proxyuserpwd,
2222  "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2223  "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2224  proxyuser, proxypasswd);
2225 
2226  conn->proxyuser = strdup(proxyuser);
2227  if(!conn->proxyuser)
2228  return CURLE_OUT_OF_MEMORY;
2229 
2230  conn->proxypasswd = strdup(proxypasswd);
2231  if(!conn->proxypasswd)
2232  return CURLE_OUT_OF_MEMORY;
2233  }
2234 
2235  /*************************************************************
2236  * Set a few convenience pointers
2237  *************************************************************/
2238  conn->name = conn->gname;
2239  conn->ppath = conn->path;
2240  conn->hostname = conn->name;
2241 
2242  /*************************************************************
2243  * Detect what (if any) proxy to use
2244  *************************************************************/
2245  if(!data->change.proxy) {
2246  /* If proxy was not specified, we check for default proxy environment
2247  * variables, to enable i.e Lynx compliance:
2248  *
2249  * http_proxy=http://some.server.dom:port/
2250  * https_proxy=http://some.server.dom:port/
2251  * ftp_proxy=http://some.server.dom:port/
2252  * gopher_proxy=http://some.server.dom:port/
2253  * no_proxy=domain1.dom,host.domain2.dom
2254  * (a comma-separated list of hosts which should
2255  * not be proxied, or an asterisk to override
2256  * all proxy variables)
2257  * all_proxy=http://some.server.dom:port/
2258  * (seems to exist for the CERN www lib. Probably
2259  * the first to check for.)
2260  *
2261  * For compatibility, the all-uppercase versions of these variables are
2262  * checked if the lowercase versions don't exist.
2263  */
2264  char *no_proxy=NULL;
2265  char *no_proxy_tok_buf;
2266  char *proxy=NULL;
2267  char proxy_env[128];
2268 
2269  no_proxy=curl_getenv("no_proxy");
2270  if(!no_proxy)
2271  no_proxy=curl_getenv("NO_PROXY");
2272 
2273  if(!no_proxy || !strequal("*", no_proxy)) {
2274  /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2275  char *nope;
2276 
2277  nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2278  while(nope) {
2279  unsigned int namelen;
2280  char *endptr = strchr(conn->name, ':');
2281  if(endptr)
2282  namelen=endptr-conn->name;
2283  else
2284  namelen=strlen(conn->name);
2285 
2286  if(strlen(nope) <= namelen) {
2287  char *checkn=
2288  conn->name + namelen - strlen(nope);
2289  if(checkprefix(nope, checkn)) {
2290  /* no proxy for this host! */
2291  break;
2292  }
2293  }
2294  nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2295  }
2296  if(!nope) {
2297  /* It was not listed as without proxy */
2298  char *protop = conn->protostr;
2299  char *envp = proxy_env;
2300  char *prox;
2301 
2302  /* Now, build <protocol>_proxy and check for such a one to use */
2303  while(*protop)
2304  *envp++ = tolower(*protop++);
2305 
2306  /* append _proxy */
2307  strcpy(envp, "_proxy");
2308 
2309  /* read the protocol proxy: */
2310  prox=curl_getenv(proxy_env);
2311 
2312  /*
2313  * We don't try the uppercase version of HTTP_PROXY because of
2314  * security reasons:
2315  *
2316  * When curl is used in a webserver application
2317  * environment (cgi or php), this environment variable can
2318  * be controlled by the web server user by setting the
2319  * http header 'Proxy:' to some value.
2320  *
2321  * This can cause 'internal' http/ftp requests to be
2322  * arbitrarily redirected by any external attacker.
2323  */
2324  if(!prox && !strequal("http_proxy", proxy_env)) {
2325  /* There was no lowercase variable, try the uppercase version: */
2326  for(envp = proxy_env; *envp; envp++)
2327  *envp = toupper(*envp);
2328  prox=curl_getenv(proxy_env);
2329  }
2330 
2331  if(prox && *prox) { /* don't count "" strings */
2332  proxy = prox; /* use this */
2333  }
2334  else {
2335  proxy = curl_getenv("all_proxy"); /* default proxy to use */
2336  if(!proxy)
2337  proxy=curl_getenv("ALL_PROXY");
2338  }
2339 
2340  if(proxy && *proxy) {
2341  /* we have a proxy here to set */
2342  char *ptr;
2343  char proxyuser[MAX_CURL_USER_LENGTH];
2344  char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
2345 
2346  /* skip the possible protocol piece */
2347  ptr=strstr(proxy, "://");
2348  if(ptr)
2349  ptr += 3;
2350  else
2351  ptr = proxy;
2352 
2353  /* check for an @-letter */
2354  ptr = strchr(ptr, '@');
2355  if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
2356  "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
2357  proxyuser, proxypasswd))) {
2358  /* found user and password, rip them out */
2359  Curl_safefree(conn->proxyuser);
2360  conn->proxyuser = strdup(proxyuser);
2361 
2362  if(!conn->proxyuser)
2363  return CURLE_OUT_OF_MEMORY;
2364 
2365  Curl_safefree(conn->proxypasswd);
2366  conn->proxypasswd = strdup(proxypasswd);
2367 
2368  if(!conn->proxypasswd)
2369  return CURLE_OUT_OF_MEMORY;
2370 
2371  conn->bits.proxy_user_passwd = TRUE; /* enable it */
2372 
2373  ptr = strdup(ptr+1);
2374  free(proxy); /* free the former data */
2375  proxy = ptr; /* now use this instead */
2376  }
2377 
2378 
2379  data->change.proxy = proxy;
2380  data->change.proxy_alloc=TRUE; /* this needs to be freed later */
2381  conn->bits.httpproxy = TRUE;
2382  }
2383  } /* if (!nope) - it wasn't specified non-proxy */
2384  } /* NO_PROXY wasn't specified or '*' */
2385  if(no_proxy)
2386  free(no_proxy);
2387  } /* if not using proxy */
2388 
2389  /*************************************************************
2390  * No protocol part in URL was used, add it!
2391  *************************************************************/
2392  if(conn->protocol&PROT_MISSING) {
2393  /* We're guessing prefixes here and if we're told to use a proxy or if
2394  we're gonna follow a Location: later or... then we need the protocol
2395  part added so that we have a valid URL. */
2396  char *reurl;
2397 
2398  reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2399 
2400  if(!reurl)
2401  return CURLE_OUT_OF_MEMORY;
2402 
2403  data->change.url = reurl;
2404  data->change.url_alloc = TRUE; /* free this later */
2405  conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2406  }
2407 
2408 #ifndef CURL_DISABLE_HTTP
2409  /************************************************************
2410  * RESUME on a HTTP page is a tricky business. First, let's just check that
2411  * 'range' isn't used, then set the range parameter and leave the resume as
2412  * it is to inform about this situation for later use. We will then
2413  * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2414  * server, we will get the document resumed. If we talk to a HTTP/1.0
2415  * server, we just fail since we can't rewind the file writing from within
2416  * this function.
2417  ***********************************************************/
2418  if(conn->resume_from) {
2419  if(!conn->bits.use_range) {
2420  /* if it already was in use, we just skip this */
2421  snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-",
2422  conn->resume_from);
2423  conn->range=strdup(resumerange); /* tell ourselves to fetch this range */
2424  conn->bits.rangestringalloc = TRUE; /* mark as allocated */
2425  conn->bits.use_range = 1; /* switch on range usage */
2426  }
2427  }
2428 #endif
2429  /*************************************************************
2430  * Setup internals depending on protocol
2431  *************************************************************/
2432 
2433  if (strequal(conn->protostr, "HTTP")) {
2434 #ifndef CURL_DISABLE_HTTP
2435  conn->port = (data->set.use_port && data->state.allow_port)?
2436  data->set.use_port:PORT_HTTP;
2437  conn->remote_port = PORT_HTTP;
2438  conn->protocol |= PROT_HTTP;
2439  conn->curl_do = Curl_http;
2440  conn->curl_do_more = NULL;
2441  conn->curl_done = Curl_http_done;
2443 #else
2444  failf(data, LIBCURL_NAME
2445  " was built with HTTP disabled, http: not supported!");
2447 #endif
2448  }
2449  else if (strequal(conn->protostr, "HTTPS")) {
2450 #if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
2451 
2452  conn->port = (data->set.use_port && data->state.allow_port)?
2453  data->set.use_port:PORT_HTTPS;
2454  conn->remote_port = PORT_HTTPS;
2456 
2457  conn->curl_do = Curl_http;
2458  conn->curl_do_more = NULL;
2459  conn->curl_done = Curl_http_done;
2461 
2462 #else /* USE_SSLEAY */
2463  failf(data, LIBCURL_NAME
2464  " was built with SSL disabled, https: not supported!");
2466 #endif /* !USE_SSLEAY */
2467  }
2468  else if (strequal(conn->protostr, "GOPHER")) {
2469 #ifndef CURL_DISABLE_GOPHER
2470  conn->port = (data->set.use_port && data->state.allow_port)?
2471  data->set.use_port:PORT_GOPHER;
2472  conn->remote_port = PORT_GOPHER;
2473  /* Skip /<item-type>/ in path if present */
2474  if (isdigit((int)conn->path[1])) {
2475  conn->ppath = strchr(&conn->path[1], '/');
2476  if (conn->ppath == NULL)
2477  conn->ppath = conn->path;
2478  }
2479  conn->protocol |= PROT_GOPHER;
2480  conn->curl_do = Curl_http;
2481  conn->curl_do_more = NULL;
2482  conn->curl_done = Curl_http_done;
2483 #else
2484  failf(data, LIBCURL_NAME
2485  " was built with GOPHER disabled, gopher: not supported!");
2486 #endif
2487  }
2488  else if(strequal(conn->protostr, "FTP") ||
2489  strequal(conn->protostr, "FTPS")) {
2490 
2491 /* MN 06/07/02 */
2492 #ifndef CURL_DISABLE_FTP
2493  char *type;
2494  int port = PORT_FTP;
2495 
2496  if(strequal(conn->protostr, "FTPS")) {
2497 #ifdef USE_SSLEAY
2498  conn->protocol |= PROT_FTPS|PROT_SSL;
2499  conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
2500  port = PORT_FTPS;
2501 #else
2502  failf(data, LIBCURL_NAME
2503  " was built with SSL disabled, ftps: not supported!");
2505 #endif /* !USE_SSLEAY */
2506  }
2507 
2508  conn->port = (data->set.use_port && data->state.allow_port)?
2509  data->set.use_port:port;
2510  conn->remote_port = port;
2511  conn->protocol |= PROT_FTP;
2512 
2513  if(data->change.proxy &&
2514  *data->change.proxy &&
2515  !data->set.tunnel_thru_httpproxy) {
2516  /* Unless we have asked to tunnel ftp operations through the proxy, we
2517  switch and use HTTP operations only */
2518  if(conn->protocol & PROT_FTPS) {
2519  /* FTPS is a hacked protocol and does not work through your
2520  ordinary http proxy! */
2521  failf(data, "ftps does not work through http proxy!");
2523  }
2524 #ifndef CURL_DISABLE_HTTP
2525  conn->curl_do = Curl_http;
2526  conn->curl_done = Curl_http_done;
2527 #else
2528  failf(data, "FTP over http proxy requires HTTP support built-in!");
2530 #endif
2531  }
2532  else {
2533  conn->curl_do = Curl_ftp;
2535  conn->curl_done = Curl_ftp_done;
2538  }
2539 
2540  conn->ppath++; /* don't include the initial slash */
2541 
2542  /* FTP URLs support an extension like ";type=<typecode>" that
2543  * we'll try to get now! */
2544  type=strstr(conn->ppath, ";type=");
2545  if(!type) {
2546  type=strstr(conn->gname, ";type=");
2547  }
2548  if(type) {
2549  char command;
2550  *type=0; /* it was in the middle of the hostname */
2551  command = toupper(type[6]);
2552  switch(command) {
2553  case 'A': /* ASCII mode */
2554  data->set.ftp_ascii = 1;
2555  break;
2556  case 'D': /* directory mode */
2557  data->set.ftp_list_only = 1;
2558  break;
2559  case 'I': /* binary mode */
2560  default:
2561  /* switch off ASCII */
2562  data->set.ftp_ascii = 0;
2563  break;
2564  }
2565  }
2566 
2567 /* MN 06/07/02 */
2568 #else /* CURL_DISABLE_FTP */
2569  failf(data, LIBCURL_NAME
2570  " was built with FTP disabled, ftp/ftps: not supported!");
2572 #endif
2573  }
2574  else if(strequal(conn->protostr, "TELNET")) {
2575 #ifndef CURL_DISABLE_TELNET
2576  /* telnet testing factory */
2577  conn->protocol |= PROT_TELNET;
2578 
2579  conn->port = (data->set.use_port && data->state.allow_port)?
2580  data->set.use_port: PORT_TELNET;
2581  conn->remote_port = PORT_TELNET;
2582  conn->curl_do = Curl_telnet;
2583  conn->curl_done = Curl_telnet_done;
2584 #else
2585  failf(data, LIBCURL_NAME
2586  " was built with TELNET disabled!");
2587 #endif
2588  }
2589  else if (strequal(conn->protostr, "DICT")) {
2590 #ifndef CURL_DISABLE_DICT
2591  conn->protocol |= PROT_DICT;
2592  conn->port = (data->set.use_port && data->state.allow_port)?
2593  data->set.use_port:PORT_DICT;
2594  conn->remote_port = PORT_DICT;
2595  conn->curl_do = Curl_dict;
2596  conn->curl_done = NULL; /* no DICT-specific done */
2597 #else
2598  failf(data, LIBCURL_NAME
2599  " was built with DICT disabled!");
2600 #endif
2601  }
2602  else if (strequal(conn->protostr, "LDAP")) {
2603 #ifndef CURL_DISABLE_LDAP
2604  conn->protocol |= PROT_LDAP;
2605  conn->port = (data->set.use_port && data->state.allow_port)?
2606  data->set.use_port:PORT_LDAP;
2607  conn->remote_port = PORT_LDAP;
2608  conn->curl_do = Curl_ldap;
2609  conn->curl_done = NULL; /* no LDAP-specific done */
2610 #else
2611  failf(data, LIBCURL_NAME
2612  " was built with LDAP disabled!");
2613 #endif
2614  }
2615  else if (strequal(conn->protostr, "FILE")) {
2616 #ifndef CURL_DISABLE_FILE
2617  conn->protocol |= PROT_FILE;
2618 
2619  conn->curl_do = Curl_file;
2620  /* no done() function */
2621 
2622  /* anyway, this is supposed to be the connect function so we better
2623  at least check that the file is present here! */
2624  result = Curl_file_connect(conn);
2625 
2626  /* Setup a "faked" transfer that'll do nothing */
2627  if(CURLE_OK == result) {
2628  conn->bits.tcpconnect = TRUE; /* we are "connected */
2629  result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
2630  -1, NULL); /* no upload */
2631  }
2632 
2633  return result;
2634 #else
2635  failf(data, LIBCURL_NAME
2636  " was built with FILE disabled!");
2637 #endif
2638  }
2639  else {
2640  /* We fell through all checks and thus we don't support the specified
2641  protocol */
2642  failf(data, "Unsupported protocol: %s", conn->protostr);
2644  }
2645 
2646  /*************************************************************
2647  * Figure out the remote port number
2648  *
2649  * No matter if we use a proxy or not, we have to figure out the remote
2650  * port number of various reasons.
2651  *
2652  * To be able to detect port number flawlessly, we must not confuse them
2653  * IPv6-specified addresses in the [0::1] style. (RFC2732)
2654  *
2655  * The conn->name is currently [user:passwd@]host[:port] where host could
2656  * be a hostname, IPv4 address or IPv6 address.
2657  *************************************************************/
2658  if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
2659  (']' == endbracket)) {
2660  /* this is a RFC2732-style specified IP-address */
2661  conn->bits.ipv6_ip = TRUE;
2662 
2663  conn->name++; /* pass the starting bracket */
2664  conn->hostname++;
2665  tmp = strchr(conn->name, ']');
2666  *tmp = 0; /* zero terminate */
2667  tmp++; /* pass the ending bracket */
2668  if(':' != *tmp)
2669  tmp = NULL; /* no port number available */
2670  }
2671  else
2672  tmp = strrchr(conn->name, ':');
2673 
2674  if (tmp) {
2675  char *rest;
2676  unsigned long port;
2677 
2678  port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
2679 
2680  if (rest != (tmp+1) && *rest == '\0') {
2681  /* The colon really did have only digits after it,
2682  * so it is either a port number or a mistake */
2683 
2684  if (port > 0xffff) { /* Single unix standard says port numbers are
2685  * 16 bits long */
2686  failf(data, "Port number too large: %lu", port);
2687  return CURLE_URL_MALFORMAT;
2688  }
2689 
2690  *tmp = '\0'; /* cut off the name there */
2691  conn->remote_port = (unsigned short)port;
2692  }
2693  }
2694 
2695  if(data->change.proxy && *data->change.proxy) {
2696  /* If this is supposed to use a proxy, we need to figure out the proxy
2697  host name name, so that we can re-use an existing connection
2698  that may exist registered to the same proxy host. */
2699 
2700  char *prox_portno;
2701  char *endofprot;
2702 
2703  /* We need to make a duplicate of the proxy so that we can modify the
2704  string safely. */
2705  char *proxydup=strdup(data->change.proxy);
2706 
2707  /* We use 'proxyptr' to point to the proxy name from now on... */
2708  char *proxyptr=proxydup;
2709 
2710  if(NULL == proxydup) {
2711  failf(data, "memory shortage");
2712  return CURLE_OUT_OF_MEMORY;
2713  }
2714 
2715  /* Daniel Dec 10, 1998:
2716  We do the proxy host string parsing here. We want the host name and the
2717  port name. Accept a protocol:// prefix, even though it should just be
2718  ignored. */
2719 
2720  /* 1. skip the protocol part if present */
2721  endofprot=strstr(proxyptr, "://");
2722  if(endofprot) {
2723  proxyptr = endofprot+3;
2724  }
2725 
2726  /* allow user to specify proxy.server.com:1080 if desired */
2727  prox_portno = strchr (proxyptr, ':');
2728  if (prox_portno) {
2729  *prox_portno = 0x0; /* cut off number from host name */
2730  prox_portno ++;
2731  /* now set the local port number */
2732  conn->port = atoi(prox_portno);
2733  }
2734  else if(data->set.proxyport) {
2735  /* None given in the proxy string, then get the default one if it is
2736  given */
2737  conn->port = data->set.proxyport;
2738  }
2739 
2740  /* now, clone the cleaned proxy host name */
2741  conn->proxyhost = strdup(proxyptr);
2742 
2743  free(proxydup); /* free the duplicate pointer and not the modified */
2744  }
2745 
2746  /*************************************************************
2747  * Take care of user and password authentication stuff
2748  *************************************************************/
2749 
2750  /*
2751  * Inputs: data->set.userpwd (CURLOPT_USERPWD)
2752  * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
2753  * data->set.use_netrc (CURLOPT_NETRC)
2754  * conn->hostname
2755  * netrc file
2756  * hard-coded defaults
2757  *
2758  * Outputs: (almost :- all currently undefined)
2759  * conn->bits.user_passwd - non-zero if non-default passwords exist
2760  * conn->user - non-zero length if defined
2761  * conn->passwd - ditto
2762  * conn->hostname - remove user name and password
2763  */
2764 
2765  /* At this point, we're hoping all the other special cases have
2766  * been taken care of, so conn->hostname is at most
2767  * [user[:password]]@]hostname
2768  *
2769  * We need somewhere to put the embedded details, so do that first.
2770  */
2771 
2772  user[0] =0; /* to make everything well-defined */
2773  passwd[0]=0;
2774 
2775  if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
2776  /* This is a FTP or HTTP URL, we will now try to extract the possible
2777  * user+password pair in a string like:
2778  * ftp://user:password@ftp.my.site:8021/README */
2779  char *ptr=strchr(conn->name, '@');
2780  char *userpass = conn->name;
2781  if(ptr != NULL) {
2782  /* there's a user+password given here, to the left of the @ */
2783 
2784  conn->name = conn->hostname = ++ptr;
2785 
2786  /* So the hostname is sane. Only bother interpreting the
2787  * results if we could care. It could still be wasted
2788  * work because it might be overtaken by the programmatically
2789  * set user/passwd, but doing that first adds more cases here :-(
2790  */
2791 
2792  if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
2793  /* We could use the one in the URL */
2794 
2795  conn->bits.user_passwd = 1; /* enable user+password */
2796 
2797  if(*userpass != ':') {
2798  /* the name is given, get user+password */
2799  sscanf(userpass, "%127[^:@]:%127[^@]",
2800  user, passwd);
2801  }
2802  else
2803  /* no name given, get the password only */
2804  sscanf(userpass, ":%127[^@]", passwd);
2805 
2806  if(user[0]) {
2807  char *newname=curl_unescape(user, 0);
2808  if(strlen(newname) < sizeof(user)) {
2809  strcpy(user, newname);
2810  }
2811  /* if the new name is longer than accepted, then just use
2812  the unconverted name, it'll be wrong but what the heck */
2813  free(newname);
2814  }
2815  if (passwd[0]) {
2816  /* we have a password found in the URL, decode it! */
2817  char *newpasswd=curl_unescape(passwd, 0);
2818  if(strlen(newpasswd) < sizeof(passwd)) {
2819  strcpy(passwd, newpasswd);
2820  }
2821  free(newpasswd);
2822  }
2823  }
2824  }
2825  }
2826 
2827  /* Programmatically set password:
2828  * - always applies, if available
2829  * - takes precedence over the values we just set above
2830  * so scribble it over the top.
2831  * User-supplied passwords are assumed not to need unescaping.
2832  *
2833  * user_password is set in "inherite initial knowledge' above,
2834  * so it doesn't have to be set in this block
2835  */
2836  if (data->set.userpwd != NULL) {
2837  /* the name is given, get user+password */
2838  sscanf(data->set.userpwd,
2839  "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2840  "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2841  user, passwd);
2842  }
2843 
2844  if (data->set.use_netrc != CURL_NETRC_IGNORED) {
2845  if(Curl_parsenetrc(conn->hostname,
2846  user, passwd,
2847  data->set.netrc_file)) {
2848  infof(data, "Couldn't find host %s in the .netrc file, using defaults\n",
2849  conn->hostname);
2850  }
2851  else
2852  conn->bits.user_passwd = 1; /* enable user+password */
2853  }
2854 
2855  /* If our protocol needs a password and we have none, use the defaults */
2856  if ( (conn->protocol & PROT_FTP) &&
2857  !conn->bits.user_passwd) {
2858 
2859  conn->user = strdup(CURL_DEFAULT_USER);
2861 
2862  /* This is the default password, so DON'T set conn->bits.user_passwd */
2863  }
2864  else {
2865  /* store user + password, zero-length if not set */
2866  conn->user = strdup(user);
2867  conn->passwd = strdup(passwd);
2868  }
2869 
2870  /*************************************************************
2871  * Check the current list of connections to see if we can
2872  * re-use an already existing one or if we have to create a
2873  * new one.
2874  *************************************************************/
2875 
2876  /* get a cloned copy of the SSL config situation stored in the
2877  connection struct */
2878  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
2879  return CURLE_OUT_OF_MEMORY;
2880 
2881  /* reuse_fresh is TRUE if we are told to use a new connection by force, but
2882  we only acknowledge this option if this is not a re-used connection
2883  already (which happens due to follow-location or during a HTTP
2884  authentication phase). */
2885  if(data->set.reuse_fresh && !data->state.this_is_a_follow)
2886  reuse = FALSE;
2887  else
2888  reuse = ConnectionExists(data, conn, &conn_temp);
2889 
2890  if(reuse) {
2891  /*
2892  * We already have a connection for this, we got the former connection
2893  * in the conn_temp variable and thus we need to cleanup the one we
2894  * just allocated before we can move along and use the previously
2895  * existing one.
2896  */
2897  struct connectdata *old_conn = conn;
2898  char *path = old_conn->path; /* setup the current path pointer properly */
2899  char *ppath = old_conn->ppath; /* this is the modified path pointer */
2900  if(old_conn->proxyhost)
2901  free(old_conn->proxyhost);
2902 
2903  /* free the SSL config struct from this connection struct as this was
2904  allocated in vain and is targeted for destruction */
2906 
2907  conn = conn_temp; /* use this connection from now on */
2908 
2909  /* get the user+password information from the old_conn struct since it may
2910  * be new for this request even when we re-use an existing connection */
2911  conn->bits.user_passwd = old_conn->bits.user_passwd;
2912  conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
2913 
2914  /* If we speak over a proxy, we need to copy the host name too, as it
2915  might be another remote host even when re-using a connection */
2916  strcpy(conn->gname, old_conn->gname); /* safe strcpy() */
2917 
2918  /* we need these pointers if we speak over a proxy */
2919  conn->hostname = conn->gname;
2920  conn->name = &conn->gname[old_conn->name - old_conn->gname];
2921 
2922  free(conn->path); /* free the previously allocated path pointer */
2923 
2924  /* 'path' points to the allocated data, 'ppath' may have been advanced
2925  to point somewhere within the 'path' area. */
2926  conn->path = path;
2927  conn->ppath = ppath;
2928 
2929  /* re-use init */
2930  conn->bits.reuse = TRUE; /* yes, we're re-using here */
2931  conn->bits.chunk = FALSE; /* always assume not chunked unless told
2932  otherwise */
2933  conn->maxdownload = -1; /* might have been used previously! */
2934 
2935  Curl_safefree(old_conn->user);
2936  Curl_safefree(old_conn->passwd);
2937  Curl_safefree(old_conn->proxyuser);
2938  Curl_safefree(old_conn->proxypasswd);
2939 
2940  if(old_conn->bits.rangestringalloc)
2941  free(old_conn->range);
2942 
2943  free(old_conn); /* we don't need this anymore */
2944 
2945  /*
2946  * If we're doing a resumed transfer, we need to setup our stuff
2947  * properly.
2948  */
2949  conn->resume_from = data->set.set_resume_from;
2950  if (conn->resume_from) {
2951  snprintf(resumerange, sizeof(resumerange), "%" FORMAT_OFF_T "-",
2952  conn->resume_from);
2953  if (conn->bits.rangestringalloc == TRUE)
2954  free(conn->range);
2955 
2956  /* tell ourselves to fetch this range */
2957  conn->range = strdup(resumerange);
2958  conn->bits.use_range = TRUE; /* enable range download */
2959  conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
2960  }
2961  else if (data->set.set_range) {
2962  /* There is a range, but is not a resume, useful for random ftp access */
2963  conn->range = strdup(data->set.set_range);
2964  conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
2965  conn->bits.use_range = TRUE; /* enable range download */
2966  }
2967  else
2968  conn->bits.use_range = FALSE; /* disable range download */
2969 
2970  *in_connect = conn; /* return this instead! */
2971 
2972  infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
2973  }
2974  else {
2975  /*
2976  * This is a brand new connection, so let's store it in the connection
2977  * cache of ours!
2978  */
2979  ConnectionStore(data, conn);
2980  }
2981 
2982  /* Continue connectdata initialization here.
2983  *
2984  * Inherit the proper values from the urldata struct AFTER we have arranged
2985  * the persistant conncetion stuff */
2986  conn->fread = data->set.fread;
2987  conn->fread_in = data->set.in;
2988 
2989  conn->bits.upload_chunky =
2990  ((conn->protocol&PROT_HTTP) &&
2991  data->set.upload &&
2992  (data->set.infilesize == -1) &&
2994  /* HTTP, upload, unknown file size and not HTTP 1.0 */
2995  TRUE:
2996  /* else, no chunky upload */
2997  FALSE;
2998 
2999 #ifndef USE_ARES
3000  /*************************************************************
3001  * Set timeout if that is being used, and we're not using an asynchronous
3002  * name resolve.
3003  *************************************************************/
3004  if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3005  /*************************************************************
3006  * Set signal handler to catch SIGALRM
3007  * Store the old value to be able to set it back later!
3008  *************************************************************/
3009 
3010 #ifdef SIGALRM
3011 #ifdef HAVE_SIGACTION
3012  struct sigaction sigact;
3013  sigaction(SIGALRM, NULL, &sigact);
3014  keep_sigact = sigact;
3015  keep_copysig = TRUE; /* yes, we have a copy */
3016  sigact.sa_handler = alarmfunc;
3017 #ifdef SA_RESTART
3018  /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3019  sigact.sa_flags &= ~SA_RESTART;
3020 #endif
3021  /* now set the new struct */
3022  sigaction(SIGALRM, &sigact, NULL);
3023 #else /* HAVE_SIGACTION */
3024  /* no sigaction(), revert to the much lamer signal() */
3025 #ifdef HAVE_SIGNAL
3026  keep_sigact = signal(SIGALRM, alarmfunc);
3027 #endif
3028 #endif /* HAVE_SIGACTION */
3029 
3030  /* We set the timeout on the name resolving phase first, separately from
3031  * the download/upload part to allow a maximum time on everything. This is
3032  * a signal-based timeout, why it won't work and shouldn't be used in
3033  * multi-threaded environments. */
3034 
3035 #ifdef HAVE_ALARM
3036  /* alarm() makes a signal get sent when the timeout fires off, and that
3037  will abort system calls */
3038  prev_alarm = alarm(data->set.connecttimeout?
3039  data->set.connecttimeout:
3040  data->set.timeout);
3041  /* We can expect the conn->created time to be "now", as that was just
3042  recently set in the beginning of this function and nothing slow
3043  has been done since then until now. */
3044 #endif
3045 #endif /* SIGALRM */
3046  }
3047 #endif /* USE_ARES */
3048 
3049  /*************************************************************
3050  * Resolve the name of the server or proxy
3051  *************************************************************/
3052  if(conn->bits.reuse) {
3053  /* re-used connection, no resolving is necessary */
3054  hostaddr = NULL;
3055  conn->connect_addr = NULL; /* we don't connect now so we don't have any
3056  fresh connect_addr struct to point to */
3057  }
3058  else if(!data->change.proxy || !*data->change.proxy) {
3059  /* If not connecting via a proxy, extract the port from the URL, if it is
3060  * there, thus overriding any defaults that might have been set above. */
3061  conn->port = conn->remote_port; /* it is the same port */
3062 
3063  /* Resolve target host right on */
3064  rc = Curl_resolv(conn, conn->name, conn->port, &hostaddr);
3065  if(rc == 1)
3066  *async = TRUE;
3067 
3068  else if(!hostaddr) {
3069  failf(data, "Couldn't resolve host '%s'", conn->name);
3070  result = CURLE_COULDNT_RESOLVE_HOST;
3071  /* don't return yet, we need to clean up the timeout first */
3072  }
3073  }
3074  else {
3075  /* This is a proxy that hasn't been resolved yet. */
3076 
3077  /* resolve proxy */
3078  rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr);
3079 
3080  if(rc == 1)
3081  *async = TRUE;
3082 
3083  else if(!hostaddr) {
3084  failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
3085  result = CURLE_COULDNT_RESOLVE_PROXY;
3086  /* don't return yet, we need to clean up the timeout first */
3087  }
3088  }
3089  *addr = hostaddr;
3090 
3091 #if defined(HAVE_ALARM) && defined(SIGALRM)
3092  if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3093 #ifdef HAVE_SIGACTION
3094  if(keep_copysig) {
3095  /* we got a struct as it looked before, now put that one back nice
3096  and clean */
3097  sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3098  }
3099 #else
3100 #ifdef HAVE_SIGNAL
3101  /* restore the previous SIGALRM handler */
3102  signal(SIGALRM, keep_sigact);
3103 #endif
3104 #endif /* HAVE_SIGACTION */
3105 
3106  /* switch back the alarm() to either zero or to what it was before minus
3107  the time we spent until now! */
3108  if(prev_alarm) {
3109  /* there was an alarm() set before us, now put it back */
3110  long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3111  long alarm_set;
3112 
3113  /* the alarm period is counted in even number of seconds */
3114  alarm_set = prev_alarm - elapsed_ms/1000;
3115 
3116  if(alarm_set<=0) {
3117  /* if it turned negative, we should fire off a SIGALRM here, but we
3118  won't, and zero would be to switch it off so we never set it to
3119  less than 1! */
3120  alarm(1);
3121  result = CURLE_OPERATION_TIMEOUTED;
3122  failf(data, "Previous alarm fired off!");
3123  }
3124  else
3125  alarm(alarm_set);
3126  }
3127  else
3128  alarm(0); /* just shut it off */
3129  }
3130 #endif
3131 
3132  return result;
3133 }
3134 
3135 /* SetupConnection() should be called after the name resolve initiated in
3136  * CreateConnection() is all done.
3137  */
3138 
3139 static CURLcode SetupConnection(struct connectdata *conn,
3140  struct Curl_dns_entry *hostaddr)
3141 {
3142  struct SessionHandle *data = conn->data;
3143  CURLcode result=CURLE_OK;
3144 
3146 
3147  if(conn->protocol & PROT_FILE)
3148  /* There's nothing in this function to setup if we're only doing
3149  a file:// transfer */
3150  return result;
3151 
3152  /*************************************************************
3153  * Send user-agent to HTTP proxies even if the target protocol
3154  * isn't HTTP.
3155  *************************************************************/
3156  if((conn->protocol&PROT_HTTP) ||
3157  (data->change.proxy && *data->change.proxy)) {
3158  if(data->set.useragent) {
3159  Curl_safefree(conn->allocptr.uagent);
3160  conn->allocptr.uagent =
3161  aprintf("User-Agent: %s\015\012", data->set.useragent);
3162  }
3163  }
3164 
3165  if(data->set.encoding) {
3167  conn->allocptr.accept_encoding =
3168  aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
3169  }
3170 
3171  conn->bytecount = 0;
3172  conn->headerbytecount = 0;
3173 
3174  if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3175  bool connected;
3176 
3177  /* Connect only if not already connected! */
3178  result = ConnectPlease(conn, hostaddr, &connected);
3179 
3180  if(connected) {
3181  result = Curl_protocol_connect(conn, hostaddr);
3182  if(CURLE_OK == result)
3183  conn->bits.tcpconnect = TRUE;
3184  }
3185  else
3186  conn->bits.tcpconnect = FALSE;
3187 
3188 
3189  if(CURLE_OK != result)
3190  return result;
3191  }
3192  else {
3193  Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
3194  conn->bits.tcpconnect = TRUE;
3195  if(data->set.verbose)
3196  verboseconnect(conn, hostaddr);
3197  }
3198 
3199  conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
3200  set this here perhaps a second time */
3201 
3202 #ifdef __EMX__
3203  /* 20000330 mgs
3204  * the check is quite a hack...
3205  * we're calling _fsetmode to fix the problem with fwrite converting newline
3206  * characters (you get mangled text files, and corrupted binary files when
3207  * you download to stdout and redirect it to a file). */
3208 
3209  if ((data->set.out)->_handle == NULL) {
3210  _fsetmode(stdout, "b");
3211  }
3212 #endif
3213 
3214  return CURLE_OK;
3215 }
3216 
3218  struct connectdata **in_connect,
3219  bool *asyncp)
3220 {
3221  CURLcode code;
3222  struct Curl_dns_entry *dns;
3223 
3224  *asyncp = FALSE; /* assume synchronous resolves by default */
3225 
3226  /* call the stuff that needs to be called */
3227  code = CreateConnection(data, in_connect, &dns, asyncp);
3228 
3229  if(CURLE_OK == code) {
3230  /* no error */
3231  if(dns || !*asyncp)
3232  /* If an address is available it means that we already have the name
3233  resolved, OR it isn't async.
3234  If so => continue connecting from here */
3235  code = SetupConnection(*in_connect, dns);
3236  /* else
3237  response will be received and treated async wise */
3238  }
3239 
3240  if(CURLE_OK != code) {
3241  /* We're not allowed to return failure with memory left allocated
3242  in the connectdata struct, free those here */
3243  if(*in_connect) {
3244  Curl_disconnect(*in_connect); /* close the connection */
3245  *in_connect = NULL; /* return a NULL */
3246  }
3247  }
3248 
3249  return code;
3250 }
3251 
3252 /* Call this function after Curl_connect() has returned async=TRUE and
3253  then a successful name resolve has been received */
3255 {
3256 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
3257  CURLcode code = SetupConnection(conn, conn->async.dns);
3258 
3259  if(code)
3260  /* We're not allowed to return failure with memory left allocated
3261  in the connectdata struct, free those here */
3262  Curl_disconnect(conn); /* close the connection */
3263 
3264  return code;
3265 #else
3266  (void)conn;
3267  return CURLE_OK;
3268 #endif
3269 }
3270 
3271 
3273 {
3274  struct SessionHandle *data=conn->data;
3275  CURLcode result;
3276 
3277  /* cleanups done even if the connection is re-used */
3278 
3279  if(conn->bits.rangestringalloc) {
3280  free(conn->range);
3281  conn->bits.rangestringalloc = FALSE;
3282  }
3283 
3284  /* Cleanup possible redirect junk */
3285  if(conn->newurl) {
3286  free(conn->newurl);
3287  conn->newurl = NULL;
3288  }
3289 
3290  if(conn->connect_addr)
3291  Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
3292 
3293 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
3294  /* scan for DNS cache entries still marked as in use */
3295  Curl_hash_apply(data->hostcache,
3297 #endif
3298 
3299  Curl_hostcache_prune(data); /* kill old DNS cache entries */
3300 
3301  /* this calls the protocol-specific function pointer previously set */
3302  if(conn->curl_done)
3303  result = conn->curl_done(conn);
3304  else
3305  result = CURLE_OK;
3306 
3307  Curl_pgrsDone(conn); /* done with the operation */
3308 
3309  /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
3310  forced us to close this no matter what we think.
3311 
3312  if conn->bits.close is TRUE, it means that the connection should be
3313  closed in spite of all our efforts to be nice, due to protocol
3314  restrictions in our or the server's end */
3315  if(data->set.reuse_forbid || conn->bits.close) {
3316  CURLcode res2;
3317  res2 = Curl_disconnect(conn); /* close the connection */
3318 
3319  /* If we had an error already, make sure we return that one. But
3320  if we got a new error, return that. */
3321  if(!result && res2)
3322  result = res2;
3323  }
3324  else
3325  infof(data, "Connection #%d left intact\n", conn->connectindex);
3326 
3327  return result;
3328 }
3329 
3331 {
3332  CURLcode result=CURLE_OK;
3333  struct connectdata *conn = *connp;
3334  struct SessionHandle *data=conn->data;
3335 
3336  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
3337 
3338  if(conn->curl_do) {
3339  /* generic protocol-specific function pointer set in curl_connect() */
3340  result = conn->curl_do(conn);
3341 
3342  /* This was formerly done in transfer.c, but we better do it here */
3343 
3344  if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
3345  /* This was a re-use of a connection and we got a write error in the
3346  * DO-phase. Then we DISCONNECT this connection and have another attempt
3347  * to CONNECT and then DO again! The retry cannot possibly find another
3348  * connection to re-use, since we only keep one possible connection for
3349  * each. */
3350 
3351  infof(data, "Re-used connection seems dead, get a new one\n");
3352 
3353  conn->bits.close = TRUE; /* enforce close of this connection */
3354  result = Curl_done(conn); /* we are so done with this */
3355 
3356  /* conn is no longer a good pointer */
3357 
3358  if(CURLE_OK == result) {
3359  bool async;
3360  /* Now, redo the connect and get a new connection */
3361  result = Curl_connect(data, connp, &async);
3362  if(CURLE_OK == result) {
3363  /* We have connected or sent away a name resolve query fine */
3364 
3365  conn = *connp; /* setup conn to again point to something nice */
3366  if(async) {
3367  /* Now, if async is TRUE here, we need to wait for the name
3368  to resolve */
3369  result = Curl_wait_for_resolv(conn, NULL);
3370  if(result)
3371  return result;
3372 
3373  /* Resolved, continue with the connection */
3374  result = Curl_async_resolved(conn);
3375  if(result)
3376  return result;
3377  }
3378 
3379  /* ... finally back to actually retry the DO phase */
3380  result = conn->curl_do(conn);
3381  }
3382  }
3383  }
3384  }
3385  return result;
3386 }
3387 
3389 {
3390  CURLcode result=CURLE_OK;
3391 
3392  if(conn->curl_do_more)
3393  result = conn->curl_do_more(conn);
3394 
3395  return result;
3396 }
3397 
3398 static bool safe_strequal(char* str1, char* str2)
3399 {
3400  if(str1 && str2)
3401  /* both pointers point to something then compare them */
3402  return strequal(str1, str2);
3403  else
3404  /* if both pointers are NULL then treat them as equal */
3405  return (!str1 && !str2);
3406 }
3407 
3408 bool
3410  struct ssl_config_data* needle)
3411 {
3412  if((data->version == needle->version) &&
3413  (data->verifypeer == needle->verifypeer) &&
3414  (data->verifyhost == needle->verifyhost) &&
3415  safe_strequal(data->CApath, needle->CApath) &&
3416  safe_strequal(data->CAfile, needle->CAfile) &&
3417  safe_strequal(data->random_file, needle->random_file) &&
3418  safe_strequal(data->egdsocket, needle->egdsocket) &&
3419  safe_strequal(data->cipher_list, needle->cipher_list))
3420  return TRUE;
3421 
3422  return FALSE;
3423 }
3424 
3425 bool
3427  struct ssl_config_data *dest)
3428 {
3429  dest->verifyhost = source->verifyhost;
3430  dest->verifypeer = source->verifypeer;
3431  dest->version = source->version;
3432 
3433  if(source->CAfile) {
3434  dest->CAfile = strdup(source->CAfile);
3435  if(!dest->CAfile)
3436  return FALSE;
3437  }
3438 
3439  if(source->CApath) {
3440  dest->CApath = strdup(source->CApath);
3441  if(!dest->CApath)
3442  return FALSE;
3443  }
3444 
3445  if(source->cipher_list) {
3446  dest->cipher_list = strdup(source->cipher_list);
3447  if(!dest->cipher_list)
3448  return FALSE;
3449  }
3450 
3451  if(source->egdsocket) {
3452  dest->egdsocket = strdup(source->egdsocket);
3453  if(!dest->egdsocket)
3454  return FALSE;
3455  }
3456 
3457  if(source->random_file) {
3458  dest->random_file = strdup(source->random_file);
3459  if(!dest->random_file)
3460  return FALSE;
3461  }
3462 
3463  return TRUE;
3464 }
3465 
3467 {
3468  if(sslc->CAfile)
3469  free(sslc->CAfile);
3470 
3471  if(sslc->CApath)
3472  free(sslc->CApath);
3473 
3474  if(sslc->cipher_list)
3475  free(sslc->cipher_list);
3476 
3477  if(sslc->egdsocket)
3478  free(sslc->egdsocket);
3479 
3480  if(sslc->random_file)
3481  free(sslc->random_file);
3482 }
#define PROT_TELNET
Definition: urldata.h:413
bool krb4
Definition: urldata.h:872
void Curl_hash_apply(curl_hash *h, void *user, void(*cb)(void *user, void *ptr))
struct ssl_connect_data ssl[2]
Definition: urldata.h:459
bool no_body
Definition: urldata.h:864
bool callback
Definition: urldata.h:614
bool ftp_use_port
Definition: urldata.h:854
int connectindex
Definition: urldata.h:404
bool rangestringalloc
Definition: urldata.h:287
struct CookieInfo * cookies
Definition: urldata.h:901
CURLcode Curl_file_connect(struct connectdata *conn)
Definition: file.c:98
bool httpproxy
Definition: urldata.h:281
#define PORT_TELNET
Definition: urldata.h:32
struct ConnectBits bits
Definition: urldata.h:462
curl_off_t bytecount
Definition: urldata.h:437
curl_hash * hostcache
Definition: share.h:40
long numsessions
Definition: urldata.h:156
struct connectdata ** connects
Definition: urldata.h:673
char * curl_unescape(const char *string, int length)
Definition: escape.c:86
#define LEAST_PATH_ALLOC
#define CURLAUTH_BASIC
Definition: curl.h:296
union connectdata::@11 proto
struct timeval start
Definition: urldata.h:629
bool http_disable_hostname_check_before_authentication
Definition: urldata.h:858
curl_closepolicy closepolicy
Definition: urldata.h:819
#define strequal(a, b)
Definition: strequal.h:32
CURLcode Curl_open(struct SessionHandle **curl)
Definition: url.c:249
int curl_socket_t
Definition: setup.h:254
int Curl_resolv(struct connectdata *conn, char *hostname, int port, struct Curl_dns_entry **entry)
Definition: hostip.c:315
curl_write_callback fwrite_header
Definition: urldata.h:789
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,...)
Definition: url.c:343
void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
Definition: progress.c:126
char * curl_getenv(const char *variable)
Definition: getenv.c:68
void Curl_pgrsDone(struct connectdata *conn)
Definition: progress.c:105
#define FIRSTSOCKET
Definition: urldata.h:394
#define PORT_GOPHER
Definition: urldata.h:33
long use_port
Definition: urldata.h:769
struct ssl_config_data ssl
Definition: urldata.h:829
CURLcode Curl_dict(struct connectdata *conn)
Definition: dict.c:82
void * in
Definition: urldata.h:765
volatile unsigned int dirty
Definition: share.h:34
long connecttimeout
Definition: urldata.h:795
bool url_alloc
Definition: urldata.h:735
curl_proxytype
Definition: curl.h:289
struct DynamicStatic change
Definition: urldata.h:899
bool ftp_use_epsv
Definition: urldata.h:876
void * fsslctxp
Definition: urldata.h:158
int dns_cache_timeout
Definition: urldata.h:833
CURLcode Curl_http_done(struct connectdata *conn)
Definition: http.c:1000
char * errorbuffer
Definition: urldata.h:759
GLfloat param
Definition: glext.h:3038
#define failf
Definition: sendf.h:32
char * useragent
Definition: urldata.h:780
char * customrequest
Definition: urldata.h:821
struct curl_slist * http200aliases
Definition: urldata.h:838
CURLcode(* curl_disconnect)(struct connectdata *)
Definition: urldata.h:483
CURLcode Curl_connect(struct SessionHandle *data, struct connectdata **in_connect, bool *asyncp)
Definition: url.c:3217
CURLcode Curl_telnet(struct connectdata *conn)
Definition: telnet.c:1078
bool no_signal
Definition: urldata.h:879
char * cookie
Definition: urldata.h:801
bool Curl_clone_ssl_config(struct ssl_config_data *source, struct ssl_config_data *dest)
Definition: url.c:3426
CURLcode(* curl_done)(struct connectdata *)
Definition: urldata.h:467
CURLcode
Definition: curl.h:209
#define MAX_CURL_USER_LENGTH_TXT
Definition: urldata.h:658
char * cookiejar
Definition: urldata.h:810
#define CURLAUTH_GSSNEGOTIATE
Definition: curl.h:298
#define MAX_CURL_PASSWORD_LENGTH
Definition: urldata.h:657
CURL_NETRC_OPTION
Definition: curl.h:837
struct in_addr Curl_ipconnect
Definition: setup.h:276
#define MAX_CURL_PASSWORD_LENGTH_TXT
Definition: urldata.h:659
char * contenttype
Definition: urldata.h:600
struct curl_slist * quote
Definition: urldata.h:813
#define PROT_FILE
Definition: urldata.h:416
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
curl_ftpssl ftp_ssl
Definition: urldata.h:878
char protostr[64]
Definition: urldata.h:428
bool upload
Definition: urldata.h:866
unsigned short remote_port
Definition: urldata.h:434
bool http_auto_referer
Definition: urldata.h:863
#define SECONDARYSOCKET
Definition: urldata.h:395
GLenum GLsizei len
Definition: glext.h:3472
struct UrlState state
Definition: urldata.h:903
CURLcode Curl_do(struct connectdata **connp)
Definition: url.c:3330
#define CURL_CA_BUNDLE
struct timeval created
Definition: urldata.h:453
size_t(* curl_write_callback)(char *buffer, size_t size, size_t nitems, void *outstream)
Definition: curl.h:169
char * proxyuser
Definition: urldata.h:449
off_t curl_off_t
Definition: curl.h:96
FILE * err
Definition: urldata.h:757
int Curl_read(struct connectdata *conn, curl_socket_t sockfd, char *buf, size_t buffersize, ssize_t *n)
Definition: sendf.c:362
long proxyauth
Definition: urldata.h:772
bool referer_alloc
Definition: urldata.h:743
#define PROT_DICT
Definition: urldata.h:414
#define LIBCURL_NAME
Definition: urldata.h:911
int i
Definition: process.py:33
long ftp_response_timeout
Definition: urldata.h:796
char * private
Definition: urldata.h:836
CURLcode Curl_ftp(struct connectdata *conn)
Definition: ftp.c:2306
#define PORT_FTPS
Definition: urldata.h:31
Boolean result
char * CApath
Definition: urldata.h:151
#define ssize_t
Definition: config-win32.h:27
char * egdsocket
Definition: urldata.h:154
struct Progress progress
Definition: urldata.h:902
void * progress_client
Definition: urldata.h:793
struct ssl_config_data ssl_config
Definition: urldata.h:460
#define CURL_DEFAULT_PASSWORD
Definition: urldata.h:47
curl_off_t set_resume_from
Definition: urldata.h:800
enum CURL_NETRC_OPTION use_netrc
Definition: urldata.h:867
curl_hash * hostcache
Definition: urldata.h:896
char * random_file
Definition: urldata.h:153
CURLcode(* curl_do_more)(struct connectdata *)
Definition: urldata.h:473
int Curl_nonblock(curl_socket_t sockfd, int nonblock)
Definition: connect.c:114
bool reuse
Definition: urldata.h:279
CURLcode Curl_write(struct connectdata *conn, curl_socket_t sockfd, void *mem, size_t len, ssize_t *written)
Definition: sendf.c:221
bool global_dns_cache
Definition: urldata.h:881
CURLcode Curl_ldap(struct connectdata *conn)
Definition: ldap.c:139
bool tunnel_thru_httpproxy
Definition: urldata.h:849
bool get_filetime
Definition: urldata.h:848
bool allow_port
Definition: urldata.h:703
char * proxyuserpwd
Definition: urldata.h:760
void Curl_global_host_cache_init(void)
Definition: hostip.c:126
CURLcode(* curl_connect)(struct connectdata *)
Definition: urldata.h:478
curl_off_t resume_from
Definition: urldata.h:442
void * out
Definition: urldata.h:764
long timeout
Definition: urldata.h:794
int(* curl_debug_callback)(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
Definition: curl.h:196
int flags
Definition: urldata.h:616
GLsizei GLsizei GLcharARB * source
Definition: glext.h:3633
char * cipher_list
Definition: urldata.h:155
char * auth_host
Definition: urldata.h:685
char * inet_ntoa_r(const struct in_addr in, char *buffer, int buflen)
bool crlf
Definition: urldata.h:812
char * passwd
Definition: urldata.h:447
#define HEADERSIZE
Definition: urldata.h:108
#define PROT_HTTP
Definition: urldata.h:410
void * writeheader
Definition: urldata.h:766
bool reuse_forbid
Definition: urldata.h:873
bool ipv6_ip
Definition: urldata.h:284
char * set_proxy
Definition: urldata.h:768
bool ftp_use_eprt
Definition: urldata.h:877
char * proxy
Definition: urldata.h:740
struct ntlmdata proxyntlm
Definition: urldata.h:571
struct PureInfo info
Definition: urldata.h:905
Curl_addrinfo * addr
Definition: hostip.h:41
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
Definition: hostip.c:408
struct curl_slist * headers
Definition: urldata.h:802
void * debugdata
Definition: urldata.h:758
char * hostname
Definition: urldata.h:432
bool ftp_create_missing_dirs
Definition: urldata.h:853
long low_speed_time
Definition: urldata.h:799
long buffer_size
Definition: urldata.h:834
#define FORMAT_OFF_T
Definition: setup.h:99
char * url
Definition: urldata.h:734
CURLcode Curl_protocol_connect(struct connectdata *conn, struct Curl_dns_entry *hostaddr)
Definition: url.c:1931
Definition: hostip.h:40
#define NULL
Definition: Lib.h:88
curl_off_t postfieldsize
Definition: urldata.h:783
int ip_version
Definition: urldata.h:840
long verifypeer
Definition: urldata.h:147
#define select(args...)
Definition: amigaos.h:39
char gname[513]
Definition: urldata.h:429
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
curl_TimeCond
Definition: curl.h:858
struct timeval now
Definition: urldata.h:452
char * ppath
Definition: urldata.h:436
char * set_referer
Definition: urldata.h:777
char * referer
Definition: urldata.h:742
char * userpwd
Definition: urldata.h:770
long httpversion
Definition: urldata.h:822
bool hide_progress
Definition: urldata.h:855
char * key
Definition: urldata.h:806
const char * path
Definition: sws.c:117
struct Curl_share * share
Definition: urldata.h:897
CURLcode Curl_http_connect(struct connectdata *conn)
Definition: http.c:956
long authwant
Definition: urldata.h:715
long maxredirs
Definition: urldata.h:776
char * scratch
Definition: urldata.h:694
CURLcode Curl_http(struct connectdata *conn)
Definition: http.c:1057
CURLcode Curl_async_resolved(struct connectdata *conn)
Definition: url.c:3254
long proxyport
Definition: urldata.h:761
long numconnects
Definition: urldata.h:674
curl_debug_callback fdebug
Definition: urldata.h:792
bool this_is_a_follow
Definition: urldata.h:683
CURLcode Curl_Transfer(struct connectdata *c_conn, int sockindex, curl_off_t size, bool getheader, curl_off_t *bytecountp, int writesockindex, curl_off_t *writecountp)
Definition: transfer.c:1998
curl_ssl_ctx_callback fsslctx
Definition: urldata.h:157
struct ntlmdata ntlm
Definition: urldata.h:568
#define CURLAUTH_NTLM
Definition: curl.h:299
char * range
Definition: urldata.h:440
#define PROT_LDAP
Definition: urldata.h:415
long Curl_tvdiff(struct timeval newer, struct timeval older)
Definition: timeval.c:92
bool reuse_fresh
Definition: urldata.h:874
long authstage
Definition: urldata.h:712
void Curl_hash_destroy(curl_hash *h)
Definition: hash.c:278
GLenum const GLvoid * addr
Definition: glext.h:5393
Definition: curl.h:210
struct SessionHandle * data
Definition: urldata.h:403
char * cert_type
Definition: urldata.h:805
#define CURL_DEFAULT_USER
Definition: urldata.h:46
curl_read_callback fread
Definition: urldata.h:565
#define checkprefix(a, b)
Definition: strequal.h:37
#define ALL_CONTENT_ENCODINGS
char * newurl
Definition: urldata.h:517
struct curl_slist * telnet_options
Definition: urldata.h:816
bool tcpconnect
Definition: urldata.h:299
struct CookieInfo * cookies
Definition: share.h:41
struct curl_slist * cookielist
Definition: urldata.h:744
long verifyhost
Definition: urldata.h:148
bool close
Definition: urldata.h:278
char * strdup(char *s1)
Definition: main.c:183
#define sclose(x)
Definition: setup.h:220
bool chunk
Definition: urldata.h:280
curl_progress_callback fprogress
Definition: urldata.h:791
#define PROT_FTPS
Definition: urldata.h:417
bool proxy_user_passwd
Definition: urldata.h:283
char * proxyhost
Definition: urldata.h:444
CURLcode Curl_close(struct SessionHandle *data)
Definition: url.c:187
CURLoption
Definition: curl.h:368
bool ftp_append
Definition: urldata.h:850
char * name
Definition: urldata.h:430
#define strtok_r
Definition: strtok.h:32
char * key_passwd
Definition: urldata.h:808
curl_off_t infilesize
Definition: urldata.h:797
#define MAX_CURL_USER_LENGTH
Definition: urldata.h:656
void Curl_digest_cleanup(struct SessionHandle *data)
Definition: http_digest.c:214
#define PORT_HTTPS
Definition: urldata.h:35
curl_read_callback fread
Definition: urldata.h:790
char * proxypasswd
Definition: urldata.h:450
CURLcode Curl_connecthost(struct connectdata *conn, struct Curl_dns_entry *remotehost, int port, curl_socket_t *sockconn, Curl_ipconnect **addr, bool *connected)
Definition: connect.c:513
CURLcode Curl_ftp_done(struct connectdata *conn)
Definition: ftp.c:720
size_t fread(void *, size_t, size_t, FILE *)
void * generic
Definition: urldata.h:549
#define RETSIGTYPE
Definition: url.c:154
CURLcode Curl_disconnect(struct connectdata *conn)
Definition: url.c:1313
bool ftp_ascii
Definition: urldata.h:851
curl_off_t max_filesize
Definition: urldata.h:842
char * headerbuff
Definition: urldata.h:676
char * cert
Definition: urldata.h:804
char * ftpport
Definition: urldata.h:786
struct curl_slist * postquote
Definition: urldata.h:814
curl_socket_t sock[2]
Definition: urldata.h:454
GLuint in
Definition: glext.h:5388
CURLcode Curl_file(struct connectdata *conn)
Definition: file.c:164
char * postfields
Definition: urldata.h:782
bool verbose
Definition: urldata.h:871
double current_speed
Definition: urldata.h:681
struct Curl_dns_entry * connect_addr
Definition: urldata.h:421
#define snprintf
Definition: Str.h:70
char * netrc_file
Definition: urldata.h:869
time_t timevalue
Definition: urldata.h:818
CURLcode Curl_do_more(struct connectdata *conn)
Definition: url.c:3388
#define PROT_HTTPS
Definition: urldata.h:411
struct curl_slist * curl_slist_append(struct curl_slist *, const char *)
Definition: sendf.c:82
#define PROT_GOPHER
Definition: urldata.h:409
bool Curl_ssl_config_matches(struct ssl_config_data *data, struct ssl_config_data *needle)
Definition: url.c:3409
CURLcode Curl_wait_for_resolv(struct connectdata *conn, struct Curl_dns_entry **entry)
Definition: hostip.c:676
char * device
Definition: urldata.h:787
curl_write_callback fwrite
Definition: urldata.h:788
#define CURL_SOCKET_BAD
Definition: setup.h:255
bool url_changed
Definition: urldata.h:736
char * encoding
Definition: urldata.h:781
void Curl_hostcache_prune(struct SessionHandle *data)
Definition: hostip.c:225
void Curl_scan_cache_used(void *user, void *ptr)
int headersize
Definition: urldata.h:677
#define infof
Definition: sendf.h:31
void Curl_safefree(void *ptr)
Definition: url.c:172
curl_ftpssl
Definition: curl.h:314
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
void * fread_in
Definition: urldata.h:566
#define FALSE
Definition: mprintf.c:70
struct timeval Curl_tvnow(void)
Definition: timeval.c:81
CURLcode Curl_telnet_done(struct connectdata *conn)
Definition: telnet.c:1067
CURLSHcode Curl_share_lock(struct SessionHandle *data, curl_lock_data type, curl_lock_access accesstype)
Definition: share.c:180
char * krb4_level
Definition: urldata.h:828
int(* curl_progress_callback)(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
Definition: curl.h:159
bool upload_chunky
Definition: urldata.h:292
#define inet_ntoa(x)
Definition: amigaos.h:40
#define PORT_LDAP
Definition: urldata.h:37
struct UserDefined set
Definition: urldata.h:898
struct hostent Curl_addrinfo
Definition: setup.h:275
void Curl_free_ssl_config(struct ssl_config_data *sslc)
Definition: url.c:3466
CURLcode(* curl_ssl_ctx_callback)(CURL *curl, void *ssl_ctx, void *userptr)
Definition: curl.h:280
char * path
Definition: urldata.h:431
void curl_slist_free_all(struct curl_slist *)
Definition: sendf.c:108
#define ARES_SUCCESS
Definition: hostip.c:88
char * key_type
Definition: urldata.h:807
long port
Definition: urldata.h:433
bool use_range
Definition: urldata.h:286
long headerbytecount
Definition: urldata.h:438
CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
Definition: ftp.c:1688
unsigned char bool
Definition: setup.h:74
char * set_range
Definition: urldata.h:773
long low_speed_limit
Definition: urldata.h:798
#define PROT_SSL
Definition: urldata.h:418
#define TRUE
Definition: mprintf.c:69
int Curl_parsenetrc(char *host, char *login, char *password, char *netrcfile)
Definition: netrc.c:79
struct curl_slist * prequote
Definition: urldata.h:815
#define PROT_MISSING
Definition: urldata.h:408
long protocol
Definition: urldata.h:407
#define PORT_HTTP
Definition: urldata.h:34
bool http_follow_location
Definition: urldata.h:857
curl_proxytype proxytype
Definition: urldata.h:831
int Curl_SSL_Close_All(struct SessionHandle *data)
curlntlm state
Definition: urldata.h:188
bool do_more
Definition: urldata.h:289
void Curl_SSL_Close(struct connectdata *conn)
Definition: ssluse.c:458
if(!ValidDisplayID(prefInfo.prefDisplayID)) prefInfo.prefDisplayID
struct connectdata::dynamically_allocated_data allocptr
#define PORT_FTP
Definition: urldata.h:30
#define PROT_FTP
Definition: urldata.h:412
size_t(* curl_read_callback)(char *buffer, size_t size, size_t nitems, void *instream)
Definition: curl.h:174
CURLcode(* curl_do)(struct connectdata *)
Definition: urldata.h:466
#define PGRS_HIDE
Definition: progress.h:63
curl_off_t maxdownload
Definition: urldata.h:456
bool ftp_list_only
Definition: urldata.h:852
Curl_HttpReq httpreq
Definition: urldata.h:820
struct curl_httppost * httppost
Definition: urldata.h:803
curl_TimeCond timecondition
Definition: urldata.h:817
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
Definition: ftp.c:2488
CURLSHcode Curl_share_unlock(struct SessionHandle *data, curl_lock_data type)
Definition: share.c:198
CURLcode Curl_ftp_connect(struct connectdata *conn)
Definition: ftp.c:441
long httpauth
Definition: urldata.h:771
#define PORT_DICT
Definition: urldata.h:36
size_t fwrite(const void *, size_t, size_t, FILE *)
bool proxy_alloc
Definition: urldata.h:741
char * set_url
Definition: urldata.h:767
bool user_passwd
Definition: urldata.h:282
char * CAfile
Definition: urldata.h:152
#define BUFSIZE
Definition: urldata.h:104
bool cookiesession
Definition: urldata.h:811
char * user
Definition: urldata.h:446
bool http_fail_on_error
Definition: urldata.h:856
CURLcode Curl_done(struct connectdata *conn)
Definition: url.c:3272
struct sockaddr_in serv_addr
Definition: urldata.h:426