1
/*****************************************************************************
3
* Project ___| | | | _ \| |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
10
* In order to be useful for every potential user, curl and libcurl are
11
* dual-licensed under the MPL and the MIT/X-derivate licenses.
13
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
14
* copies of the Software, and permit persons to whom the Software is
15
* furnished to do so, under the terms of the MPL or the MIT/X-derivate
16
* licenses. You may pick one of these licenses.
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
21
* $Id: url.c,v 1.191 2002/02/28 23:31:23 bagder Exp $
22
*****************************************************************************/
24
/* -- WIN32 approved -- */
33
#include <sys/types.h>
38
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
43
#ifdef HAVE_SYS_SOCKET_H
44
#include <sys/socket.h>
46
#include <netinet/in.h>
48
#include <sys/resource.h>
53
#ifdef HAVE_ARPA_INET_H
54
#include <arpa/inet.h>
59
#include <sys/ioctl.h>
62
#ifdef HAVE_SYS_PARAM_H
63
#include <sys/param.h>
66
#ifdef HAVE_SYS_SELECT_H
67
#include <sys/select.h>
76
#error "We can't compile without select() support!"
79
#error "We can't compile without socket() support!"
101
/* And now for the protocols */
111
#include <curl/types.h>
113
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
114
#include "inet_ntoa_r.h"
117
#define _MPRINTF_REPLACE /* use our functions only */
118
#include <curl/mprintf.h>
121
#include "security.h"
123
/* The last #include file should be: */
125
#include "memdebug.h"
128
/* Local static prototypes */
129
static int ConnectionKillOne(struct SessionHandle *data);
130
static bool ConnectionExists(struct SessionHandle *data,
131
struct connectdata *needle,
132
struct connectdata **usethis);
133
static unsigned int ConnectionStore(struct SessionHandle *data,
134
struct connectdata *conn);
137
#if !defined(WIN32)||defined(__CYGWIN32__)
139
#define RETSIGTYPE void
142
RETSIGTYPE alarmfunc(int signal)
144
/* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
152
* This is the internal function curl_easy_cleanup() calls. This should
153
* cleanup and free all resources associated with this sessionhandle.
155
* NOTE: if we ever add something that attempts to write to a socket or
156
* similar here, we must ignore SIGPIPE first. It is currently only done
157
* when curl_easy_perform() is invoked.
160
CURLcode Curl_close(struct SessionHandle *data)
162
/* Loop through all open connections and kill them one by one */
163
while(-1 != ConnectionKillOne(data));
166
/* Close down all open SSL info and sessions */
167
Curl_SSL_Close_All(data);
170
if(data->state.auth_host)
171
free(data->state.auth_host);
173
if(data->change.proxy_alloc)
174
free(data->change.proxy);
176
if(data->change.referer_alloc)
177
free(data->change.referer);
179
if(data->change.url_alloc)
180
free(data->change.url);
182
if(data->state.headerbuff)
183
free(data->state.headerbuff);
185
if(data->set.cookiejar)
186
/* we have a "destination" for all the cookies to get dumped to */
187
Curl_cookie_output(data->cookies, data->set.cookiejar);
189
Curl_cookie_cleanup(data->cookies);
191
/* free the connection cache */
192
free(data->state.connects);
194
if(data->info.contenttype)
195
free(data->info.contenttype);
202
int my_getpass(void *clientp, const char *prompt, char* buffer, int buflen )
205
clientp=NULL; /* prevent compiler warning */
207
retbuf = getpass_r(prompt, buffer, buflen);
211
return 0; /* success */
215
CURLcode Curl_open(struct SessionHandle **curl)
217
/* We don't yet support specifying the URL at this point */
218
struct SessionHandle *data;
219
/* Very simple start-up: alloc the struct, init it with zeroes and return */
220
data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle));
222
/* this is a very serious error */
223
return CURLE_OUT_OF_MEMORY;
225
memset(data, 0, sizeof(struct SessionHandle));
227
/* We do some initial setup here, all those fields that can't be just 0 */
229
data->state.headerbuff=(char*)malloc(HEADERSIZE);
230
if(!data->state.headerbuff) {
231
free(data); /* free the memory again */
232
return CURLE_OUT_OF_MEMORY;
235
data->state.headersize=HEADERSIZE;
237
data->set.out = stdout; /* default output to stdout */
238
data->set.in = stdin; /* default input from stdin */
239
data->set.err = stderr; /* default stderr to stderr */
241
/* use fwrite as default function to store output */
242
data->set.fwrite = (curl_write_callback)fwrite;
244
/* use fread as default function to read input */
245
data->set.fread = (curl_read_callback)fread;
247
/* set the default passwd function */
248
data->set.fpasswd = my_getpass;
250
data->set.infilesize = -1; /* we don't know any size */
252
data->state.current_speed = -1; /* init to negative == impossible */
254
data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
255
data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
257
data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
259
/* make libcurl quiet by default: */
260
data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
261
data->progress.flags |= PGRS_HIDE;
263
/* Set the default size of the SSL session ID cache */
264
data->set.ssl.numsessions = 5;
266
/* create an array with connection data struct pointers */
267
data->state.numconnects = 5; /* hard-coded right now */
268
data->state.connects = (struct connectdata **)
269
malloc(sizeof(struct connectdata *) * data->state.numconnects);
271
if(!data->state.connects) {
273
return CURLE_OUT_OF_MEMORY;
276
memset(data->state.connects, 0,
277
sizeof(struct connectdata *)*data->state.numconnects);
284
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
289
va_start(param, option);
292
case CURLOPT_DNS_CACHE_TIMEOUT:
293
data->set.dns_cache_timeout = va_arg(param, int);
295
case CURLOPT_DNS_USE_GLOBAL_CACHE:
297
int use_cache = va_arg(param, int);
299
Curl_global_host_cache_init();
302
data->set.global_dns_cache = use_cache;
305
case CURLOPT_SSL_CIPHER_LIST:
306
/* set a list of cipher we want to use in the SSL connection */
307
data->set.ssl.cipher_list = va_arg(param, char *);
310
case CURLOPT_RANDOM_FILE:
312
* This is the path name to a file that contains random data to seed
313
* the random SSL stuff with. The file is only used for reading.
315
data->set.ssl.random_file = va_arg(param, char *);
317
case CURLOPT_EGDSOCKET:
319
* The Entropy Gathering Daemon socket pathname
321
data->set.ssl.egdsocket = va_arg(param, char *);
323
case CURLOPT_MAXCONNECTS:
325
* Set the absolute number of maximum simultaneous alive connection that
326
* libcurl is allowed to have.
329
long newconnects= va_arg(param, long);
330
struct connectdata **newptr;
332
if(newconnects < data->state.numconnects) {
333
/* Since this number is *decreased* from the existing number, we must
334
close the possibly open connections that live on the indexes that
335
are being removed! */
337
for(i=newconnects; i< data->state.numconnects; i++)
338
Curl_disconnect(data->state.connects[i]);
341
newptr= (struct connectdata **)
342
realloc(data->state.connects,
343
sizeof(struct connectdata *) * newconnects);
345
/* we closed a few connections in vain, but so what? */
346
return CURLE_OUT_OF_MEMORY;
347
data->state.connects = newptr;
348
data->state.numconnects = newconnects;
351
/* zero makes NO cache at all */
352
if(data->state.connects)
353
free(data->state.connects);
354
data->state.connects=NULL;
355
data->state.numconnects=0;
359
case CURLOPT_FORBID_REUSE:
361
* When this transfer is done, it must not be left to be reused by a
362
* subsequent transfer but shall be closed immediately.
364
data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
366
case CURLOPT_FRESH_CONNECT:
368
* This transfer shall not use a previously cached connection but
369
* should be made with a fresh new connect!
371
data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
373
case CURLOPT_VERBOSE:
375
* Verbose means infof() calls that give a lot of information about
376
* the connection and transfer procedures as well as internal choices.
378
data->set.verbose = va_arg(param, long)?TRUE:FALSE;
382
* Set to include the header in the general data output stream.
384
data->set.http_include_header = va_arg(param, long)?TRUE:FALSE;
386
case CURLOPT_NOPROGRESS:
388
* Shut off the internal supported progress meter
390
data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
391
if(data->set.hide_progress)
392
data->progress.flags |= PGRS_HIDE;
394
data->progress.flags &= ~PGRS_HIDE;
398
* Do not include the body part in the output data stream.
400
data->set.no_body = va_arg(param, long)?TRUE:FALSE;
402
case CURLOPT_FAILONERROR:
404
* Don't output the >=300 error code HTML-page, but instead only
407
data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
411
* We want to sent data to the remote host
413
data->set.upload = va_arg(param, long)?TRUE:FALSE;
415
/* If this is HTTP, PUT is what's needed to "upload" */
416
data->set.httpreq = HTTPREQ_PUT;
418
case CURLOPT_FILETIME:
420
* Try to get the file time of the remote document. The time will
421
* later (possibly) become available using curl_easy_getinfo().
423
data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
425
case CURLOPT_FTPLISTONLY:
427
* An FTP option that changes the command to one that asks for a list
428
* only, no file info details.
430
data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
432
case CURLOPT_FTPAPPEND:
434
* We want to upload and append to an existing (FTP) file.
436
data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
440
* Parse the $HOME/.netrc file
442
data->set.use_netrc = va_arg(param, long)?TRUE:FALSE;
444
case CURLOPT_FOLLOWLOCATION:
446
* Follow Location: header hints on a HTTP-server.
448
data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
450
case CURLOPT_HTTP_VERSION:
452
* This sets a requested HTTP version to be used. The value is one of
453
* the listed enums in curl/curl.h.
455
data->set.httpversion = va_arg(param, long);
457
case CURLOPT_TRANSFERTEXT:
459
* This option was previously named 'FTPASCII'. Renamed to work with
460
* more protocols than merely FTP.
462
* Transfer using ASCII (instead of BINARY).
464
data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
468
* Use the HTTP PUT request to transfer data if this is TRUE. If this is
469
* FALSE, don't set the httpreq. We can't know what to revert it to!
471
if(va_arg(param, long))
472
data->set.httpreq = HTTPREQ_PUT;
474
case CURLOPT_TIMECONDITION:
476
* Set HTTP time condition. This must be one of the defines in the
477
* curl/curl.h header file.
479
data->set.timecondition = va_arg(param, long);
481
case CURLOPT_TIMEVALUE:
483
* This is the value to compare with the remote document with the
484
* method set with CURLOPT_TIMECONDITION
486
data->set.timevalue = va_arg(param, long);
488
case CURLOPT_SSLVERSION:
490
* Set explicit SSL version to try to connect with, as some SSL
491
* implementations are lame.
493
data->set.ssl.version = va_arg(param, long);
496
case CURLOPT_COOKIEFILE:
498
* Set cookie file to read and parse. Can be used multiple times.
500
cookiefile = (char *)va_arg(param, void *);
502
data->cookies = Curl_cookie_init(cookiefile, data->cookies);
505
case CURLOPT_COOKIEJAR:
507
* Set cookie file name to dump all cookies to when we're done.
509
data->set.cookiejar = (char *)va_arg(param, void *);
512
* Activate the cookie parser. This may or may not already
515
data->cookies = Curl_cookie_init(NULL, data->cookies);
517
case CURLOPT_WRITEHEADER:
519
* Custom pointer to pass the header write callback function
521
data->set.writeheader = (void *)va_arg(param, void *);
525
* Cookie string to send to the remote server in the request.
527
data->set.cookie = va_arg(param, char *);
529
case CURLOPT_ERRORBUFFER:
531
* Error buffer provided by the caller to get the human readable
534
data->set.errorbuffer = va_arg(param, char *);
538
* FILE pointer to write to or include in the data write callback
540
data->set.out = va_arg(param, FILE *);
542
case CURLOPT_FTPPORT:
544
* Use FTP PORT, this also specifies which IP address to use
546
data->set.ftpport = va_arg(param, char *);
547
data->set.ftp_use_port = data->set.ftpport?1:0;
550
case CURLOPT_FTP_USE_EPSV:
551
data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
554
case CURLOPT_HTTPHEADER:
556
* Set a list with HTTP headers to use (or replace internals with)
558
data->set.headers = va_arg(param, struct curl_slist *);
560
case CURLOPT_CUSTOMREQUEST:
562
* Set a custom string to use as request
564
data->set.customrequest = va_arg(param, char *);
567
data->set.httpreq = HTTPREQ_CUSTOM;
568
here, we continue as if we were using the already set type
569
and this just changes the actual request keyword */
571
case CURLOPT_HTTPPOST:
573
* Set to make us do HTTP POST
575
data->set.httppost = va_arg(param, struct HttpPost *);
576
if(data->set.httppost)
577
data->set.httpreq = HTTPREQ_POST_FORM;
580
case CURLOPT_HTTPGET:
582
* Set to force us do HTTP GET
584
if(va_arg(param, long)) {
585
data->set.httpreq = HTTPREQ_GET;
586
data->set.upload = FALSE; /* switch off upload */
592
* FILE pointer to read the file to be uploaded from. Or possibly
593
* used as argument to the read callback.
595
data->set.in = va_arg(param, FILE *);
597
case CURLOPT_INFILESIZE:
599
* If known, this should inform curl about the file size of the
600
* to-be-uploaded file.
602
data->set.infilesize = va_arg(param, long);
604
case CURLOPT_LOW_SPEED_LIMIT:
606
* The low speed limit that if transfers are below this for
607
* CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
609
data->set.low_speed_limit=va_arg(param, long);
611
case CURLOPT_LOW_SPEED_TIME:
613
* The low speed time that if transfers are below the set
614
* CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
616
data->set.low_speed_time=va_arg(param, long);
622
if(data->change.url_alloc) {
623
/* the already set URL is allocated, free it first! */
624
free(data->change.url);
625
data->change.url_alloc=FALSE;
627
data->set.set_url = va_arg(param, char *);
628
data->change.url = data->set.set_url;
632
* The port number to use when getting the URL
634
data->set.use_port = va_arg(param, long);
637
/* Does this option serve a purpose anymore? */
639
if(va_arg(param, long))
640
data->set.httpreq = HTTPREQ_POST;
642
case CURLOPT_POSTFIELDS:
644
* A string with POST data. Makes curl HTTP POST.
646
data->set.postfields = va_arg(param, char *);
647
if(data->set.postfields)
648
data->set.httpreq = HTTPREQ_POST;
650
case CURLOPT_POSTFIELDSIZE:
652
* The size of the POSTFIELD data, if curl should now do a strlen
653
* to find out. Enables binary posts.
655
data->set.postfieldsize = va_arg(param, long);
657
case CURLOPT_REFERER:
659
* String to set in the HTTP Referer: field.
661
if(data->change.referer_alloc) {
662
free(data->change.referer);
663
data->change.referer_alloc = FALSE;
665
data->set.set_referer = va_arg(param, char *);
666
data->change.referer = data->set.set_referer;
668
case CURLOPT_AUTOREFERER:
670
* Switch on automatic referer that gets set if curl follows locations.
672
data->set.http_auto_referer = va_arg(param, long)?1:0;
676
* Set proxy server:port to use as HTTP proxy
678
if(data->change.proxy_alloc) {
680
* The already set string is allocated, free that first
682
data->change.proxy_alloc=FALSE;;
683
free(data->change.proxy);
685
data->set.set_proxy = va_arg(param, char *);
686
data->change.proxy = data->set.set_proxy;
688
case CURLOPT_HTTPPROXYTUNNEL:
690
* Tunnel operations through the proxy instead of normal proxy use
692
data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
694
case CURLOPT_PROXYPORT:
696
* Explicitly set HTTP proxy port number.
698
data->set.proxyport = va_arg(param, long);
700
case CURLOPT_TIMEOUT:
702
* The maximum time you allow curl to use for a single transfer
705
data->set.timeout = va_arg(param, long);
707
case CURLOPT_CONNECTTIMEOUT:
709
* The maximum time you allow curl to use to connect.
711
data->set.connecttimeout = va_arg(param, long);
713
case CURLOPT_MAXREDIRS:
715
* The maximum amount of hops you allow curl to follow Location:
716
* headers. This should mostly be used to detect never-ending loops.
718
data->set.maxredirs = va_arg(param, long);
720
case CURLOPT_USERAGENT:
722
* String to use in the HTTP User-Agent field
724
data->set.useragent = va_arg(param, char *);
726
case CURLOPT_USERPWD:
728
* user:password to use in the operation
730
data->set.userpwd = va_arg(param, char *);
732
case CURLOPT_POSTQUOTE:
734
* List of RAW FTP commands to use after a transfer
736
data->set.postquote = va_arg(param, struct curl_slist *);
738
case CURLOPT_PREQUOTE:
740
* List of RAW FTP commands to use prior to RETR (Wesley Laxton)
742
data->set.prequote = va_arg(param, struct curl_slist *);
746
* List of RAW FTP commands to use before a transfer
748
data->set.quote = va_arg(param, struct curl_slist *);
750
case CURLOPT_PROGRESSFUNCTION:
752
* Progress callback function
754
data->set.fprogress = va_arg(param, curl_progress_callback);
755
data->progress.callback = TRUE; /* no longer internal */
757
case CURLOPT_PROGRESSDATA:
759
* Custom client data to pass to the progress callback
761
data->set.progress_client = va_arg(param, void *);
763
case CURLOPT_PASSWDFUNCTION:
765
* Password prompt callback
767
data->set.fpasswd = va_arg(param, curl_passwd_callback);
769
case CURLOPT_PASSWDDATA:
771
* Custom client data to pass to the password callback
773
data->set.passwd_client = va_arg(param, void *);
775
case CURLOPT_PROXYUSERPWD:
777
* user:password needed to use the proxy
779
data->set.proxyuserpwd = va_arg(param, char *);
783
* What range of the file you want to transfer
785
data->set.set_range = va_arg(param, char *);
787
case CURLOPT_RESUME_FROM:
789
* Resume transfer at the give file position
791
data->set.set_resume_from = va_arg(param, long);
795
* Set to a FILE * that should receive all error writes. This
796
* defaults to stderr for normal operations.
798
data->set.err = va_arg(param, FILE *);
800
case CURLOPT_HEADERFUNCTION:
802
* Set header write callback
804
data->set.fwrite_header = va_arg(param, curl_write_callback);
806
case CURLOPT_WRITEFUNCTION:
808
* Set data write callback
810
data->set.fwrite = va_arg(param, curl_write_callback);
812
case CURLOPT_READFUNCTION:
816
data->set.fread = va_arg(param, curl_read_callback);
818
case CURLOPT_SSLCERT:
820
* String that holds file name of the SSL certificate to use
822
data->set.cert = va_arg(param, char *);
824
case CURLOPT_SSLCERTTYPE:
826
* String that holds file type of the SSL certificate to use
828
data->set.cert_type = va_arg(param, char *);
832
* String that holds file name of the SSL certificate to use
834
data->set.key = va_arg(param, char *);
836
case CURLOPT_SSLKEYTYPE:
838
* String that holds file type of the SSL certificate to use
840
data->set.key_type = va_arg(param, char *);
842
case CURLOPT_SSLKEYPASSWD:
844
* String that holds the SSL private key password.
846
data->set.key_passwd = va_arg(param, char *);
848
case CURLOPT_SSLENGINE:
850
* String that holds the SSL crypto engine.
852
#ifdef HAVE_OPENSSL_ENGINE_H
854
const char *cpTemp = va_arg(param, char *);
856
if (cpTemp && cpTemp[0]) {
857
e = ENGINE_by_id(cpTemp);
860
ENGINE_free(data->engine);
865
failf(data, "SSL Engine '%s' not found", cpTemp);
866
return CURLE_SSL_ENGINE_NOTFOUND;
871
return CURLE_SSL_ENGINE_NOTFOUND;
874
case CURLOPT_SSLENGINE_DEFAULT:
876
* flag to set engine as default.
878
#ifdef HAVE_OPENSSL_ENGINE_H
880
if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) {
882
fprintf(stderr,"set default crypto engine\n");
887
failf(data, "set default crypto engine failed");
889
return CURLE_SSL_ENGINE_SETFAILED;
896
* Kludgy option to enable CRLF convertions. Subject for removal.
898
data->set.crlf = va_arg(param, long)?TRUE:FALSE;
900
case CURLOPT_INTERFACE:
902
* Set what interface to bind to when performing an operation and thus
903
* what from-IP your connection will use.
905
data->set.device = va_arg(param, char *);
907
case CURLOPT_KRB4LEVEL:
909
* A string that defines the krb4 security level.
911
data->set.krb4_level = va_arg(param, char *);
912
data->set.krb4=data->set.krb4_level?TRUE:FALSE;
914
case CURLOPT_SSL_VERIFYPEER:
916
* Enable peer SSL verifying.
918
data->set.ssl.verifypeer = va_arg(param, long);
920
case CURLOPT_SSL_VERIFYHOST:
922
* Enable verification of the CN contained in the peer certificate
924
data->set.ssl.verifyhost = va_arg(param, long);
928
* Set CA info for SSL connection. Specify file name of the CA certificate
930
data->set.ssl.CAfile = va_arg(param, char *);
931
data->set.ssl.CApath = NULL; /*This does not work on windows.*/
933
case CURLOPT_TELNETOPTIONS:
935
* Set a linked list of telnet options
937
data->set.telnet_options = va_arg(param, struct curl_slist *);
940
/* unknown tag and its companion, just ignore: */
941
return CURLE_READ_ERROR; /* correct this */
946
CURLcode Curl_disconnect(struct connectdata *conn)
949
return CURLE_OK; /* this is closed and fine already */
952
* The range string is usually freed in curl_done(), but we might
953
* get here *instead* if we fail prematurely. Thus we need to be able
954
* to free this resource here as well.
956
if(conn->bits.rangestringalloc) {
958
conn->bits.rangestringalloc = FALSE;
961
if(-1 != conn->connectindex) {
962
/* unlink ourselves! */
963
infof(conn->data, "Closing connection #%d\n", conn->connectindex);
964
conn->data->state.connects[conn->connectindex] = NULL;
967
if(conn->curl_disconnect)
968
/* This is set if protocol-specific cleanups should be made */
969
conn->curl_disconnect(conn);
971
if(conn->proto.generic)
972
free(conn->proto.generic);
977
if(conn->path) /* the URL path part */
981
Curl_SSL_Close(conn);
982
#endif /* USE_SSLEAY */
984
/* close possibly still open sockets */
985
if(-1 != conn->secondarysocket)
986
sclose(conn->secondarysocket);
987
if(-1 != conn->firstsocket)
988
sclose(conn->firstsocket);
990
if(conn->allocptr.proxyuserpwd)
991
free(conn->allocptr.proxyuserpwd);
992
if(conn->allocptr.uagent)
993
free(conn->allocptr.uagent);
994
if(conn->allocptr.userpwd)
995
free(conn->allocptr.userpwd);
996
if(conn->allocptr.rangeline)
997
free(conn->allocptr.rangeline);
998
if(conn->allocptr.ref)
999
free(conn->allocptr.ref);
1000
if(conn->allocptr.cookie)
1001
free(conn->allocptr.cookie);
1002
if(conn->allocptr.host)
1003
free(conn->allocptr.host);
1006
free(conn->proxyhost);
1008
free(conn); /* free all the connection oriented data */
1014
* This function should return TRUE if the socket is to be assumed to
1015
* be dead. Most commonly this happens when the server has closed the
1016
* connection due to inactivity.
1018
static bool SocketIsDead(int sock)
1021
bool ret_val = TRUE;
1025
FD_ZERO(&check_set);
1026
FD_SET(sock,&check_set);
1031
sval = select(sock + 1, &check_set, 0, 0, &to);
1040
* Given one filled in connection struct (named needle), this function should
1041
* detect if there already is one that have all the significant details
1042
* exactly the same and thus should be used instead.
1045
ConnectionExists(struct SessionHandle *data,
1046
struct connectdata *needle,
1047
struct connectdata **usethis)
1050
struct connectdata *check;
1052
for(i=0; i< data->state.numconnects; i++) {
1054
* Note that if we use a HTTP proxy, we check connections to that
1055
* proxy and not to the actual remote server.
1057
check = data->state.connects[i];
1059
/* NULL pointer means not filled-in entry */
1061
if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1062
/* The requested connection does not use a HTTP proxy or it
1065
if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1066
/* we don't do SSL but the cached connection has a proxy,
1067
then don't match this */
1070
if(strequal(needle->protostr, check->protostr) &&
1071
strequal(needle->name, check->name) &&
1072
(needle->remote_port == check->remote_port) ) {
1074
if(strequal(needle->protostr, "FTP")) {
1075
/* This is FTP, verify that we're using the same name and
1077
if(!strequal(needle->data->state.user, check->proto.ftp->user) ||
1078
!strequal(needle->data->state.passwd, check->proto.ftp->passwd)) {
1079
/* one of them was different */
1083
dead = SocketIsDead(check->firstsocket);
1086
* Even though the connection seems to have passed away, we could
1087
* still make an effort to get the name information, as we intend to
1088
* connect to the same host again.
1090
* This is now subject to discussion. What do you think?
1092
infof(data, "Connection %d seems to be dead!\n", i);
1093
Curl_disconnect(check); /* disconnect resources */
1094
data->state.connects[i]=NULL; /* nothing here */
1096
/* There's no need to continue search, because we only store
1097
one connection for each unique set of identifiers */
1102
return TRUE; /* yes, we found one to use! */
1106
else { /* The requested needle connection is using a proxy,
1107
is the checked one using the same? */
1108
if(check->bits.httpproxy &&
1109
strequal(needle->proxyhost, check->proxyhost) &&
1110
needle->port == check->port) {
1111
/* This is the same proxy connection, use it! */
1117
return FALSE; /* no matching connecting exists */
1121
* This function frees/closes a connection in the connection cache. This
1122
* should take the previously set policy into account when deciding which
1123
* of the connections to kill.
1126
ConnectionKillOne(struct SessionHandle *data)
1129
struct connectdata *conn;
1138
for(i=0; i< data->state.numconnects; i++) {
1139
conn = data->state.connects[i];
1145
* By using the set policy, we score each connection.
1147
switch(data->set.closepolicy) {
1148
case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
1151
* Set higher score for the age passed since the connection
1154
score = Curl_tvdiff(now, conn->now);
1156
case CURLCLOSEPOLICY_OLDEST:
1158
* Set higher score for the age passed since the connection
1161
score = Curl_tvdiff(now, conn->created);
1165
if(score > highscore) {
1170
if(connindex >= 0) {
1172
/* the winner gets the honour of being disconnected */
1173
result = Curl_disconnect(data->state.connects[connindex]);
1175
/* clean the array entry */
1176
data->state.connects[connindex] = NULL;
1179
return connindex; /* return the available index or -1 */
1183
* The given input connection struct pointer is to be stored. If the "cache"
1184
* is already full, we must clean out the most suitable using the previously
1187
* The given connection should be unique. That must've been checked prior to
1191
ConnectionStore(struct SessionHandle *data,
1192
struct connectdata *conn)
1195
for(i=0; i< data->state.numconnects; i++) {
1196
if(!data->state.connects[i])
1199
if(i == data->state.numconnects) {
1200
/* there was no room available, kill one */
1201
i = ConnectionKillOne(data);
1202
infof(data, "Connection (#%d) was killed to make room\n", i);
1206
/* only do this if a true index was returned, if -1 was returned there
1207
is no room in the cache for an unknown reason and we cannot store
1209
data->state.connects[i] = conn; /* fill in this */
1210
conn->connectindex = i; /* make the child know where the pointer to this
1211
particular data is stored */
1216
static CURLcode ConnectPlease(struct connectdata *conn)
1219
Curl_ipconnect *addr;
1221
/*************************************************************
1222
* Connect to server/proxy
1223
*************************************************************/
1224
result= Curl_connecthost(conn,
1229
if(CURLE_OK == result) {
1230
/* All is cool, then we store the current information from the hostaddr
1231
struct to the serv_addr, as it might be needed later. The address
1232
returned from the function above is crucial here. */
1234
conn->serv_addr = addr;
1236
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
1237
memcpy((char *)&(conn->serv_addr.sin_addr),
1238
(struct in_addr *)addr, sizeof(struct in_addr));
1239
conn->serv_addr.sin_family = conn->hostaddr->h_addrtype;
1240
conn->serv_addr.sin_port = htons(conn->port);
1247
static CURLcode CreateConnection(struct SessionHandle *data,
1248
struct connectdata **in_connect)
1252
CURLcode result=CURLE_OK;
1253
char resumerange[40]="";
1254
struct connectdata *conn;
1255
struct connectdata *conn_temp;
1258
#ifdef HAVE_INET_NTOA_R
1262
unsigned int prev_alarm;
1265
#ifdef HAVE_SIGACTION
1266
struct sigaction keep_sigact; /* store the old struct here */
1267
bool keep_copysig; /* did copy it? */
1270
void *keep_sigact; /* store the old handler here */
1274
/*************************************************************
1276
*************************************************************/
1278
if(!data->change.url)
1279
return CURLE_URL_MALFORMAT;
1281
/* First, split up the current URL in parts so that we can use the
1282
parts for checking against the already present connections. In order
1283
to not have to modify everything at once, we allocate a temporary
1284
connection data struct and fill in for comparison purposes. */
1286
conn = (struct connectdata *)malloc(sizeof(struct connectdata));
1288
*in_connect = NULL; /* clear the pointer */
1289
return CURLE_OUT_OF_MEMORY;
1291
/* We must set the return variable as soon as possible, so that our
1292
parent can cleanup any possible allocs we may have done before
1296
/* we have to init the struct */
1297
memset(conn, 0, sizeof(struct connectdata));
1299
/* and we setup a few fields in case we end up actually using this struct */
1300
conn->data = data; /* remember our daddy */
1301
conn->firstsocket = -1; /* no file descriptor */
1302
conn->secondarysocket = -1; /* no file descriptor */
1303
conn->connectindex = -1; /* no index */
1304
conn->bits.httpproxy = data->change.proxy?TRUE:FALSE; /* proxy-or-not */
1305
conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
1306
conn->range = data->set.set_range; /* clone the range setting */
1307
conn->resume_from = data->set.set_resume_from; /* inherite resume_from */
1309
/* Default protocol-independent behavior doesn't support persistant
1310
connections, so we set this to force-close. Protocols that support
1311
this need to set this to FALSE in their "curl_do" functions. */
1312
conn->bits.close = TRUE;
1314
/* inherite initial knowledge from the data struct */
1315
conn->bits.user_passwd = data->set.userpwd?1:0;
1316
conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
1318
/* maxdownload must be -1 on init, as 0 is a valid value! */
1319
conn->maxdownload = -1; /* might have been used previously! */
1321
/* Store creation time to help future close decision making */
1322
conn->created = Curl_tvnow();
1325
/***********************************************************
1326
* We need to allocate memory to store the path in. We get the size of the
1327
* full URL to be sure, and we need to make it at least 256 bytes since
1328
* other parts of the code will rely on this fact
1329
***********************************************************/
1330
#define LEAST_PATH_ALLOC 256
1331
urllen=strlen(data->change.url);
1332
if(urllen < LEAST_PATH_ALLOC)
1333
urllen=LEAST_PATH_ALLOC;
1335
conn->path=(char *)malloc(urllen);
1336
if(NULL == conn->path)
1337
return CURLE_OUT_OF_MEMORY; /* really bad error */
1339
/*************************************************************
1342
* We need to parse the url even when using the proxy, because we will need
1343
* the hostname and port in case we are trying to SSL connect through the
1344
* proxy -- and we don't know if we will need to use SSL until we parse the
1346
************************************************************/
1347
if((2 == sscanf(data->change.url, "%64[^:]://%[^\n]",
1349
conn->path)) && strequal(conn->protostr, "file")) {
1351
* we deal with file://<host>/<path> differently since it supports no
1352
* hostname other than "localhost" and "127.0.0.1", which is unique among
1353
* the URL protocols specified in RFC 1738
1355
if(conn->path[0] != '/') {
1356
/* the URL included a host name, we ignore host names in file:// URLs
1357
as the standards don't define what to do with them */
1358
char *ptr=strchr(conn->path, '/');
1360
/* there was a slash present
1362
RFC1738 (section 3.1, page 5) says:
1364
The rest of the locator consists of data specific to the scheme,
1365
and is known as the "url-path". It supplies the details of how the
1366
specified resource can be accessed. Note that the "/" between the
1367
host (or port) and the url-path is NOT part of the url-path.
1369
As most agents use file://localhost/foo to get '/foo' although the
1370
slash preceeding foo is a separator and not a slash for the path,
1371
a URL as file://localhost//foo must be valid as well, to refer to
1372
the same file with an absolute path.
1375
if(ptr[1] && ('/' == ptr[1]))
1376
/* if there was two slashes, we skip the first one as that is then
1377
used truly as a separator */
1380
strcpy(conn->path, ptr);
1384
strcpy(conn->protostr, "file"); /* store protocol string lowercase */
1387
/* Set default host and default path */
1388
strcpy(conn->gname, "curl.haxx.se");
1389
strcpy(conn->path, "/");
1391
if (2 > sscanf(data->change.url,
1392
"%64[^\n:]://%512[^\n/]%[^\n]",
1393
conn->protostr, conn->gname, conn->path)) {
1396
* The URL was badly formatted, let's try the browser-style _without_
1397
* protocol specified like 'http://'.
1399
if((1 > sscanf(data->change.url, "%512[^\n/]%[^\n]",
1400
conn->gname, conn->path)) ) {
1402
* We couldn't even get this format.
1404
failf(data, "<url> malformed");
1405
return CURLE_URL_MALFORMAT;
1409
* Since there was no protocol part specified, we guess what protocol it
1410
* is based on the first letters of the server name.
1413
if(strnequal(conn->gname, "FTP", 3)) {
1414
strcpy(conn->protostr, "ftp");
1416
else if(strnequal(conn->gname, "GOPHER", 6))
1417
strcpy(conn->protostr, "gopher");
1419
else if(strnequal(conn->gname, "HTTPS", 5))
1420
strcpy(conn->protostr, "https");
1421
else if(strnequal(conn->gname, "FTPS", 4))
1422
strcpy(conn->protostr, "ftps");
1423
#endif /* USE_SSLEAY */
1424
else if(strnequal(conn->gname, "TELNET", 6))
1425
strcpy(conn->protostr, "telnet");
1426
else if (strnequal(conn->gname, "DICT", sizeof("DICT")-1))
1427
strcpy(conn->protostr, "DICT");
1428
else if (strnequal(conn->gname, "LDAP", sizeof("LDAP")-1))
1429
strcpy(conn->protostr, "LDAP");
1431
strcpy(conn->protostr, "http");
1434
conn->protocol |= PROT_MISSING; /* not given in URL */
1438
buf = data->state.buffer; /* this is our buffer */
1440
/*************************************************************
1441
* Take care of user and password authentication stuff
1442
*************************************************************/
1444
if(conn->bits.user_passwd && !data->set.use_netrc) {
1445
data->state.user[0] =0;
1446
data->state.passwd[0]=0;
1448
if(*data->set.userpwd != ':') {
1449
/* the name is given, get user+password */
1450
sscanf(data->set.userpwd, "%127[^:]:%127[^\n]",
1451
data->state.user, data->state.passwd);
1454
/* no name given, get the password only */
1455
sscanf(data->set.userpwd+1, "%127[^\n]", data->state.passwd);
1457
/* check for password, if no ask for one */
1458
if( !data->state.passwd[0] ) {
1459
if(!data->set.fpasswd ||
1460
data->set.fpasswd(data->set.passwd_client,
1461
"password:", data->state.passwd,
1462
sizeof(data->state.passwd)))
1463
return CURLE_BAD_PASSWORD_ENTERED;
1467
/*************************************************************
1468
* Take care of proxy authentication stuff
1469
*************************************************************/
1470
if(conn->bits.proxy_user_passwd) {
1471
data->state.proxyuser[0] =0;
1472
data->state.proxypasswd[0]=0;
1474
if(*data->set.proxyuserpwd != ':') {
1475
/* the name is given, get user+password */
1476
sscanf(data->set.proxyuserpwd, "%127[^:]:%127[^\n]",
1477
data->state.proxyuser, data->state.proxypasswd);
1480
/* no name given, get the password only */
1481
sscanf(data->set.proxyuserpwd+1, "%127[^\n]", data->state.proxypasswd);
1483
/* check for password, if no ask for one */
1484
if( !data->state.proxypasswd[0] ) {
1485
if(!data->set.fpasswd ||
1486
data->set.fpasswd( data->set.passwd_client,
1488
data->state.proxypasswd,
1489
sizeof(data->state.proxypasswd)))
1490
return CURLE_BAD_PASSWORD_ENTERED;
1495
/*************************************************************
1496
* Set a few convenience pointers
1497
*************************************************************/
1498
conn->name = conn->gname;
1499
conn->ppath = conn->path;
1500
conn->hostname = conn->name;
1503
/*************************************************************
1504
* Detect what (if any) proxy to use
1505
*************************************************************/
1506
if(!data->change.proxy) {
1507
/* If proxy was not specified, we check for default proxy environment
1508
* variables, to enable i.e Lynx compliance:
1510
* http_proxy=http://some.server.dom:port/
1511
* https_proxy=http://some.server.dom:port/
1512
* ftp_proxy=http://some.server.dom:port/
1513
* gopher_proxy=http://some.server.dom:port/
1514
* no_proxy=domain1.dom,host.domain2.dom
1515
* (a comma-separated list of hosts which should
1516
* not be proxied, or an asterisk to override
1517
* all proxy variables)
1518
* all_proxy=http://some.server.dom:port/
1519
* (seems to exist for the CERN www lib. Probably
1520
* the first to check for.)
1522
* For compatibility, the all-uppercase versions of these variables are
1523
* checked if the lowercase versions don't exist.
1525
char *no_proxy=NULL;
1526
char *no_proxy_tok_buf;
1528
char proxy_env[128];
1530
no_proxy=curl_getenv("no_proxy");
1532
no_proxy=curl_getenv("NO_PROXY");
1534
if(!no_proxy || !strequal("*", no_proxy)) {
1535
/* NO_PROXY wasn't specified or it wasn't just an asterisk */
1538
nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
1540
if(strlen(nope) <= strlen(conn->name)) {
1542
conn->name + strlen(conn->name) - strlen(nope);
1543
if(strnequal(nope, checkn, strlen(nope))) {
1544
/* no proxy for this host! */
1548
nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
1551
/* It was not listed as without proxy */
1552
char *protop = conn->protostr;
1553
char *envp = proxy_env;
1556
/* Now, build <protocol>_proxy and check for such a one to use */
1558
*envp++ = tolower(*protop++);
1561
strcpy(envp, "_proxy");
1563
/* read the protocol proxy: */
1564
prox=curl_getenv(proxy_env);
1567
* We don't try the uppercase version of HTTP_PROXY because of
1570
* When curl is used in a webserver application
1571
* environment (cgi or php), this environment variable can
1572
* be controlled by the web server user by setting the
1573
* http header 'Proxy:' to some value.
1575
* This can cause 'internal' http/ftp requests to be
1576
* arbitrarily redirected by any external attacker.
1578
if(!prox && !strequal("http_proxy", proxy_env)) {
1579
/* There was no lowercase variable, try the uppercase version: */
1580
for(envp = proxy_env; *envp; envp++)
1581
*envp = toupper(*envp);
1582
prox=curl_getenv(proxy_env);
1585
if(prox && *prox) { /* don't count "" strings */
1586
proxy = prox; /* use this */
1589
proxy = curl_getenv("all_proxy"); /* default proxy to use */
1591
proxy=curl_getenv("ALL_PROXY");
1594
if(proxy && *proxy) {
1595
/* we have a proxy here to set */
1596
data->change.proxy = proxy;
1597
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
1598
conn->bits.httpproxy = TRUE;
1600
} /* if (!nope) - it wasn't specified non-proxy */
1601
} /* NO_PROXY wasn't specified or '*' */
1604
} /* if not using proxy */
1606
/*************************************************************
1607
* No protocol part in URL was used, add it!
1608
*************************************************************/
1609
if(conn->protocol&PROT_MISSING) {
1610
/* We're guessing prefixes here and if we're told to use a proxy or if
1611
we're gonna follow a Location: later or... then we need the protocol
1612
part added so that we have a valid URL. */
1615
reurl = aprintf("%s://%s", conn->protostr, data->change.url);
1618
return CURLE_OUT_OF_MEMORY;
1620
data->change.url = reurl;
1621
data->change.url_alloc = TRUE; /* free this later */
1622
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
1625
/************************************************************
1626
* RESUME on a HTTP page is a tricky business. First, let's just check that
1627
* 'range' isn't used, then set the range parameter and leave the resume as
1628
* it is to inform about this situation for later use. We will then
1629
* "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
1630
* server, we will get the document resumed. If we talk to a HTTP/1.0
1631
* server, we just fail since we can't rewind the file writing from within
1633
***********************************************************/
1634
if(conn->resume_from) {
1635
if(!conn->bits.use_range) {
1636
/* if it already was in use, we just skip this */
1637
snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from);
1638
conn->range=strdup(resumerange); /* tell ourselves to fetch this range */
1639
conn->bits.rangestringalloc = TRUE; /* mark as allocated */
1640
conn->bits.use_range = 1; /* switch on range usage */
1644
/*************************************************************
1645
* Setup internals depending on protocol
1646
*************************************************************/
1648
if (strequal(conn->protostr, "HTTP")) {
1649
conn->port = (data->set.use_port && data->state.allow_port)?
1650
data->set.use_port:PORT_HTTP;
1651
conn->remote_port = PORT_HTTP;
1652
conn->protocol |= PROT_HTTP;
1653
conn->curl_do = Curl_http;
1654
conn->curl_done = Curl_http_done;
1655
conn->curl_connect = Curl_http_connect;
1657
else if (strequal(conn->protostr, "HTTPS")) {
1660
conn->port = (data->set.use_port && data->state.allow_port)?
1661
data->set.use_port:PORT_HTTPS;
1662
conn->remote_port = PORT_HTTPS;
1663
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
1665
conn->curl_do = Curl_http;
1666
conn->curl_done = Curl_http_done;
1667
conn->curl_connect = Curl_http_connect;
1669
#else /* USE_SSLEAY */
1670
failf(data, LIBCURL_NAME
1671
" was built with SSL disabled, https: not supported!");
1672
return CURLE_UNSUPPORTED_PROTOCOL;
1673
#endif /* !USE_SSLEAY */
1675
else if (strequal(conn->protostr, "GOPHER")) {
1676
conn->port = (data->set.use_port && data->state.allow_port)?
1677
data->set.use_port:PORT_GOPHER;
1678
conn->remote_port = PORT_GOPHER;
1679
/* Skip /<item-type>/ in path if present */
1680
if (isdigit((int)conn->path[1])) {
1681
conn->ppath = strchr(&conn->path[1], '/');
1682
if (conn->ppath == NULL)
1683
conn->ppath = conn->path;
1685
conn->protocol |= PROT_GOPHER;
1686
conn->curl_do = Curl_http;
1687
conn->curl_done = Curl_http_done;
1689
else if(strequal(conn->protostr, "FTP") ||
1690
strequal(conn->protostr, "FTPS")) {
1693
if(strequal(conn->protostr, "FTPS")) {
1695
conn->protocol |= PROT_FTPS|PROT_SSL;
1697
failf(data, LIBCURL_NAME
1698
" was built with SSL disabled, ftps: not supported!");
1699
return CURLE_UNSUPPORTED_PROTOCOL;
1700
#endif /* !USE_SSLEAY */
1703
conn->port = (data->set.use_port && data->state.allow_port)?
1704
data->set.use_port:PORT_FTP;
1705
conn->remote_port = PORT_FTP;
1706
conn->protocol |= PROT_FTP;
1708
if(data->change.proxy &&
1709
!data->set.tunnel_thru_httpproxy) {
1710
/* Unless we have asked to tunnel ftp operations through the proxy, we
1711
switch and use HTTP operations only */
1712
if(conn->protocol & PROT_FTPS) {
1713
/* FTPS is a hacked protocol and does not work through your
1714
ordinary http proxy! */
1715
failf(data, "ftps does not work through http proxy!");
1716
return CURLE_UNSUPPORTED_PROTOCOL;
1718
conn->curl_do = Curl_http;
1719
conn->curl_done = Curl_http_done;
1722
conn->curl_do = Curl_ftp;
1723
conn->curl_done = Curl_ftp_done;
1724
conn->curl_connect = Curl_ftp_connect;
1725
conn->curl_disconnect = Curl_ftp_disconnect;
1728
conn->ppath++; /* don't include the initial slash */
1730
/* FTP URLs support an extension like ";type=<typecode>" that
1731
* we'll try to get now! */
1732
type=strstr(conn->ppath, ";type=");
1734
type=strstr(conn->gname, ";type=");
1739
command = toupper(type[6]);
1741
case 'A': /* ASCII mode */
1742
data->set.ftp_ascii = 1;
1744
case 'D': /* directory mode */
1745
data->set.ftp_list_only = 1;
1747
case 'I': /* binary mode */
1749
/* switch off ASCII */
1750
data->set.ftp_ascii = 0;
1755
else if(strequal(conn->protostr, "TELNET")) {
1756
/* telnet testing factory */
1757
conn->protocol |= PROT_TELNET;
1759
conn->port = (data->set.use_port && data->state.allow_port)?
1760
data->set.use_port: PORT_TELNET;
1761
conn->remote_port = PORT_TELNET;
1762
conn->curl_do = Curl_telnet;
1763
conn->curl_done = Curl_telnet_done;
1765
else if (strequal(conn->protostr, "DICT")) {
1766
conn->protocol |= PROT_DICT;
1767
conn->port = (data->set.use_port && data->state.allow_port)?
1768
data->set.use_port:PORT_DICT;
1769
conn->remote_port = PORT_DICT;
1770
conn->curl_do = Curl_dict;
1771
conn->curl_done = NULL; /* no DICT-specific done */
1773
else if (strequal(conn->protostr, "LDAP")) {
1774
conn->protocol |= PROT_LDAP;
1775
conn->port = (data->set.use_port && data->state.allow_port)?
1776
data->set.use_port:PORT_LDAP;
1777
conn->remote_port = PORT_LDAP;
1778
conn->curl_do = Curl_ldap;
1779
conn->curl_done = NULL; /* no LDAP-specific done */
1781
else if (strequal(conn->protostr, "FILE")) {
1782
conn->protocol |= PROT_FILE;
1784
conn->curl_do = Curl_file;
1785
/* no done() function */
1787
/* anyway, this is supposed to be the connect function so we better
1788
at least check that the file is present here! */
1789
result = Curl_file_connect(conn);
1791
/* Setup a "faked" transfer that'll do nothing */
1792
if(CURLE_OK == result) {
1793
result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
1794
-1, NULL); /* no upload */
1800
/* We fell through all checks and thus we don't support the specified
1802
failf(data, "Unsupported protocol: %s", conn->protostr);
1803
return CURLE_UNSUPPORTED_PROTOCOL;
1806
/*************************************************************
1807
* .netrc scanning coming up
1808
*************************************************************/
1809
if(data->set.use_netrc) {
1810
if(Curl_parsenetrc(conn->hostname,
1812
data->state.passwd)) {
1813
infof(data, "Couldn't find host %s in the .netrc file, using defaults",
1817
conn->bits.user_passwd = 1; /* enable user+password */
1819
/* weather we failed or not, we don't know which fields that were filled
1821
if(!data->state.user[0])
1822
strcpy(data->state.user, CURL_DEFAULT_USER);
1823
if(!data->state.passwd[0])
1824
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
1826
else if(!(conn->bits.user_passwd) &&
1827
(conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
1828
/* This is a FTP or HTTP URL, and we haven't got the user+password in
1829
* the extra parameter, we will now try to extract the possible
1830
* user+password pair in a string like:
1831
* ftp://user:password@ftp.my.site:8021/README */
1832
char *ptr=NULL; /* assign to remove possible warnings */
1833
if((ptr=strchr(conn->name, '@'))) {
1834
/* there's a user+password given here, to the left of the @ */
1836
data->state.user[0] =0;
1837
data->state.passwd[0]=0;
1839
if(*conn->name != ':') {
1840
/* the name is given, get user+password */
1841
sscanf(conn->name, "%127[^:@]:%127[^@]",
1842
data->state.user, data->state.passwd);
1845
/* no name given, get the password only */
1846
sscanf(conn->name+1, "%127[^@]", data->state.passwd);
1848
if(data->state.user[0]) {
1849
char *newname=curl_unescape(data->state.user, 0);
1850
if(strlen(newname) < sizeof(data->state.user)) {
1851
strcpy(data->state.user, newname);
1853
/* if the new name is longer than accepted, then just use
1854
the unconverted name, it'll be wrong but what the heck */
1858
/* check for password, if no ask for one */
1859
if( !data->state.passwd[0] ) {
1860
if(!data->set.fpasswd ||
1861
data->set.fpasswd(data->set.passwd_client,
1862
"password:", data->state.passwd,
1863
sizeof(data->state.passwd)))
1864
return CURLE_BAD_PASSWORD_ENTERED;
1867
/* we have a password found in the URL, decode it! */
1868
char *newpasswd=curl_unescape(data->state.passwd, 0);
1869
if(strlen(newpasswd) < sizeof(data->state.passwd)) {
1870
strcpy(data->state.passwd, newpasswd);
1876
conn->bits.user_passwd=TRUE; /* enable user+password */
1879
strcpy(data->state.user, CURL_DEFAULT_USER);
1880
strcpy(data->state.passwd, CURL_DEFAULT_PASSWORD);
1884
/*************************************************************
1885
* Figure out the remote port number
1887
* No matter if we use a proxy or not, we have to figure out the remote
1888
* port number of various reasons.
1890
* To be able to detect port number flawlessly, we must not confuse them
1891
* IPv6-specified addresses in the [0::1] style. (RFC2732)
1892
*************************************************************/
1894
if((1 == sscanf(conn->name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
1895
(']' == endbracket)) {
1896
/* This is a (IPv6-style) specified IP-address. We support _any_
1897
IP within brackets to be really generic. */
1898
conn->name++; /* pass the starting bracket */
1900
tmp = strchr(conn->name, ']');
1901
*tmp = 0; /* zero terminate */
1903
tmp++; /* pass the ending bracket */
1905
tmp = NULL; /* no port number available */
1908
/* traditional IPv4-style port-extracting */
1909
tmp = strchr(conn->name, ':');
1913
*tmp++ = '\0'; /* cut off the name there */
1914
conn->remote_port = atoi(tmp);
1917
if(data->change.proxy) {
1918
/* If this is supposed to use a proxy, we need to figure out the proxy
1919
host name name, so that we can re-use an existing connection
1920
that may exist registered to the same proxy host. */
1925
/* We need to make a duplicate of the proxy so that we can modify the
1927
char *proxydup=strdup(data->change.proxy);
1929
/* We use 'proxyptr' to point to the proxy name from now on... */
1930
char *proxyptr=proxydup;
1932
if(NULL == proxydup) {
1933
failf(data, "memory shortage");
1934
return CURLE_OUT_OF_MEMORY;
1937
/* Daniel Dec 10, 1998:
1938
We do the proxy host string parsing here. We want the host name and the
1939
port name. Accept a protocol:// prefix, even though it should just be
1942
/* 1. skip the protocol part if present */
1943
endofprot=strstr(proxyptr, "://");
1945
proxyptr = endofprot+3;
1948
/* allow user to specify proxy.server.com:1080 if desired */
1949
prox_portno = strchr (proxyptr, ':');
1951
*prox_portno = 0x0; /* cut off number from host name */
1953
/* now set the local port number */
1954
conn->port = atoi(prox_portno);
1956
else if(data->set.proxyport) {
1957
/* None given in the proxy string, then get the default one if it is
1959
conn->port = data->set.proxyport;
1962
/* now, clone the cleaned proxy host name */
1963
conn->proxyhost = strdup(proxyptr);
1965
free(proxydup); /* free the duplicate pointer and not the modified */
1968
/*************************************************************
1969
* Check the current list of connections to see if we can
1970
* re-use an already existing one or if we have to create a
1972
*************************************************************/
1974
/* reuse_fresh is set TRUE if we are told to use a fresh connection
1976
if(!data->set.reuse_fresh &&
1977
ConnectionExists(data, conn, &conn_temp)) {
1979
* We already have a connection for this, we got the former connection
1980
* in the conn_temp variable and thus we need to cleanup the one we
1981
* just allocated before we can move along and use the previously
1984
struct connectdata *old_conn = conn;
1985
char *path = old_conn->path; /* setup the current path pointer properly */
1986
char *ppath = old_conn->ppath; /* this is the modified path pointer */
1987
if(old_conn->proxyhost)
1988
free(old_conn->proxyhost);
1989
conn = conn_temp; /* use this connection from now on */
1991
/* we need these pointers if we speak over a proxy */
1992
conn->hostname = conn->gname;
1993
conn->name = &conn->gname[old_conn->name - old_conn->gname];
1995
free(conn->path); /* free the previously allocated path pointer */
1997
/* 'path' points to the allocated data, 'ppath' may have been advanced
1998
to point somewhere within the 'path' area. */
2000
conn->ppath = ppath;
2003
conn->bits.reuse = TRUE; /* yes, we're re-using here */
2004
conn->bits.chunk = FALSE; /* always assume not chunked unless told
2006
conn->maxdownload = -1; /* might have been used previously! */
2008
free(old_conn); /* we don't need this anymore */
2011
* If we're doing a resumed transfer, we need to setup our stuff
2014
conn->resume_from = data->set.set_resume_from;
2015
if (conn->resume_from) {
2016
snprintf(resumerange, sizeof(resumerange), "%d-", conn->resume_from);
2017
if (conn->bits.rangestringalloc == TRUE)
2020
/* tell ourselves to fetch this range */
2021
conn->range = strdup(resumerange);
2022
conn->bits.use_range = TRUE; /* enable range download */
2023
conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
2025
else if (data->set.set_range) {
2026
/* There is a range, but is not a resume, useful for random ftp access */
2027
conn->range = strdup(data->set.set_range);
2028
conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
2029
conn->bits.use_range = TRUE; /* enable range download */
2032
*in_connect = conn; /* return this instead! */
2034
infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
2038
* This is a brand new connection, so let's store it in the connection
2041
ConnectionStore(data, conn);
2044
/*************************************************************
2045
* Set timeout if that is being used
2046
*************************************************************/
2047
if(data->set.timeout || data->set.connecttimeout) {
2048
/*************************************************************
2049
* Set signal handler to catch SIGALRM
2050
* Store the old value to be able to set it back later!
2051
*************************************************************/
2053
#ifdef HAVE_SIGACTION
2054
struct sigaction sigact;
2055
sigaction(SIGALRM, NULL, &sigact);
2056
keep_sigact = sigact;
2057
keep_copysig = TRUE; /* yes, we have a copy */
2058
sigact.sa_handler = alarmfunc;
2060
/* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
2061
sigact.sa_flags &= ~SA_RESTART;
2063
/* now set the new struct */
2064
sigaction(SIGALRM, &sigact, NULL);
2066
/* no sigaction(), revert to the much lamer signal() */
2068
keep_sigact = signal(SIGALRM, alarmfunc);
2072
/* We set the timeout on the name resolving phase first, separately from
2073
* the download/upload part to allow a maximum time on everything. This is
2074
* a signal-based timeout, why it won't work and shouldn't be used in
2075
* multi-threaded environments. */
2078
/* alarm() makes a signal get sent when the timeout fires off, and that
2079
will abort system calls */
2080
prev_alarm = alarm(data->set.connecttimeout?
2081
data->set.connecttimeout:
2083
/* We can expect the conn->created time to be "now", as that was just
2084
recently set in the beginning of this function and nothing slow
2085
has been done since then until now. */
2089
/*************************************************************
2090
* Resolve the name of the server or proxy
2091
*************************************************************/
2092
if(!data->change.proxy) {
2093
/* If not connecting via a proxy, extract the port from the URL, if it is
2094
* there, thus overriding any defaults that might have been set above. */
2095
conn->port = conn->remote_port; /* it is the same port */
2097
/* Resolve target host right on */
2098
if(!conn->hostaddr) {
2099
/* it might already be set if reusing a connection */
2100
conn->hostaddr = Curl_resolv(data, conn->name, conn->port,
2101
&conn->hostent_buf);
2103
if(!conn->hostaddr) {
2104
failf(data, "Couldn't resolve host '%s'", conn->name);
2105
result = CURLE_COULDNT_RESOLVE_HOST;
2106
/* don't return yet, we need to clean up the timeout first */
2109
else if(!conn->hostaddr) {
2110
/* This is a proxy that hasn't been resolved yet. It may be resolved
2111
if we're reusing an existing connection. */
2114
/* it might already be set if reusing a connection */
2115
conn->hostaddr = Curl_resolv(data, conn->proxyhost, conn->port,
2116
&conn->hostent_buf);
2118
if(!conn->hostaddr) {
2119
failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
2120
result = CURLE_COULDNT_RESOLVE_PROXY;
2121
/* don't return yet, we need to clean up the timeout first */
2124
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
2126
if(data->set.timeout || data->set.connecttimeout) {
2127
#ifdef HAVE_SIGACTION
2129
/* we got a struct as it looked before, now put that one back nice
2131
sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
2135
/* restore the previous SIGALRM handler */
2136
signal(SIGALRM, keep_sigact);
2139
/* switch back the alarm() to either zero or to what it was before minus
2140
the time we spent until now! */
2142
/* there was an alarm() set before us, now put it back */
2143
long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
2146
/* the alarm period is counted in even number of seconds */
2147
alarm_set = prev_alarm - elapsed_ms/1000;
2150
/* if it turned negative, we should fire off a SIGALRM here, but we
2151
won't, and zero would be to switch it off so we never set it to
2154
result = CURLE_OPERATION_TIMEOUTED;
2155
failf(data, "Previous alarm fired off!");
2161
alarm(0); /* just shut it off */
2167
/*************************************************************
2168
* Proxy authentication
2169
*************************************************************/
2170
if(conn->bits.proxy_user_passwd) {
2171
char *authorization;
2172
snprintf(data->state.buffer, BUFSIZE, "%s:%s",
2173
data->state.proxyuser, data->state.proxypasswd);
2174
if(Curl_base64_encode(data->state.buffer, strlen(data->state.buffer),
2175
&authorization) >= 0) {
2176
if(conn->allocptr.proxyuserpwd)
2177
free(conn->allocptr.proxyuserpwd);
2178
conn->allocptr.proxyuserpwd =
2179
aprintf("Proxy-authorization: Basic %s\015\012", authorization);
2180
free(authorization);
2184
/*************************************************************
2185
* Send user-agent to HTTP proxies even if the target protocol
2187
*************************************************************/
2188
if((conn->protocol&PROT_HTTP) || data->change.proxy) {
2189
if(data->set.useragent) {
2190
if(conn->allocptr.uagent)
2191
free(conn->allocptr.uagent);
2192
conn->allocptr.uagent =
2193
aprintf("User-Agent: %s\015\012", data->set.useragent);
2197
if(-1 == conn->firstsocket) {
2198
/* Connect only if not already connected! */
2199
result = ConnectPlease(conn);
2200
if(CURLE_OK != result)
2203
if(conn->curl_connect) {
2204
/* is there a connect() procedure? */
2206
/* set start time here for timeout purposes in the
2207
* connect procedure, it is later set again for the
2208
* progress meter purpose */
2209
conn->now = Curl_tvnow();
2211
/* Call the protocol-specific connect function */
2212
result = conn->curl_connect(conn);
2213
if(result != CURLE_OK)
2214
return result; /* pass back errors */
2218
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */
2220
conn->now = Curl_tvnow(); /* time this *after* the connect is done */
2221
conn->bytecount = 0;
2222
conn->headerbytecount = 0;
2224
/* Figure out the ip-number and display the first host name it shows: */
2227
char hbuf[NI_MAXHOST];
2228
#ifdef NI_WITHSCOPEID
2229
const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
2231
const int niflags = NI_NUMERICHOST;
2233
struct addrinfo *ai = conn->serv_addr;
2235
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
2237
snprintf(hbuf, sizeof(hbuf), "?");
2239
if (ai->ai_canonname) {
2240
infof(data, "Connected to %s (%s) port %d\n", ai->ai_canonname, hbuf,
2243
infof(data, "Connected to %s port %d\n", hbuf, conn->port);
2249
(void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
2250
infof(data, "Connected to %s (%s)\n", conn->hostaddr->h_name,
2251
#if defined(HAVE_INET_NTOA_R)
2252
inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf))
2262
* the check is quite a hack...
2263
* we're calling _fsetmode to fix the problem with fwrite converting newline
2264
* characters (you get mangled text files, and corrupted binary files when
2265
* you download to stdout and redirect it to a file). */
2267
if ((data->set.out)->_handle == NULL) {
2268
_fsetmode(stdout, "b");
2275
CURLcode Curl_connect(struct SessionHandle *data,
2276
struct connectdata **in_connect)
2279
struct connectdata *conn;
2281
/* call the stuff that needs to be called */
2282
code = CreateConnection(data, in_connect);
2284
if(CURLE_OK != code) {
2285
/* We're not allowed to return failure with memory left allocated
2286
in the connectdata struct, free those here */
2287
conn = (struct connectdata *)*in_connect;
2289
Curl_disconnect(conn); /* close the connection */
2290
*in_connect = NULL; /* return a NULL */
2297
CURLcode Curl_done(struct connectdata *conn)
2299
struct SessionHandle *data=conn->data;
2302
/* cleanups done even if the connection is re-used */
2304
if(conn->bits.rangestringalloc) {
2306
conn->bits.rangestringalloc = FALSE;
2309
/* Cleanup possible redirect junk */
2312
conn->newurl = NULL;
2315
/* this calls the protocol-specific function pointer previously set */
2317
result = conn->curl_done(conn);
2321
Curl_pgrsDone(conn); /* done with the operation */
2323
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
2324
forced us to close this no matter what we think.
2326
if conn->bits.close is TRUE, it means that the connection should be
2327
closed in spite of all our efforts to be nice, due to protocol
2328
restrictions in our or the server's end */
2329
if(data->set.reuse_forbid ||
2330
((CURLE_OK == result) && conn->bits.close))
2331
result = Curl_disconnect(conn); /* close the connection */
2333
infof(data, "Connection #%d left intact\n", conn->connectindex);
2338
CURLcode Curl_do(struct connectdata **connp)
2340
CURLcode result=CURLE_OK;
2341
struct connectdata *conn = *connp;
2342
struct SessionHandle *data=conn->data;
2345
/* generic protocol-specific function pointer set in curl_connect() */
2346
result = conn->curl_do(conn);
2348
/* This was formerly done in transfer.c, but we better do it here */
2350
if((CURLE_WRITE_ERROR == result) && conn->bits.reuse) {
2351
/* This was a re-use of a connection and we got a write error in the
2352
* DO-phase. Then we DISCONNECT this connection and have another attempt
2353
* to CONNECT and then DO again! The retry cannot possibly find another
2354
* connection to re-use, since we only keep one possible connection for
2357
infof(data, "Re-used connection seems dead, get a new one\n");
2359
conn->bits.close = TRUE; /* enforce close of this connetion */
2360
result = Curl_done(conn); /* we are so done with this */
2361
if(CURLE_OK == result) {
2362
/* Now, redo the connect and get a new connection */
2363
result = Curl_connect(data, connp);
2364
if(CURLE_OK == result)
2365
/* ... finally back to actually retry the DO phase */
2366
result = conn->curl_do(*connp);
2375
* eval: (load-file "../curl-mode.el")
2377
* vim600: fdm=marker
2378
* vim: et sw=2 ts=2 sts=2 tw=78