1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
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.3 2007-05-03 17:03:13 king Exp $
22 ***************************************************************************/
24 /* -- WIN32 approved -- */
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
36 #ifdef HAVE_SYS_STAT_H
45 #ifdef HAVE_SYS_SOCKET_H
46 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #ifdef HAVE_SYS_TIME_H
56 #ifdef HAVE_ARPA_INET_H
57 #include <arpa/inet.h>
62 #include <sys/ioctl.h>
65 #ifdef HAVE_SYS_PARAM_H
66 #include <sys/param.h>
79 #error "We can't compile without socket() support!"
86 #include <stringprep.h>
87 #ifdef HAVE_IDN_FREE_H
90 void idn_free (void *ptr
); /* prototype from idn-free.h, not provided by
91 libidn 0.4.5's make install! */
94 /* if idn_free() was not found in this version of libidn, use plain free()
96 #define idn_free(x) (free)(x)
98 #endif /* USE_LIBIDN */
103 #include "formdata.h"
107 #include "transfer.h"
109 #include "progress.h"
111 #include "strequal.h"
112 #include "strerror.h"
116 #include "content_encoding.h"
117 #include "http_digest.h"
118 #include "http_negotiate.h"
123 /* And now for the protocols */
134 #include "inet_ntop.h"
135 #include "http_ntlm.h"
137 #include <ca-bundle.h>
139 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
140 #include "inet_ntoa_r.h"
143 #define _MPRINTF_REPLACE /* use our functions only */
144 #include <curl/mprintf.h>
151 /* The last #include file should be: */
152 #include "memdebug.h"
154 /* Local static prototypes */
155 static long ConnectionKillOne(struct SessionHandle
*data
);
156 static bool ConnectionExists(struct SessionHandle
*data
,
157 struct connectdata
*needle
,
158 struct connectdata
**usethis
);
159 static long ConnectionStore(struct SessionHandle
*data
,
160 struct connectdata
*conn
);
161 static bool IsPipeliningPossible(struct SessionHandle
*handle
);
162 static bool IsPipeliningEnabled(struct SessionHandle
*handle
);
163 static void conn_free(struct connectdata
*conn
);
165 static void signalPipeClose(struct curl_llist
*pipe
);
167 #define MAX_PIPELINE_LENGTH 5
170 * We use this ZERO_NULL to avoid picky compiler warnings,
171 * when assigning a NULL pointer to a function pointer var.
177 /* not for ares builds */
180 /* not for WIN32 builds */
182 #ifdef HAVE_SIGSETJMP
183 extern sigjmp_buf curl_jmpenv
;
188 RETSIGTYPE
alarmfunc(int sig
)
190 /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
192 #ifdef HAVE_SIGSETJMP
193 siglongjmp(curl_jmpenv
, 1);
195 /*return;*/ /* not reahed, and has no effect anyway */
199 #endif /* USE_ARES */
201 void Curl_safefree(void *ptr
)
207 static void close_connections(struct SessionHandle
*data
)
209 /* Loop through all open connections and kill them one by one */
210 while(-1 != ConnectionKillOne(data
))
215 * This is the internal function curl_easy_cleanup() calls. This should
216 * cleanup and free all resources associated with this sessionhandle.
218 * NOTE: if we ever add something that attempts to write to a socket or
219 * similar here, we must ignore SIGPIPE first. It is currently only done
220 * when curl_easy_perform() is invoked.
223 CURLcode
Curl_close(struct SessionHandle
*data
)
225 struct Curl_multi
*m
= data
->multi
;
228 /* only for debugging, scan through all connections and see if there's a
229 pipe reference still identifying this handle */
231 if(data
->state
.is_in_pipeline
)
232 fprintf(stderr
, "CLOSED when in pipeline!\n");
234 if(data
->state
.connc
&& data
->state
.connc
->type
== CONNCACHE_MULTI
) {
235 struct conncache
*c
= data
->state
.connc
;
237 struct curl_llist
*pipe
;
238 struct curl_llist_element
*curr
;
239 struct connectdata
*connptr
;
241 for(i
=0; i
< c
->num
; i
++) {
242 connptr
= c
->connects
[i
];
246 pipe
= connptr
->send_pipe
;
248 for (curr
= pipe
->head
; curr
; curr
=curr
->next
) {
249 if(data
== (struct SessionHandle
*) curr
->ptr
) {
251 "MAJOR problem we %p are still in send pipe for %p done %d\n",
252 data
, connptr
, connptr
->bits
.done
);
256 pipe
= connptr
->recv_pipe
;
258 for (curr
= pipe
->head
; curr
; curr
=curr
->next
) {
259 if(data
== (struct SessionHandle
*) curr
->ptr
) {
261 "MAJOR problem we %p are still in recv pipe for %p done %d\n",
262 data
, connptr
, connptr
->bits
.done
);
271 /* This handle is still part of a multi handle, take care of this first
272 and detach this handle from there. */
273 Curl_multi_rmeasy(data
->multi
, data
);
275 data
->magic
= 0; /* force a clear AFTER the possibly enforced removal from
276 the multi handle, since that function uses the magic
279 if(data
->state
.connc
) {
281 if(data
->state
.connc
->type
== CONNCACHE_PRIVATE
) {
282 /* close all connections still alive that are in the private connection
283 cache, as we no longer have the pointer left to the shared one. */
284 close_connections(data
);
286 /* free the connection cache if allocated privately */
287 Curl_rm_connc(data
->state
.connc
);
291 if(data
->state
.shared_conn
) {
292 /* marked to be used by a pending connection so we can't kill this handle
294 data
->state
.closed
= TRUE
;
298 if ( ! (data
->share
&& data
->share
->hostcache
) ) {
299 if ( !Curl_global_host_cache_use(data
)) {
300 Curl_hash_destroy(data
->dns
.hostcache
);
304 /* Free the pathbuffer */
305 Curl_safefree(data
->reqdata
.pathbuffer
);
306 Curl_safefree(data
->reqdata
.proto
.generic
);
308 /* Close down all open SSL info and sessions */
309 Curl_ssl_close_all(data
);
310 Curl_safefree(data
->state
.first_host
);
311 Curl_safefree(data
->state
.scratch
);
313 if(data
->change
.referer_alloc
)
314 free(data
->change
.referer
);
316 if(data
->change
.url_alloc
)
317 free(data
->change
.url
);
319 Curl_safefree(data
->state
.headerbuff
);
321 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
322 Curl_share_lock(data
, CURL_LOCK_DATA_COOKIE
, CURL_LOCK_ACCESS_SINGLE
);
323 if(data
->set
.cookiejar
) {
324 if(data
->change
.cookielist
) {
325 /* If there is a list of cookie files to read, do it first so that
326 we have all the told files read before we write the new jar */
327 Curl_cookie_loadfiles(data
);
330 /* we have a "destination" for all the cookies to get dumped to */
331 if(Curl_cookie_output(data
->cookies
, data
->set
.cookiejar
))
332 infof(data
, "WARNING: failed to save cookies in %s\n",
333 data
->set
.cookiejar
);
336 if(data
->change
.cookielist
)
337 /* since nothing is written, we can just free the list of cookie file
339 curl_slist_free_all(data
->change
.cookielist
); /* clean up list */
342 if( !data
->share
|| (data
->cookies
!= data
->share
->cookies
) ) {
343 Curl_cookie_cleanup(data
->cookies
);
345 Curl_share_unlock(data
, CURL_LOCK_DATA_COOKIE
);
348 Curl_digest_cleanup(data
);
350 Curl_safefree(data
->info
.contenttype
);
352 /* this destroys the channel and we cannot use it anymore after this */
353 ares_destroy(data
->state
.areschannel
);
355 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
356 /* close iconv conversion descriptors */
357 if (data
->inbound_cd
!= (iconv_t
)-1) {
358 iconv_close(data
->inbound_cd
);
360 if (data
->outbound_cd
!= (iconv_t
)-1) {
361 iconv_close(data
->outbound_cd
);
363 if (data
->utf8_cd
!= (iconv_t
)-1) {
364 iconv_close(data
->utf8_cd
);
366 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
368 /* No longer a dirty share, if it exists */
370 data
->share
->dirty
--;
376 /* create a connection cache of a private or multi type */
377 struct conncache
*Curl_mk_connc(int type
,
378 int amount
) /* set -1 to use default */
380 /* It is subject for debate how many default connections to have for a multi
381 connection cache... */
382 int default_amount
= amount
== -1?
383 ((type
== CONNCACHE_PRIVATE
)?5:10):amount
;
386 c
= calloc(sizeof(struct conncache
), 1);
390 c
->connects
= calloc(sizeof(struct connectdata
*), default_amount
);
396 c
->num
= default_amount
;
401 /* Change number of entries of a connection cache */
402 CURLcode
Curl_ch_connc(struct SessionHandle
*data
,
407 struct connectdata
**newptr
;
410 newamount
= 1; /* we better have at least one entry */
413 /* we get a NULL pointer passed in as connection cache, which means that
414 there is no cache created for this SessionHandle just yet, we create a
415 brand new with the requested size.
417 data
->state
.connc
= Curl_mk_connc(CONNCACHE_PRIVATE
, newamount
);
418 if(!data
->state
.connc
)
419 return CURLE_OUT_OF_MEMORY
;
423 if(newamount
< c
->num
) {
424 /* Since this number is *decreased* from the existing number, we must
425 close the possibly open connections that live on the indexes that
428 NOTE: for conncache_multi cases we must make sure that we only
429 close handles not in use.
431 for(i
=newamount
; i
< c
->num
; i
++)
432 Curl_disconnect(c
->connects
[i
]);
434 /* If the most recent connection is no longer valid, mark it
436 if(data
->state
.lastconnect
<= newamount
)
437 data
->state
.lastconnect
= -1;
440 newptr
= (struct connectdata
**)
441 realloc(c
->connects
, sizeof(struct connectdata
*) * newamount
);
443 /* we closed a few connections in vain, but so what? */
444 return CURLE_OUT_OF_MEMORY
;
446 /* nullify the newly added pointers */
447 for(i
=c
->num
; i
<newamount
; i
++)
450 c
->connects
= newptr
;
453 /* we no longer support less than 1 as size for the connection cache, and
454 I'm not sure it ever worked to set it to zero */
458 /* Free a connection cache. This is called from Curl_close() and
459 curl_multi_cleanup(). */
460 void Curl_rm_connc(struct conncache
*c
)
464 for(i
= 0; i
< c
->num
; ++i
)
465 conn_free(c
->connects
[i
]);
476 * @param curl is a pointer to a sessionhandle pointer that gets set by this
481 CURLcode
Curl_open(struct SessionHandle
**curl
)
483 CURLcode res
= CURLE_OK
;
484 struct SessionHandle
*data
;
486 /* Very simple start-up: alloc the struct, init it with zeroes and return */
487 data
= (struct SessionHandle
*)calloc(1, sizeof(struct SessionHandle
));
489 /* this is a very serious error */
490 return CURLE_OUT_OF_MEMORY
;
492 data
->magic
= CURLEASY_MAGIC_NUMBER
;
495 if(ARES_SUCCESS
!= ares_init(&data
->state
.areschannel
)) {
497 return CURLE_FAILED_INIT
;
499 /* make sure that all other returns from this function should destroy the
500 ares channel before returning error! */
503 /* We do some initial setup here, all those fields that can't be just 0 */
505 data
->state
.headerbuff
=(char*)malloc(HEADERSIZE
);
506 if(!data
->state
.headerbuff
)
507 res
= CURLE_OUT_OF_MEMORY
;
509 data
->state
.headersize
=HEADERSIZE
;
511 data
->set
.out
= stdout
; /* default output to stdout */
512 data
->set
.in
= stdin
; /* default input from stdin */
513 data
->set
.err
= stderr
; /* default stderr to stderr */
515 /* use fwrite as default function to store output */
516 data
->set
.fwrite
= (curl_write_callback
)fwrite
;
518 /* use fread as default function to read input */
519 data
->set
.fread
= (curl_read_callback
)fread
;
521 /* conversion callbacks for non-ASCII hosts */
522 data
->set
.convfromnetwork
= (curl_conv_callback
)ZERO_NULL
;
523 data
->set
.convtonetwork
= (curl_conv_callback
)ZERO_NULL
;
524 data
->set
.convfromutf8
= (curl_conv_callback
)ZERO_NULL
;
526 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
527 /* conversion descriptors for iconv calls */
528 data
->outbound_cd
= (iconv_t
)-1;
529 data
->inbound_cd
= (iconv_t
)-1;
530 data
->utf8_cd
= (iconv_t
)-1;
531 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
533 data
->set
.infilesize
= -1; /* we don't know any size */
534 data
->set
.postfieldsize
= -1;
535 data
->set
.maxredirs
= -1; /* allow any amount by default */
536 data
->state
.current_speed
= -1; /* init to negative == impossible */
538 data
->set
.httpreq
= HTTPREQ_GET
; /* Default HTTP request */
539 data
->set
.ftp_use_epsv
= TRUE
; /* FTP defaults to EPSV operations */
540 data
->set
.ftp_use_eprt
= TRUE
; /* FTP defaults to EPRT operations */
541 data
->set
.ftp_filemethod
= FTPFILE_MULTICWD
;
542 data
->set
.dns_cache_timeout
= 60; /* Timeout every 60 seconds by default */
544 /* make libcurl quiet by default: */
545 data
->set
.hide_progress
= TRUE
; /* CURLOPT_NOPROGRESS changes these */
546 data
->progress
.flags
|= PGRS_HIDE
;
548 /* Set the default size of the SSL session ID cache */
549 data
->set
.ssl
.numsessions
= 5;
551 data
->set
.proxyport
= 1080;
552 data
->set
.proxytype
= CURLPROXY_HTTP
; /* defaults to HTTP proxy */
553 data
->set
.httpauth
= CURLAUTH_BASIC
; /* defaults to basic */
554 data
->set
.proxyauth
= CURLAUTH_BASIC
; /* defaults to basic */
556 /* This no longer creates a connection cache here. It is instead made on
557 the first call to curl_easy_perform() or when the handle is added to a
560 data
->set
.ssh_auth_types
= CURLSSH_AUTH_DEFAULT
; /* defaults to any auth
563 /* most recent connection is not yet defined */
564 data
->state
.lastconnect
= -1;
566 Curl_easy_initHandleData(data
);
569 * libcurl 7.10 introduced SSL verification *by default*! This needs to be
570 * switched off unless wanted.
572 data
->set
.ssl
.verifypeer
= TRUE
;
573 data
->set
.ssl
.verifyhost
= 2;
574 data
->set
.ssl
.sessionid
= TRUE
; /* session ID caching enabled by default */
575 #ifdef CURL_CA_BUNDLE
576 /* This is our preferred CA cert bundle since install time */
577 data
->set
.ssl
.CAfile
= (char *)CURL_CA_BUNDLE
;
582 ares_destroy(data
->state
.areschannel
);
583 if(data
->state
.headerbuff
)
584 free(data
->state
.headerbuff
);
594 CURLcode
Curl_setopt(struct SessionHandle
*data
, CURLoption option
,
598 CURLcode result
= CURLE_OK
;
601 case CURLOPT_DNS_CACHE_TIMEOUT
:
602 data
->set
.dns_cache_timeout
= va_arg(param
, int);
604 case CURLOPT_DNS_USE_GLOBAL_CACHE
:
606 int use_cache
= va_arg(param
, int);
608 Curl_global_host_cache_init();
611 data
->set
.global_dns_cache
= (bool)(0 != use_cache
);
614 case CURLOPT_SSL_CIPHER_LIST
:
615 /* set a list of cipher we want to use in the SSL connection */
616 data
->set
.ssl
.cipher_list
= va_arg(param
, char *);
619 case CURLOPT_RANDOM_FILE
:
621 * This is the path name to a file that contains random data to seed
622 * the random SSL stuff with. The file is only used for reading.
624 data
->set
.ssl
.random_file
= va_arg(param
, char *);
626 case CURLOPT_EGDSOCKET
:
628 * The Entropy Gathering Daemon socket pathname
630 data
->set
.ssl
.egdsocket
= va_arg(param
, char *);
632 case CURLOPT_MAXCONNECTS
:
634 * Set the absolute number of maximum simultaneous alive connection that
635 * libcurl is allowed to have.
637 result
= Curl_ch_connc(data
, data
->state
.connc
, va_arg(param
, long));
639 case CURLOPT_FORBID_REUSE
:
641 * When this transfer is done, it must not be left to be reused by a
642 * subsequent transfer but shall be closed immediately.
644 data
->set
.reuse_forbid
= (bool)(0 != va_arg(param
, long));
646 case CURLOPT_FRESH_CONNECT
:
648 * This transfer shall not use a previously cached connection but
649 * should be made with a fresh new connect!
651 data
->set
.reuse_fresh
= (bool)(0 != va_arg(param
, long));
653 case CURLOPT_VERBOSE
:
655 * Verbose means infof() calls that give a lot of information about
656 * the connection and transfer procedures as well as internal choices.
658 data
->set
.verbose
= (bool)(0 != va_arg(param
, long));
662 * Set to include the header in the general data output stream.
664 data
->set
.include_header
= (bool)(0 != va_arg(param
, long));
666 case CURLOPT_NOPROGRESS
:
668 * Shut off the internal supported progress meter
670 data
->set
.hide_progress
= (bool)(0 != va_arg(param
, long));
671 if(data
->set
.hide_progress
)
672 data
->progress
.flags
|= PGRS_HIDE
;
674 data
->progress
.flags
&= ~PGRS_HIDE
;
678 * Do not include the body part in the output data stream.
680 data
->set
.opt_no_body
= (bool)(0 != va_arg(param
, long));
681 if(data
->set
.opt_no_body
)
682 /* in HTTP lingo, this means using the HEAD request */
683 data
->set
.httpreq
= HTTPREQ_HEAD
;
685 case CURLOPT_FAILONERROR
:
687 * Don't output the >=300 error code HTML-page, but instead only
690 data
->set
.http_fail_on_error
= (bool)(0 != va_arg(param
, long));
695 * We want to sent data to the remote host. If this is HTTP, that equals
696 * using the PUT request.
698 data
->set
.upload
= (bool)(0 != va_arg(param
, long));
700 /* If this is HTTP, PUT is what's needed to "upload" */
701 data
->set
.httpreq
= HTTPREQ_PUT
;
703 case CURLOPT_FILETIME
:
705 * Try to get the file time of the remote document. The time will
706 * later (possibly) become available using curl_easy_getinfo().
708 data
->set
.get_filetime
= (bool)(0 != va_arg(param
, long));
710 case CURLOPT_FTP_CREATE_MISSING_DIRS
:
712 * An FTP option that modifies an upload to create missing directories on
715 data
->set
.ftp_create_missing_dirs
= (bool)(0 != va_arg(param
, long));
717 case CURLOPT_FTP_RESPONSE_TIMEOUT
:
719 * An FTP option that specifies how quickly an FTP response must be
720 * obtained before it is considered failure.
722 data
->set
.ftp_response_timeout
= va_arg( param
, long );
724 case CURLOPT_FTPLISTONLY
:
726 * An FTP option that changes the command to one that asks for a list
727 * only, no file info details.
729 data
->set
.ftp_list_only
= (bool)(0 != va_arg(param
, long));
731 case CURLOPT_FTPAPPEND
:
733 * We want to upload and append to an existing (FTP) file.
735 data
->set
.ftp_append
= (bool)(0 != va_arg(param
, long));
737 case CURLOPT_FTP_FILEMETHOD
:
739 * How do access files over FTP.
741 data
->set
.ftp_filemethod
= (curl_ftpfile
)va_arg(param
, long);
745 * Parse the $HOME/.netrc file
747 data
->set
.use_netrc
= (enum CURL_NETRC_OPTION
)va_arg(param
, long);
749 case CURLOPT_NETRC_FILE
:
751 * Use this file instead of the $HOME/.netrc file
753 data
->set
.netrc_file
= va_arg(param
, char *);
755 case CURLOPT_TRANSFERTEXT
:
757 * This option was previously named 'FTPASCII'. Renamed to work with
758 * more protocols than merely FTP.
760 * Transfer using ASCII (instead of BINARY).
762 data
->set
.prefer_ascii
= (bool)(0 != va_arg(param
, long));
764 case CURLOPT_TIMECONDITION
:
766 * Set HTTP time condition. This must be one of the defines in the
767 * curl/curl.h header file.
769 data
->set
.timecondition
= (curl_TimeCond
)va_arg(param
, long);
771 case CURLOPT_TIMEVALUE
:
773 * This is the value to compare with the remote document with the
774 * method set with CURLOPT_TIMECONDITION
776 data
->set
.timevalue
= (time_t)va_arg(param
, long);
778 case CURLOPT_SSLVERSION
:
780 * Set explicit SSL version to try to connect with, as some SSL
781 * implementations are lame.
783 data
->set
.ssl
.version
= va_arg(param
, long);
786 #ifndef CURL_DISABLE_HTTP
787 case CURLOPT_AUTOREFERER
:
789 * Switch on automatic referer that gets set if curl follows locations.
791 data
->set
.http_auto_referer
= (bool)(0 != va_arg(param
, long));
794 case CURLOPT_ENCODING
:
796 * String to use at the value of Accept-Encoding header.
798 * If the encoding is set to "" we use an Accept-Encoding header that
799 * encompasses all the encodings we support.
800 * If the encoding is set to NULL we don't send an Accept-Encoding header
801 * and ignore an received Content-Encoding header.
804 data
->set
.encoding
= va_arg(param
, char *);
805 if(data
->set
.encoding
&& !*data
->set
.encoding
)
806 data
->set
.encoding
= (char*)ALL_CONTENT_ENCODINGS
;
809 case CURLOPT_FOLLOWLOCATION
:
811 * Follow Location: header hints on a HTTP-server.
813 data
->set
.http_follow_location
= (bool)(0 != va_arg(param
, long));
816 case CURLOPT_UNRESTRICTED_AUTH
:
818 * Send authentication (user+password) when following locations, even when
821 data
->set
.http_disable_hostname_check_before_authentication
=
822 (bool)(0 != va_arg(param
, long));
825 case CURLOPT_MAXREDIRS
:
827 * The maximum amount of hops you allow curl to follow Location:
828 * headers. This should mostly be used to detect never-ending loops.
830 data
->set
.maxredirs
= va_arg(param
, long);
834 /* Does this option serve a purpose anymore? Yes it does, when
835 CURLOPT_POSTFIELDS isn't used and the POST data is read off the
837 if(va_arg(param
, long)) {
838 data
->set
.httpreq
= HTTPREQ_POST
;
839 data
->set
.opt_no_body
= FALSE
; /* this is implied */
842 data
->set
.httpreq
= HTTPREQ_GET
;
845 case CURLOPT_POSTFIELDS
:
847 * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
849 data
->set
.postfields
= va_arg(param
, char *);
850 data
->set
.httpreq
= HTTPREQ_POST
;
853 case CURLOPT_POSTFIELDSIZE
:
855 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
856 * figure it out. Enables binary posts.
858 data
->set
.postfieldsize
= va_arg(param
, long);
861 case CURLOPT_POSTFIELDSIZE_LARGE
:
863 * The size of the POSTFIELD data to prevent libcurl to do strlen() to
864 * figure it out. Enables binary posts.
866 data
->set
.postfieldsize
= va_arg(param
, curl_off_t
);
869 case CURLOPT_HTTPPOST
:
871 * Set to make us do HTTP POST
873 data
->set
.httppost
= va_arg(param
, struct curl_httppost
*);
874 data
->set
.httpreq
= HTTPREQ_POST_FORM
;
875 data
->set
.opt_no_body
= FALSE
; /* this is implied */
878 case CURLOPT_REFERER
:
880 * String to set in the HTTP Referer: field.
882 if(data
->change
.referer_alloc
) {
883 free(data
->change
.referer
);
884 data
->change
.referer_alloc
= FALSE
;
886 data
->set
.set_referer
= va_arg(param
, char *);
887 data
->change
.referer
= data
->set
.set_referer
;
890 case CURLOPT_USERAGENT
:
892 * String to use in the HTTP User-Agent field
894 data
->set
.useragent
= va_arg(param
, char *);
897 case CURLOPT_HTTPHEADER
:
899 * Set a list with HTTP headers to use (or replace internals with)
901 data
->set
.headers
= va_arg(param
, struct curl_slist
*);
904 case CURLOPT_HTTP200ALIASES
:
906 * Set a list of aliases for HTTP 200 in response header
908 data
->set
.http200aliases
= va_arg(param
, struct curl_slist
*);
911 #if !defined(CURL_DISABLE_COOKIES)
914 * Cookie string to send to the remote server in the request.
916 data
->set
.cookie
= va_arg(param
, char *);
919 case CURLOPT_COOKIEFILE
:
921 * Set cookie file to read and parse. Can be used multiple times.
923 argptr
= (char *)va_arg(param
, void *);
925 struct curl_slist
*cl
;
926 /* append the cookie file name to the list of file names, and deal with
928 cl
= curl_slist_append(data
->change
.cookielist
, argptr
);
931 return CURLE_OUT_OF_MEMORY
;
933 data
->change
.cookielist
= cl
;
937 case CURLOPT_COOKIEJAR
:
939 * Set cookie file name to dump all cookies to when we're done.
941 data
->set
.cookiejar
= (char *)va_arg(param
, void *);
944 * Activate the cookie parser. This may or may not already
947 data
->cookies
= Curl_cookie_init(data
, NULL
, data
->cookies
,
948 data
->set
.cookiesession
);
951 case CURLOPT_COOKIESESSION
:
953 * Set this option to TRUE to start a new "cookie session". It will
954 * prevent the forthcoming read-cookies-from-file actions to accept
955 * cookies that are marked as being session cookies, as they belong to a
958 * In the original Netscape cookie spec, "session cookies" are cookies
959 * with no expire date set. RFC2109 describes the same action if no
960 * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
961 * a 'Discard' action that can enforce the discard even for cookies that
964 * We run mostly with the original cookie spec, as hardly anyone implements
967 data
->set
.cookiesession
= (bool)(0 != va_arg(param
, long));
970 case CURLOPT_COOKIELIST
:
971 argptr
= va_arg(param
, char *);
976 if(strequal(argptr
, "ALL")) {
977 /* clear all cookies */
978 Curl_cookie_clearall(data
->cookies
);
981 else if(strequal(argptr
, "SESS")) {
982 /* clear session cookies */
983 Curl_cookie_clearsess(data
->cookies
);
988 /* if cookie engine was not running, activate it */
989 data
->cookies
= Curl_cookie_init(data
, NULL
, NULL
, TRUE
);
991 argptr
= strdup(argptr
);
993 result
= CURLE_OUT_OF_MEMORY
;
997 if(checkprefix("Set-Cookie:", argptr
))
998 /* HTTP Header format line */
999 Curl_cookie_add(data
, data
->cookies
, TRUE
, argptr
+ 11, NULL
, NULL
);
1002 /* Netscape format line */
1003 Curl_cookie_add(data
, data
->cookies
, FALSE
, argptr
, NULL
, NULL
);
1007 #endif /* CURL_DISABLE_COOKIES */
1009 case CURLOPT_HTTPGET
:
1011 * Set to force us do HTTP GET
1013 if(va_arg(param
, long)) {
1014 data
->set
.httpreq
= HTTPREQ_GET
;
1015 data
->set
.upload
= FALSE
; /* switch off upload */
1016 data
->set
.opt_no_body
= FALSE
; /* this is implied */
1020 case CURLOPT_HTTP_VERSION
:
1022 * This sets a requested HTTP version to be used. The value is one of
1023 * the listed enums in curl/curl.h.
1025 data
->set
.httpversion
= va_arg(param
, long);
1028 case CURLOPT_HTTPPROXYTUNNEL
:
1030 * Tunnel operations through the proxy instead of normal proxy use
1032 data
->set
.tunnel_thru_httpproxy
= (bool)(0 != va_arg(param
, long));
1035 case CURLOPT_CUSTOMREQUEST
:
1037 * Set a custom string to use as request
1039 data
->set
.customrequest
= va_arg(param
, char *);
1042 data->set.httpreq = HTTPREQ_CUSTOM;
1043 here, we continue as if we were using the already set type
1044 and this just changes the actual request keyword */
1047 case CURLOPT_PROXYPORT
:
1049 * Explicitly set HTTP proxy port number.
1051 data
->set
.proxyport
= va_arg(param
, long);
1054 case CURLOPT_HTTPAUTH
:
1056 * Set HTTP Authentication type BITMASK.
1059 long auth
= va_arg(param
, long);
1060 /* switch off bits we can't support */
1062 auth
&= ~CURLAUTH_NTLM
; /* no NTLM without SSL */
1065 auth
&= ~CURLAUTH_GSSNEGOTIATE
; /* no GSS-Negotiate without GSSAPI */
1068 return CURLE_FAILED_INIT
; /* no supported types left! */
1070 data
->set
.httpauth
= auth
;
1074 case CURLOPT_PROXYAUTH
:
1076 * Set HTTP Authentication type BITMASK.
1079 long auth
= va_arg(param
, long);
1080 /* switch off bits we can't support */
1082 auth
&= ~CURLAUTH_NTLM
; /* no NTLM without SSL */
1085 auth
&= ~CURLAUTH_GSSNEGOTIATE
; /* no GSS-Negotiate without GSSAPI */
1088 return CURLE_FAILED_INIT
; /* no supported types left! */
1090 data
->set
.proxyauth
= auth
;
1093 #endif /* CURL_DISABLE_HTTP */
1097 * Set proxy server:port to use as HTTP proxy.
1099 * If the proxy is set to "" we explicitly say that we don't want to use a
1100 * proxy (even though there might be environment variables saying so).
1102 * Setting it to NULL, means no proxy but allows the environment variables
1105 data
->set
.proxy
= va_arg(param
, char *);
1108 case CURLOPT_WRITEHEADER
:
1110 * Custom pointer to pass the header write callback function
1112 data
->set
.writeheader
= (void *)va_arg(param
, void *);
1114 case CURLOPT_ERRORBUFFER
:
1116 * Error buffer provided by the caller to get the human readable
1119 data
->set
.errorbuffer
= va_arg(param
, char *);
1123 * FILE pointer to write to or include in the data write callback
1125 data
->set
.out
= va_arg(param
, FILE *);
1127 case CURLOPT_FTPPORT
:
1129 * Use FTP PORT, this also specifies which IP address to use
1131 data
->set
.ftpport
= va_arg(param
, char *);
1132 data
->set
.ftp_use_port
= (bool)(NULL
!= data
->set
.ftpport
);
1135 case CURLOPT_FTP_USE_EPRT
:
1136 data
->set
.ftp_use_eprt
= (bool)(0 != va_arg(param
, long));
1139 case CURLOPT_FTP_USE_EPSV
:
1140 data
->set
.ftp_use_epsv
= (bool)(0 != va_arg(param
, long));
1143 case CURLOPT_FTP_SSL_CCC
:
1144 data
->set
.ftp_use_ccc
= (bool)(0 != va_arg(param
, long));
1147 case CURLOPT_FTP_SKIP_PASV_IP
:
1149 * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1150 * bypass of the IP address in PASV responses.
1152 data
->set
.ftp_skip_ip
= (bool)(0 != va_arg(param
, long));
1155 case CURLOPT_INFILE
:
1157 * FILE pointer to read the file to be uploaded from. Or possibly
1158 * used as argument to the read callback.
1160 data
->set
.in
= va_arg(param
, FILE *);
1162 case CURLOPT_INFILESIZE
:
1164 * If known, this should inform curl about the file size of the
1165 * to-be-uploaded file.
1167 data
->set
.infilesize
= va_arg(param
, long);
1169 case CURLOPT_INFILESIZE_LARGE
:
1171 * If known, this should inform curl about the file size of the
1172 * to-be-uploaded file.
1174 data
->set
.infilesize
= va_arg(param
, curl_off_t
);
1176 case CURLOPT_LOW_SPEED_LIMIT
:
1178 * The low speed limit that if transfers are below this for
1179 * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1181 data
->set
.low_speed_limit
=va_arg(param
, long);
1183 case CURLOPT_MAX_SEND_SPEED_LARGE
:
1185 * The max speed limit that sends transfer more than
1186 * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is
1189 data
->set
.max_send_speed
=va_arg(param
, curl_off_t
);
1191 case CURLOPT_MAX_RECV_SPEED_LARGE
:
1193 * The max speed limit that sends transfer more than
1194 * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is
1197 data
->set
.max_recv_speed
=va_arg(param
, curl_off_t
);
1199 case CURLOPT_LOW_SPEED_TIME
:
1201 * The low speed time that if transfers are below the set
1202 * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1204 data
->set
.low_speed_time
=va_arg(param
, long);
1210 if(data
->change
.url_alloc
) {
1211 /* the already set URL is allocated, free it first! */
1212 free(data
->change
.url
);
1213 data
->change
.url_alloc
=FALSE
;
1215 data
->set
.set_url
= va_arg(param
, char *);
1216 data
->change
.url
= data
->set
.set_url
;
1217 data
->change
.url_changed
= TRUE
;
1221 * The port number to use when getting the URL
1223 data
->set
.use_port
= va_arg(param
, long);
1225 case CURLOPT_TIMEOUT
:
1227 * The maximum time you allow curl to use for a single transfer
1230 data
->set
.timeout
= va_arg(param
, long);
1232 case CURLOPT_CONNECTTIMEOUT
:
1234 * The maximum time you allow curl to use to connect.
1236 data
->set
.connecttimeout
= va_arg(param
, long);
1239 case CURLOPT_USERPWD
:
1241 * user:password to use in the operation
1243 data
->set
.userpwd
= va_arg(param
, char *);
1245 case CURLOPT_POSTQUOTE
:
1247 * List of RAW FTP commands to use after a transfer
1249 data
->set
.postquote
= va_arg(param
, struct curl_slist
*);
1251 case CURLOPT_PREQUOTE
:
1253 * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1255 data
->set
.prequote
= va_arg(param
, struct curl_slist
*);
1259 * List of RAW FTP commands to use before a transfer
1261 data
->set
.quote
= va_arg(param
, struct curl_slist
*);
1263 case CURLOPT_PROGRESSFUNCTION
:
1265 * Progress callback function
1267 data
->set
.fprogress
= va_arg(param
, curl_progress_callback
);
1268 if(data
->set
.fprogress
)
1269 data
->progress
.callback
= TRUE
; /* no longer internal */
1271 data
->progress
.callback
= FALSE
; /* NULL enforces internal */
1274 case CURLOPT_PROGRESSDATA
:
1276 * Custom client data to pass to the progress callback
1278 data
->set
.progress_client
= va_arg(param
, void *);
1280 case CURLOPT_PROXYUSERPWD
:
1282 * user:password needed to use the proxy
1284 data
->set
.proxyuserpwd
= va_arg(param
, char *);
1288 * What range of the file you want to transfer
1290 data
->set
.set_range
= va_arg(param
, char *);
1292 case CURLOPT_RESUME_FROM
:
1294 * Resume transfer at the give file position
1296 data
->set
.set_resume_from
= va_arg(param
, long);
1298 case CURLOPT_RESUME_FROM_LARGE
:
1300 * Resume transfer at the give file position
1302 data
->set
.set_resume_from
= va_arg(param
, curl_off_t
);
1304 case CURLOPT_DEBUGFUNCTION
:
1306 * stderr write callback.
1308 data
->set
.fdebug
= va_arg(param
, curl_debug_callback
);
1310 * if the callback provided is NULL, it'll use the default callback
1313 case CURLOPT_DEBUGDATA
:
1315 * Set to a void * that should receive all error writes. This
1316 * defaults to CURLOPT_STDERR for normal operations.
1318 data
->set
.debugdata
= va_arg(param
, void *);
1320 case CURLOPT_STDERR
:
1322 * Set to a FILE * that should receive all error writes. This
1323 * defaults to stderr for normal operations.
1325 data
->set
.err
= va_arg(param
, FILE *);
1327 data
->set
.err
= stderr
;
1329 case CURLOPT_HEADERFUNCTION
:
1331 * Set header write callback
1333 data
->set
.fwrite_header
= va_arg(param
, curl_write_callback
);
1335 case CURLOPT_WRITEFUNCTION
:
1337 * Set data write callback
1339 data
->set
.fwrite
= va_arg(param
, curl_write_callback
);
1340 if(!data
->set
.fwrite
)
1341 /* When set to NULL, reset to our internal default function */
1342 data
->set
.fwrite
= (curl_write_callback
)fwrite
;
1344 case CURLOPT_READFUNCTION
:
1346 * Read data callback
1348 data
->set
.fread
= va_arg(param
, curl_read_callback
);
1349 if(!data
->set
.fread
)
1350 /* When set to NULL, reset to our internal default function */
1351 data
->set
.fread
= (curl_read_callback
)fread
;
1353 case CURLOPT_CONV_FROM_NETWORK_FUNCTION
:
1355 * "Convert from network encoding" callback
1357 data
->set
.convfromnetwork
= va_arg(param
, curl_conv_callback
);
1359 case CURLOPT_CONV_TO_NETWORK_FUNCTION
:
1361 * "Convert to network encoding" callback
1363 data
->set
.convtonetwork
= va_arg(param
, curl_conv_callback
);
1365 case CURLOPT_CONV_FROM_UTF8_FUNCTION
:
1367 * "Convert from UTF-8 encoding" callback
1369 data
->set
.convfromutf8
= va_arg(param
, curl_conv_callback
);
1371 case CURLOPT_IOCTLFUNCTION
:
1373 * I/O control callback. Might be NULL.
1375 data
->set
.ioctl
= va_arg(param
, curl_ioctl_callback
);
1377 case CURLOPT_IOCTLDATA
:
1379 * I/O control data pointer. Might be NULL.
1381 data
->set
.ioctl_client
= va_arg(param
, void *);
1383 case CURLOPT_SSLCERT
:
1385 * String that holds file name of the SSL certificate to use
1387 data
->set
.cert
= va_arg(param
, char *);
1389 case CURLOPT_SSLCERTTYPE
:
1391 * String that holds file type of the SSL certificate to use
1393 data
->set
.cert_type
= va_arg(param
, char *);
1395 case CURLOPT_SSLKEY
:
1397 * String that holds file name of the SSL certificate to use
1399 data
->set
.key
= va_arg(param
, char *);
1401 case CURLOPT_SSLKEYTYPE
:
1403 * String that holds file type of the SSL certificate to use
1405 data
->set
.key_type
= va_arg(param
, char *);
1407 case CURLOPT_SSLKEYPASSWD
:
1409 * String that holds the SSL private key password.
1411 data
->set
.key_passwd
= va_arg(param
, char *);
1413 case CURLOPT_SSLENGINE
:
1415 * String that holds the SSL crypto engine.
1417 argptr
= va_arg(param
, char *);
1418 if (argptr
&& argptr
[0])
1419 result
= Curl_ssl_set_engine(data
, argptr
);
1422 case CURLOPT_SSLENGINE_DEFAULT
:
1424 * flag to set engine as default.
1426 result
= Curl_ssl_set_engine_default(data
);
1430 * Kludgy option to enable CRLF conversions. Subject for removal.
1432 data
->set
.crlf
= (bool)(0 != va_arg(param
, long));
1435 case CURLOPT_INTERFACE
:
1437 * Set what interface or address/hostname to bind the socket to when
1438 * performing an operation and thus what from-IP your connection will use.
1440 data
->set
.device
= va_arg(param
, char *);
1442 case CURLOPT_LOCALPORT
:
1444 * Set what local port to bind the socket to when performing an operation.
1446 data
->set
.localport
= (unsigned short) va_arg(param
, long);
1448 case CURLOPT_LOCALPORTRANGE
:
1450 * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1452 data
->set
.localportrange
= (int) va_arg(param
, long);
1454 case CURLOPT_KRB4LEVEL
:
1456 * A string that defines the krb4 security level.
1458 data
->set
.krb4_level
= va_arg(param
, char *);
1459 data
->set
.krb4
= (bool)(NULL
!= data
->set
.krb4_level
);
1461 case CURLOPT_SSL_VERIFYPEER
:
1463 * Enable peer SSL verifying.
1465 data
->set
.ssl
.verifypeer
= va_arg(param
, long);
1467 case CURLOPT_SSL_VERIFYHOST
:
1469 * Enable verification of the CN contained in the peer certificate
1471 data
->set
.ssl
.verifyhost
= va_arg(param
, long);
1473 case CURLOPT_SSL_CTX_FUNCTION
:
1475 * Set a SSL_CTX callback
1477 data
->set
.ssl
.fsslctx
= va_arg(param
, curl_ssl_ctx_callback
);
1479 case CURLOPT_SSL_CTX_DATA
:
1481 * Set a SSL_CTX callback parameter pointer
1483 data
->set
.ssl
.fsslctxp
= va_arg(param
, void *);
1485 case CURLOPT_CAINFO
:
1487 * Set CA info for SSL connection. Specify file name of the CA certificate
1489 data
->set
.ssl
.CAfile
= va_arg(param
, char *);
1491 case CURLOPT_CAPATH
:
1493 * Set CA path info for SSL connection. Specify directory name of the CA
1494 * certificates which have been prepared using openssl c_rehash utility.
1496 /* This does not work on windows. */
1497 data
->set
.ssl
.CApath
= va_arg(param
, char *);
1499 case CURLOPT_TELNETOPTIONS
:
1501 * Set a linked list of telnet options
1503 data
->set
.telnet_options
= va_arg(param
, struct curl_slist
*);
1506 case CURLOPT_BUFFERSIZE
:
1508 * The application kindly asks for a differently sized receive buffer.
1509 * If it seems reasonable, we'll use it.
1511 data
->set
.buffer_size
= va_arg(param
, long);
1513 if((data
->set
.buffer_size
> (BUFSIZE
-1 )) ||
1514 (data
->set
.buffer_size
< 1))
1515 data
->set
.buffer_size
= 0; /* huge internal default */
1519 case CURLOPT_NOSIGNAL
:
1521 * The application asks not to set any signal() or alarm() handlers,
1522 * even when using a timeout.
1524 data
->set
.no_signal
= (bool)(0 != va_arg(param
, long));
1529 struct Curl_share
*set
;
1530 set
= va_arg(param
, struct Curl_share
*);
1532 /* disconnect from old share, if any */
1534 Curl_share_lock(data
, CURL_LOCK_DATA_SHARE
, CURL_LOCK_ACCESS_SINGLE
);
1536 if(data
->dns
.hostcachetype
== HCACHE_SHARED
) {
1537 data
->dns
.hostcache
= NULL
;
1538 data
->dns
.hostcachetype
= HCACHE_NONE
;
1541 if(data
->share
->cookies
== data
->cookies
)
1542 data
->cookies
= NULL
;
1544 data
->share
->dirty
--;
1546 Curl_share_unlock(data
, CURL_LOCK_DATA_SHARE
);
1550 /* use new share if it set */
1554 Curl_share_lock(data
, CURL_LOCK_DATA_SHARE
, CURL_LOCK_ACCESS_SINGLE
);
1556 data
->share
->dirty
++;
1558 if(data
->share
->hostcache
) {
1559 /* use shared host cache, first free the private one if any */
1560 if(data
->dns
.hostcachetype
== HCACHE_PRIVATE
)
1561 Curl_hash_destroy(data
->dns
.hostcache
);
1563 data
->dns
.hostcache
= data
->share
->hostcache
;
1564 data
->dns
.hostcachetype
= HCACHE_SHARED
;
1566 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1567 if(data
->share
->cookies
) {
1568 /* use shared cookie list, first free own one if any */
1570 Curl_cookie_cleanup(data
->cookies
);
1571 data
->cookies
= data
->share
->cookies
;
1573 #endif /* CURL_DISABLE_HTTP */
1574 Curl_share_unlock(data
, CURL_LOCK_DATA_SHARE
);
1577 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1578 /* check cookie list is set */
1580 data
->cookies
= Curl_cookie_init(data
, NULL
, NULL
, TRUE
);
1581 #endif /* CURL_DISABLE_HTTP */
1582 /* check for host cache not needed,
1583 * it will be done by curl_easy_perform */
1587 case CURLOPT_PROXYTYPE
:
1589 * Set proxy type. HTTP/SOCKS4/SOCKS5
1591 data
->set
.proxytype
= (curl_proxytype
)va_arg(param
, long);
1594 case CURLOPT_PRIVATE
:
1596 * Set private data pointer.
1598 data
->set
.private_data
= va_arg(param
, char *);
1601 case CURLOPT_MAXFILESIZE
:
1603 * Set the maximum size of a file to download.
1605 data
->set
.max_filesize
= va_arg(param
, long);
1608 case CURLOPT_FTP_SSL
:
1610 * Make FTP transfers attempt to use SSL/TLS.
1612 data
->set
.ftp_ssl
= (curl_ftpssl
)va_arg(param
, long);
1615 case CURLOPT_FTPSSLAUTH
:
1617 * Set a specific auth for FTP-SSL transfers.
1619 data
->set
.ftpsslauth
= (curl_ftpauth
)va_arg(param
, long);
1622 case CURLOPT_IPRESOLVE
:
1623 data
->set
.ip_version
= va_arg(param
, long);
1626 case CURLOPT_MAXFILESIZE_LARGE
:
1628 * Set the maximum size of a file to download.
1630 data
->set
.max_filesize
= va_arg(param
, curl_off_t
);
1633 case CURLOPT_TCP_NODELAY
:
1635 * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
1638 data
->set
.tcp_nodelay
= (bool)(0 != va_arg(param
, long));
1642 case CURLOPT_SOURCE_URL:
1643 case CURLOPT_SOURCE_USERPWD:
1644 case CURLOPT_SOURCE_QUOTE:
1645 case CURLOPT_SOURCE_PREQUOTE:
1646 case CURLOPT_SOURCE_POSTQUOTE:
1647 These former 3rd party transfer options are deprecated */
1649 case CURLOPT_FTP_ACCOUNT
:
1650 data
->set
.ftp_account
= va_arg(param
, char *);
1653 case CURLOPT_IGNORE_CONTENT_LENGTH
:
1654 data
->set
.ignorecl
= (bool)(0 != va_arg(param
, long));
1657 case CURLOPT_CONNECT_ONLY
:
1659 * No data transfer, set up connection and let application use the socket
1661 data
->set
.connect_only
= (bool)(0 != va_arg(param
, long));
1664 case CURLOPT_FTP_ALTERNATIVE_TO_USER
:
1665 data
->set
.ftp_alternative_to_user
= va_arg(param
, char *);
1668 case CURLOPT_SOCKOPTFUNCTION
:
1670 * socket callback function: called after socket() but before connect()
1672 data
->set
.fsockopt
= va_arg(param
, curl_sockopt_callback
);
1675 case CURLOPT_SOCKOPTDATA
:
1677 * socket callback data pointer. Might be NULL.
1679 data
->set
.sockopt_client
= va_arg(param
, void *);
1682 case CURLOPT_SSL_SESSIONID_CACHE
:
1683 data
->set
.ssl
.sessionid
= (bool)(0 != va_arg(param
, long));
1686 case CURLOPT_SSH_AUTH_TYPES
:
1687 data
->set
.ssh_auth_types
= va_arg(param
, long);
1690 case CURLOPT_SSH_PUBLIC_KEYFILE
:
1692 * Use this file instead of the $HOME/.ssh/id_dsa.pub file
1694 data
->set
.ssh_public_key
= va_arg(param
, char *);
1697 case CURLOPT_SSH_PRIVATE_KEYFILE
:
1699 * Use this file instead of the $HOME/.ssh/id_dsa file
1701 data
->set
.ssh_private_key
= va_arg(param
, char *);
1705 /* unknown tag and its companion, just ignore: */
1706 result
= CURLE_FAILED_INIT
; /* correct this */
1713 static void conn_free(struct connectdata
*conn
)
1718 /* close possibly still open sockets */
1719 if(CURL_SOCKET_BAD
!= conn
->sock
[SECONDARYSOCKET
])
1720 sclose(conn
->sock
[SECONDARYSOCKET
]);
1721 if(CURL_SOCKET_BAD
!= conn
->sock
[FIRSTSOCKET
])
1722 sclose(conn
->sock
[FIRSTSOCKET
]);
1724 Curl_safefree(conn
->user
);
1725 Curl_safefree(conn
->passwd
);
1726 Curl_safefree(conn
->proxyuser
);
1727 Curl_safefree(conn
->proxypasswd
);
1728 Curl_safefree(conn
->allocptr
.proxyuserpwd
);
1729 Curl_safefree(conn
->allocptr
.uagent
);
1730 Curl_safefree(conn
->allocptr
.userpwd
);
1731 Curl_safefree(conn
->allocptr
.accept_encoding
);
1732 Curl_safefree(conn
->allocptr
.rangeline
);
1733 Curl_safefree(conn
->allocptr
.ref
);
1734 Curl_safefree(conn
->allocptr
.host
);
1735 Curl_safefree(conn
->allocptr
.cookiehost
);
1736 Curl_safefree(conn
->ip_addr_str
);
1737 Curl_safefree(conn
->trailer
);
1738 Curl_safefree(conn
->host
.rawalloc
); /* host name buffer */
1739 Curl_safefree(conn
->proxy
.rawalloc
); /* proxy name buffer */
1741 Curl_llist_destroy(conn
->send_pipe
, NULL
);
1742 Curl_llist_destroy(conn
->recv_pipe
, NULL
);
1744 /* possible left-overs from the async name resolvers */
1745 #if defined(USE_ARES)
1746 Curl_safefree(conn
->async
.hostname
);
1747 Curl_safefree(conn
->async
.os_specific
);
1748 #elif defined(CURLRES_THREADED)
1749 Curl_destroy_thread_data(&conn
->async
);
1752 Curl_free_ssl_config(&conn
->ssl_config
);
1754 free(conn
); /* free all the connection oriented data */
1757 CURLcode
Curl_disconnect(struct connectdata
*conn
)
1759 struct SessionHandle
*data
;
1761 return CURLE_OK
; /* this is closed and fine already */
1765 DEBUGF(infof(data
, "DISCONNECT without easy handle, ignoring\n"));
1769 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
1770 /* scan for DNS cache entries still marked as in use */
1771 Curl_hash_apply(data
->hostcache
,
1772 NULL
, Curl_scan_cache_used
);
1775 Curl_expire(data
, 0); /* shut off timers */
1776 Curl_hostcache_prune(data
); /* kill old DNS cache entries */
1779 * The range string is usually freed in curl_done(), but we might
1780 * get here *instead* if we fail prematurely. Thus we need to be able
1781 * to free this resource here as well.
1783 if(data
->reqdata
.rangestringalloc
) {
1784 free(data
->reqdata
.range
);
1785 data
->reqdata
.rangestringalloc
= FALSE
;
1788 if((conn
->ntlm
.state
!= NTLMSTATE_NONE
) ||
1789 (conn
->proxyntlm
.state
!= NTLMSTATE_NONE
)) {
1790 /* Authentication data is a mix of connection-related and sessionhandle-
1791 related stuff. NTLM is connection-related so when we close the shop
1793 data
->state
.authhost
.done
= FALSE
;
1794 data
->state
.authhost
.picked
=
1795 data
->state
.authhost
.want
;
1797 data
->state
.authproxy
.done
= FALSE
;
1798 data
->state
.authproxy
.picked
=
1799 data
->state
.authproxy
.want
;
1801 data
->state
.authproblem
= FALSE
;
1803 Curl_ntlm_cleanup(conn
);
1806 if(conn
->curl_disconnect
)
1807 /* This is set if protocol-specific cleanups should be made */
1808 conn
->curl_disconnect(conn
);
1810 if(-1 != conn
->connectindex
) {
1811 /* unlink ourselves! */
1812 infof(data
, "Closing connection #%ld\n", conn
->connectindex
);
1813 if(data
->state
.connc
)
1814 /* only clear the table entry if we still know in which cache we
1816 data
->state
.connc
->connects
[conn
->connectindex
] = NULL
;
1820 if(conn
->host
.encalloc
)
1821 idn_free(conn
->host
.encalloc
); /* encoded host name buffer, must be freed
1822 with idn_free() since this was allocated
1824 if(conn
->proxy
.encalloc
)
1825 idn_free(conn
->proxy
.encalloc
); /* encoded proxy name buffer, must be
1826 freed with idn_free() since this was
1827 allocated by libidn */
1830 Curl_ssl_close(conn
);
1832 /* Indicate to all handles on the pipe that we're dead */
1833 if (IsPipeliningEnabled(data
)) {
1834 signalPipeClose(conn
->send_pipe
);
1835 signalPipeClose(conn
->recv_pipe
);
1844 * This function should return TRUE if the socket is to be assumed to
1845 * be dead. Most commonly this happens when the server has closed the
1846 * connection due to inactivity.
1848 static bool SocketIsDead(curl_socket_t sock
)
1851 bool ret_val
= TRUE
;
1853 sval
= Curl_select(sock
, CURL_SOCKET_BAD
, 0);
1861 static bool IsPipeliningPossible(struct SessionHandle
*handle
)
1863 if (handle
->multi
&& Curl_multi_canPipeline(handle
->multi
) &&
1864 (handle
->set
.httpreq
== HTTPREQ_GET
||
1865 handle
->set
.httpreq
== HTTPREQ_HEAD
) &&
1866 handle
->set
.httpversion
!= CURL_HTTP_VERSION_1_0
)
1872 static bool IsPipeliningEnabled(struct SessionHandle
*handle
)
1874 if (handle
->multi
&& Curl_multi_canPipeline(handle
->multi
))
1880 void Curl_addHandleToPipeline(struct SessionHandle
*data
,
1881 struct curl_llist
*pipe
)
1884 if(!IsPipeliningPossible(data
)) {
1885 /* when not pipelined, there MUST be no handle in the list already */
1887 infof(data
, "PIPE when no PIPE supposed!\n");
1890 Curl_llist_insert_next(pipe
, pipe
->tail
, data
);
1894 int Curl_removeHandleFromPipeline(struct SessionHandle
*handle
,
1895 struct curl_llist
*pipe
)
1897 struct curl_llist_element
*curr
;
1901 if (curr
->ptr
== handle
) {
1902 Curl_llist_remove(pipe
, curr
, NULL
);
1903 return 1; /* we removed a handle */
1911 #if 0 /* this code is saved here as it is useful for debugging purposes */
1912 static void Curl_printPipeline(struct curl_llist
*pipe
)
1914 struct curl_llist_element
*curr
;
1918 struct SessionHandle
*data
= (struct SessionHandle
*) curr
->ptr
;
1919 infof(data
, "Handle in pipeline: %s\n",
1920 data
->reqdata
.path
);
1926 bool Curl_isHandleAtHead(struct SessionHandle
*handle
,
1927 struct curl_llist
*pipe
)
1929 struct curl_llist_element
*curr
= pipe
->head
;
1931 return (bool)(curr
->ptr
== handle
);
1937 static void signalPipeClose(struct curl_llist
*pipe
)
1939 struct curl_llist_element
*curr
;
1943 struct curl_llist_element
*next
= curr
->next
;
1944 struct SessionHandle
*data
= (struct SessionHandle
*) curr
->ptr
;
1946 #ifdef CURLDEBUG /* debug-only code */
1947 if(data
->magic
!= CURLEASY_MAGIC_NUMBER
) {
1949 fprintf(stderr
, "signalPipeClose() found BAAD easy handle\n");
1954 data
->state
.pipe_broke
= TRUE
;
1955 Curl_llist_remove(pipe
, curr
, NULL
);
1962 * Given one filled in connection struct (named needle), this function should
1963 * detect if there already is one that has all the significant details
1964 * exactly the same and thus should be used instead.
1966 * If there is a match, this function returns TRUE - and has marked the
1967 * connection as 'in-use'. It must later be called with ConnectionDone() to
1968 * return back to 'idle' (unused) state.
1971 ConnectionExists(struct SessionHandle
*data
,
1972 struct connectdata
*needle
,
1973 struct connectdata
**usethis
)
1976 struct connectdata
*check
;
1977 bool canPipeline
= IsPipeliningPossible(data
);
1979 for(i
=0; i
< data
->state
.connc
->num
; i
++) {
1982 * Note that if we use a HTTP proxy, we check connections to that
1983 * proxy and not to the actual remote server.
1985 check
= data
->state
.connc
->connects
[i
];
1987 /* NULL pointer means not filled-in entry */
1990 if (check
->connectindex
== -1) {
1991 check
->connectindex
= i
; /* Set this appropriately since it might have
1992 been set to -1 when the easy was removed
1996 infof(data
, "Examining connection #%ld for reuse\n", check
->connectindex
);
1998 if(check
->inuse
&& !canPipeline
) {
1999 /* can only happen within multi handles, and means that another easy
2000 handle is using this connection */
2004 #ifdef CURLRES_ASYNCH
2005 /* ip_addr_str is NULL only if the resolving of the name hasn't completed
2006 yet and until then we don't re-use this connection */
2007 if (!check
->ip_addr_str
) {
2009 "Connection #%ld has not finished name resolve, can't reuse\n",
2010 check
->connectindex
);
2015 if (check
->send_pipe
->size
+
2016 check
->recv_pipe
->size
>= MAX_PIPELINE_LENGTH
) {
2017 infof(data
, "Connection #%ld has its pipeline full, can't reuse\n",
2018 check
->connectindex
);
2022 if (data
->state
.is_in_pipeline
&& check
->bits
.close
) {
2023 /* Don't pick a connection that is going to be closed */
2024 infof(data
, "Connection #%ld has been marked for close, can't reuse\n",
2025 check
->connectindex
);
2029 if((needle
->protocol
&PROT_SSL
) != (check
->protocol
&PROT_SSL
))
2030 /* don't do mixed SSL and non-SSL connections */
2033 if(!needle
->bits
.httpproxy
|| needle
->protocol
&PROT_SSL
) {
2034 /* The requested connection does not use a HTTP proxy or it
2037 if(!(needle
->protocol
&PROT_SSL
) && check
->bits
.httpproxy
)
2038 /* we don't do SSL but the cached connection has a proxy,
2039 then don't match this */
2042 if(strequal(needle
->protostr
, check
->protostr
) &&
2043 strequal(needle
->host
.name
, check
->host
.name
) &&
2044 (needle
->remote_port
== check
->remote_port
) ) {
2045 if(needle
->protocol
& PROT_SSL
) {
2046 /* This is SSL, verify that we're using the same
2047 ssl options as well */
2048 if(!Curl_ssl_config_matches(&needle
->ssl_config
,
2049 &check
->ssl_config
)) {
2051 "Connection #%ld has different SSL parameters, "
2053 check
->connectindex
);
2057 if((needle
->protocol
& PROT_FTP
) ||
2058 ((needle
->protocol
& PROT_HTTP
) &&
2059 (data
->state
.authhost
.want
==CURLAUTH_NTLM
))) {
2060 /* This is FTP or HTTP+NTLM, verify that we're using the same name
2061 and password as well */
2062 if(!strequal(needle
->user
, check
->user
) ||
2063 !strequal(needle
->passwd
, check
->passwd
)) {
2064 /* one of them was different */
2071 else { /* The requested needle connection is using a proxy,
2072 is the checked one using the same? */
2073 if(check
->bits
.httpproxy
&&
2074 strequal(needle
->proxy
.name
, check
->proxy
.name
) &&
2075 needle
->port
== check
->port
) {
2076 /* This is the same proxy connection, use it! */
2082 if (!IsPipeliningEnabled(data
)) {
2083 /* The check for a dead socket makes sense only in the
2084 non-pipelining case */
2085 bool dead
= SocketIsDead(check
->sock
[FIRSTSOCKET
]);
2088 infof(data
, "Connection #%d seems to be dead!\n", i
);
2090 Curl_disconnect(check
); /* disconnect resources */
2091 data
->state
.connc
->connects
[i
]=NULL
; /* nothing here */
2097 check
->inuse
= TRUE
; /* mark this as being in use so that no other
2098 handle in a multi stack may nick it */
2101 /* Mark the connection as being in a pipeline */
2102 check
->is_in_pipeline
= TRUE
;
2105 check
->connectindex
= i
; /* Set this appropriately since it might have
2106 been set to -1 when the easy was removed
2109 return TRUE
; /* yes, we found one to use! */
2113 return FALSE
; /* no matching connecting exists */
2119 * This function frees/closes a connection in the connection cache. This
2120 * should take the previously set policy into account when deciding which
2121 * of the connections to kill.
2124 ConnectionKillOne(struct SessionHandle
*data
)
2127 struct connectdata
*conn
;
2135 for(i
=0; data
->state
.connc
&& (i
< data
->state
.connc
->num
); i
++) {
2136 conn
= data
->state
.connc
->connects
[i
];
2138 if(!conn
|| conn
->inuse
)
2141 /* Set higher score for the age passed since the connection was used */
2142 score
= Curl_tvdiff(now
, conn
->now
);
2144 if(score
> highscore
) {
2149 if(connindex
>= 0) {
2150 /* Set the connection's owner correctly */
2151 conn
= data
->state
.connc
->connects
[connindex
];
2154 /* the winner gets the honour of being disconnected */
2155 (void)Curl_disconnect(conn
);
2157 /* clean the array entry */
2158 data
->state
.connc
->connects
[connindex
] = NULL
;
2161 return connindex
; /* return the available index or -1 */
2164 /* this connection can now be marked 'idle' */
2166 ConnectionDone(struct connectdata
*conn
)
2168 conn
->inuse
= FALSE
;
2169 if (!conn
->send_pipe
&& !conn
->recv_pipe
)
2170 conn
->is_in_pipeline
= FALSE
;
2174 * The given input connection struct pointer is to be stored. If the "cache"
2175 * is already full, we must clean out the most suitable using the previously
2178 * The given connection should be unique. That must've been checked prior to
2182 ConnectionStore(struct SessionHandle
*data
,
2183 struct connectdata
*conn
)
2186 for(i
=0; i
< data
->state
.connc
->num
; i
++) {
2187 if(!data
->state
.connc
->connects
[i
])
2190 if(i
== data
->state
.connc
->num
) {
2191 /* there was no room available, kill one */
2192 i
= ConnectionKillOne(data
);
2194 infof(data
, "Connection (#%d) was killed to make room (holds %d)\n",
2195 i
, data
->state
.connc
->num
);
2197 infof(data
, "This connection did not fit in the connection cache\n");
2200 conn
->connectindex
= i
; /* Make the child know where the pointer to this
2201 particular data is stored. But note that this -1
2202 if this is not within the cache and this is
2203 probably not checked for everywhere (yet). */
2206 /* Only do this if a true index was returned, if -1 was returned there
2207 is no room in the cache for an unknown reason and we cannot store
2210 TODO: make sure we really can work with more handles than positions in
2211 the cache, or possibly we should (allow to automatically) resize the
2212 connection cache when we add more easy handles to a multi handle!
2214 data
->state
.connc
->connects
[i
] = conn
; /* fill in this */
2221 static CURLcode
ConnectPlease(struct SessionHandle
*data
,
2222 struct connectdata
*conn
,
2223 struct Curl_dns_entry
*hostaddr
,
2227 Curl_addrinfo
*addr
;
2228 char *hostname
= conn
->bits
.httpproxy
?conn
->proxy
.name
:conn
->host
.name
;
2230 infof(data
, "About to connect() to %s%s port %d (#%d)\n",
2231 conn
->bits
.httpproxy
?"proxy ":"",
2232 hostname
, conn
->port
, conn
->connectindex
);
2234 /*************************************************************
2235 * Connect to server/proxy
2236 *************************************************************/
2237 result
= Curl_connecthost(conn
,
2239 &conn
->sock
[FIRSTSOCKET
],
2242 if(CURLE_OK
== result
) {
2243 /* All is cool, then we store the current information */
2244 conn
->dns_entry
= hostaddr
;
2245 conn
->ip_addr
= addr
;
2247 Curl_store_ip_addr(conn
);
2249 switch(data
->set
.proxytype
) {
2250 case CURLPROXY_SOCKS5
:
2251 result
= Curl_SOCKS5(conn
->proxyuser
, conn
->proxypasswd
, conn
);
2253 case CURLPROXY_HTTP
:
2254 /* do nothing here. handled later. */
2256 case CURLPROXY_SOCKS4
:
2257 result
= Curl_SOCKS4(conn
->proxyuser
, conn
);
2260 failf(data
, "unknown proxytype option given");
2261 result
= CURLE_COULDNT_CONNECT
;
2270 * verboseconnect() displays verbose information after a connect
2272 static void verboseconnect(struct connectdata
*conn
)
2274 infof(conn
->data
, "Connected to %s (%s) port %d (#%d)\n",
2275 conn
->bits
.httpproxy
? conn
->proxy
.dispname
: conn
->host
.dispname
,
2276 conn
->ip_addr_str
, conn
->port
, conn
->connectindex
);
2279 int Curl_protocol_getsock(struct connectdata
*conn
,
2280 curl_socket_t
*socks
,
2283 if(conn
->curl_proto_getsock
)
2284 return conn
->curl_proto_getsock(conn
, socks
, numsocks
);
2285 return GETSOCK_BLANK
;
2288 int Curl_doing_getsock(struct connectdata
*conn
,
2289 curl_socket_t
*socks
,
2292 if(conn
&& conn
->curl_doing_getsock
)
2293 return conn
->curl_doing_getsock(conn
, socks
, numsocks
);
2294 return GETSOCK_BLANK
;
2298 * We are doing protocol-specific connecting and this is being called over and
2299 * over from the multi interface until the connection phase is done on
2303 CURLcode
Curl_protocol_connecting(struct connectdata
*conn
,
2306 CURLcode result
=CURLE_OK
;
2308 if(conn
&& conn
->curl_connecting
) {
2310 result
= conn
->curl_connecting(conn
, done
);
2319 * We are DOING this is being called over and over from the multi interface
2320 * until the DOING phase is done on protocol layer.
2323 CURLcode
Curl_protocol_doing(struct connectdata
*conn
, bool *done
)
2325 CURLcode result
=CURLE_OK
;
2327 if(conn
&& conn
->curl_doing
) {
2329 result
= conn
->curl_doing(conn
, done
);
2338 * We have discovered that the TCP connection has been successful, we can now
2339 * proceed with some action.
2342 CURLcode
Curl_protocol_connect(struct connectdata
*conn
,
2343 bool *protocol_done
)
2345 CURLcode result
=CURLE_OK
;
2346 struct SessionHandle
*data
= conn
->data
;
2348 *protocol_done
= FALSE
;
2350 if(conn
->bits
.tcpconnect
&& conn
->bits
.protoconnstart
) {
2351 /* We already are connected, get back. This may happen when the connect
2352 worked fine in the first call, like when we connect to a local server
2353 or proxy. Note that we don't know if the protocol is actually done.
2355 Unless this protocol doesn't have any protocol-connect callback, as
2356 then we know we're done. */
2357 if(!conn
->curl_connecting
)
2358 *protocol_done
= TRUE
;
2363 if(!conn
->bits
.tcpconnect
) {
2365 Curl_pgrsTime(data
, TIMER_CONNECT
); /* connect done */
2367 if(data
->set
.verbose
)
2368 verboseconnect(conn
);
2371 if(!conn
->bits
.protoconnstart
) {
2372 if(conn
->curl_connect
) {
2373 /* is there a protocol-specific connect() procedure? */
2375 /* Set start time here for timeout purposes in the connect procedure, it
2376 is later set again for the progress meter purpose */
2377 conn
->now
= Curl_tvnow();
2379 /* Call the protocol-specific connect function */
2380 result
= conn
->curl_connect(conn
, protocol_done
);
2383 *protocol_done
= TRUE
;
2385 /* it has started, possibly even completed but that knowledge isn't stored
2388 conn
->bits
.protoconnstart
= TRUE
;
2391 return result
; /* pass back status */
2395 * Helpers for IDNA convertions.
2398 static bool is_ASCII_name(const char *hostname
)
2400 const unsigned char *ch
= (const unsigned char*)hostname
;
2410 * Check if characters in hostname is allowed in Top Level Domain.
2412 static bool tld_check_name(struct SessionHandle
*data
,
2413 const char *ace_hostname
)
2416 char *uc_name
= NULL
;
2419 /* Convert (and downcase) ACE-name back into locale's character set */
2420 rc
= idna_to_unicode_lzlz(ace_hostname
, &uc_name
, 0);
2421 if (rc
!= IDNA_SUCCESS
)
2424 rc
= tld_check_lz(uc_name
, &err_pos
, NULL
);
2425 if (rc
== TLD_INVALID
)
2426 infof(data
, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2427 #ifdef HAVE_TLD_STRERROR
2428 tld_strerror((Tld_rc
)rc
),
2432 err_pos
, uc_name
[err_pos
],
2433 uc_name
[err_pos
] & 255);
2434 else if (rc
!= TLD_SUCCESS
)
2435 infof(data
, "WARNING: TLD check for %s failed; %s\n",
2437 #ifdef HAVE_TLD_STRERROR
2438 tld_strerror((Tld_rc
)rc
)
2445 return (bool)(rc
== TLD_SUCCESS
);
2449 static void fix_hostname(struct SessionHandle
*data
,
2450 struct connectdata
*conn
, struct hostname
*host
)
2452 /* set the name we use to display the host name */
2453 host
->dispname
= host
->name
;
2456 /*************************************************************
2457 * Check name for non-ASCII and convert hostname to ACE form.
2458 *************************************************************/
2459 if (!is_ASCII_name(host
->name
) &&
2460 stringprep_check_version(LIBIDN_REQUIRED_VERSION
)) {
2461 char *ace_hostname
= NULL
;
2462 int rc
= idna_to_ascii_lz(host
->name
, &ace_hostname
, 0);
2463 infof (data
, "Input domain encoded as `%s'\n",
2464 stringprep_locale_charset ());
2465 if (rc
!= IDNA_SUCCESS
)
2466 infof(data
, "Failed to convert %s to ACE; %s\n",
2467 host
->name
, Curl_idn_strerror(conn
,rc
));
2469 /* tld_check_name() displays a warning if the host name contains
2470 "illegal" characters for this TLD */
2471 (void)tld_check_name(data
, ace_hostname
);
2473 host
->encalloc
= ace_hostname
;
2474 /* change the name pointer to point to the encoded hostname */
2475 host
->name
= host
->encalloc
;
2479 (void)data
; /* never used */
2480 (void)conn
; /* never used */
2485 * Parse URL and fill in the relevant members of the connection struct.
2487 static CURLcode
ParseURLAndFillConnection(struct SessionHandle
*data
,
2488 struct connectdata
*conn
)
2493 char *path
= data
->reqdata
.path
;
2495 /*************************************************************
2498 * We need to parse the url even when using the proxy, because we will need
2499 * the hostname and port in case we are trying to SSL connect through the
2500 * proxy -- and we don't know if we will need to use SSL until we parse the
2502 ************************************************************/
2503 if((2 == sscanf(data
->change
.url
, "%15[^:]:%[^\n]",
2505 path
)) && strequal(conn
->protostr
, "file")) {
2506 if(path
[0] == '/' && path
[1] == '/') {
2507 /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
2508 * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2509 * file://localhost/<path> is similar to how other schemes treat missing
2510 * hostnames. See RFC 1808. */
2512 /* This cannot be done with strcpy() in a portable manner, since the
2513 memory areas overlap! */
2514 memmove(path
, path
+ 2, strlen(path
+ 2)+1);
2517 * we deal with file://<host>/<path> differently since it supports no
2518 * hostname other than "localhost" and "127.0.0.1", which is unique among
2519 * the URL protocols specified in RFC 1738
2521 if(path
[0] != '/') {
2522 /* the URL included a host name, we ignore host names in file:// URLs
2523 as the standards don't define what to do with them */
2524 char *ptr
=strchr(path
, '/');
2526 /* there was a slash present
2528 RFC1738 (section 3.1, page 5) says:
2530 The rest of the locator consists of data specific to the scheme,
2531 and is known as the "url-path". It supplies the details of how the
2532 specified resource can be accessed. Note that the "/" between the
2533 host (or port) and the url-path is NOT part of the url-path.
2535 As most agents use file://localhost/foo to get '/foo' although the
2536 slash preceding foo is a separator and not a slash for the path,
2537 a URL as file://localhost//foo must be valid as well, to refer to
2538 the same file with an absolute path.
2541 if(ptr
[1] && ('/' == ptr
[1]))
2542 /* if there was two slashes, we skip the first one as that is then
2543 used truly as a separator */
2546 /* This cannot be made with strcpy, as the memory chunks overlap! */
2547 memmove(path
, ptr
, strlen(ptr
)+1);
2551 strcpy(conn
->protostr
, "file"); /* store protocol string lowercase */
2557 if (2 > sscanf(data
->change
.url
,
2558 "%15[^\n:]://%[^\n/]%[^\n]",
2560 conn
->host
.name
, path
)) {
2563 * The URL was badly formatted, let's try the browser-style _without_
2564 * protocol specified like 'http://'.
2566 if((1 > sscanf(data
->change
.url
, "%[^\n/]%[^\n]",
2567 conn
->host
.name
, path
)) ) {
2569 * We couldn't even get this format.
2571 failf(data
, "<url> malformed");
2572 return CURLE_URL_MALFORMAT
;
2576 * Since there was no protocol part specified, we guess what protocol it
2577 * is based on the first letters of the server name.
2580 /* Note: if you add a new protocol, please update the list in
2581 * lib/version.c too! */
2583 if(checkprefix("FTP.", conn
->host
.name
))
2584 strcpy(conn
->protostr
, "ftp");
2585 else if (checkprefix("DICT.", conn
->host
.name
))
2586 strcpy(conn
->protostr
, "DICT");
2587 else if (checkprefix("LDAP.", conn
->host
.name
))
2588 strcpy(conn
->protostr
, "LDAP");
2590 strcpy(conn
->protostr
, "http");
2593 conn
->protocol
|= PROT_MISSING
; /* not given in URL */
2597 /* We search for '?' in the host name (but only on the right side of a
2598 * @-letter to allow ?-letters in username and password) to handle things
2599 * like http://example.com?param= (notice the missing '/').
2601 at
= strchr(conn
->host
.name
, '@');
2603 tmp
= strchr(at
+1, '?');
2605 tmp
= strchr(conn
->host
.name
, '?');
2608 /* We must insert a slash before the '?'-letter in the URL. If the URL had
2609 a slash after the '?', that is where the path currently begins and the
2610 '?string' is still part of the host name.
2612 We must move the trailing part from the host name and put it first in
2613 the path. And have it all prefixed with a slash.
2616 size_t hostlen
= strlen(tmp
);
2617 size_t pathlen
= strlen(path
);
2619 /* move the existing path plus the zero byte forward, to make room for
2620 the host-name part */
2621 memmove(path
+hostlen
+1, path
, pathlen
+1);
2623 /* now copy the trailing host part in front of the existing path */
2624 memcpy(path
+1, tmp
, hostlen
);
2626 path
[0]='/'; /* prepend the missing slash */
2628 *tmp
=0; /* now cut off the hostname at the ? */
2631 /* if there's no path set, use a single slash */
2635 /* If the URL is malformatted (missing a '/' after hostname before path) we
2636 * insert a slash here. The only letter except '/' we accept to start a path
2639 if(path
[0] == '?') {
2640 /* We need this function to deal with overlapping memory areas. We know
2641 that the memory area 'path' points to is 'urllen' bytes big and that
2642 is bigger than the path. Use +1 to move the zero byte too. */
2643 memmove(&path
[1], path
, strlen(path
)+1);
2648 * So if the URL was A://B/C,
2649 * conn->protostr is A
2650 * conn->host.name is B
2651 * data->reqdata.path is /C
2657 static void llist_dtor(void *user
, void *element
)
2666 * CreateConnection() sets up a new connectdata struct, or re-uses an already
2667 * existing one, and resolves host name.
2669 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
2670 * response will be coming asynchronously. If *async is FALSE, the name is
2673 * @param data The sessionhandle pointer
2674 * @param in_connect is set to the next connection data pointer
2675 * @param addr is set to the new dns entry for this connection. If this
2676 * connection is re-used it will be NULL.
2677 * @param async is set TRUE/FALSE depending on the nature of this lookup
2679 * @see SetupConnection()
2681 * *NOTE* this function assigns the conn->data pointer!
2684 static CURLcode
CreateConnection(struct SessionHandle
*data
,
2685 struct connectdata
**in_connect
,
2686 struct Curl_dns_entry
**addr
,
2691 CURLcode result
=CURLE_OK
;
2692 struct connectdata
*conn
;
2693 struct connectdata
*conn_temp
= NULL
;
2695 struct Curl_dns_entry
*hostaddr
;
2696 #if defined(HAVE_ALARM) && !defined(USE_ARES)
2697 unsigned int prev_alarm
=0;
2700 char user
[MAX_CURL_USER_LENGTH
];
2701 char passwd
[MAX_CURL_PASSWORD_LENGTH
];
2705 bool proxy_alloc
= FALSE
;
2709 #ifdef HAVE_SIGACTION
2710 struct sigaction keep_sigact
; /* store the old struct here */
2711 bool keep_copysig
=FALSE
; /* did copy it? */
2714 void (*keep_sigact
)(int); /* store the old handler here */
2715 #endif /* HAVE_SIGNAL */
2716 #endif /* HAVE_SIGACTION */
2717 #endif /* SIGALRM */
2718 #endif /* USE_ARES */
2720 *addr
= NULL
; /* nothing yet */
2723 /*************************************************************
2725 *************************************************************/
2727 if(!data
->change
.url
)
2728 return CURLE_URL_MALFORMAT
;
2730 /* First, split up the current URL in parts so that we can use the
2731 parts for checking against the already present connections. In order
2732 to not have to modify everything at once, we allocate a temporary
2733 connection data struct and fill in for comparison purposes. */
2735 conn
= (struct connectdata
*)calloc(sizeof(struct connectdata
), 1);
2737 *in_connect
= NULL
; /* clear the pointer */
2738 return CURLE_OUT_OF_MEMORY
;
2740 /* We must set the return variable as soon as possible, so that our
2741 parent can cleanup any possible allocs we may have done before
2745 /* and we setup a few fields in case we end up actually using this struct */
2747 conn
->data
= data
; /* Setup the association between this connection
2748 and the SessionHandle */
2750 conn
->sock
[FIRSTSOCKET
] = CURL_SOCKET_BAD
; /* no file descriptor */
2751 conn
->sock
[SECONDARYSOCKET
] = CURL_SOCKET_BAD
; /* no file descriptor */
2752 conn
->connectindex
= -1; /* no index */
2754 conn
->bits
.httpproxy
= (bool)(data
->set
.proxy
/* http proxy or not */
2756 && (data
->set
.proxytype
== CURLPROXY_HTTP
));
2757 proxy
= data
->set
.proxy
; /* if global proxy is set, this is it */
2759 /* Default protocol-independent behavior doesn't support persistent
2760 connections, so we set this to force-close. Protocols that support
2761 this need to set this to FALSE in their "curl_do" functions. */
2762 conn
->bits
.close
= TRUE
;
2764 conn
->readchannel_inuse
= FALSE
;
2765 conn
->writechannel_inuse
= FALSE
;
2770 /* Initialize the pipeline lists */
2771 conn
->send_pipe
= Curl_llist_alloc((curl_llist_dtor
) llist_dtor
);
2772 conn
->recv_pipe
= Curl_llist_alloc((curl_llist_dtor
) llist_dtor
);
2774 /* Store creation time to help future close decision making */
2775 conn
->created
= Curl_tvnow();
2778 data
->reqdata
.use_range
= (bool)(NULL
!= data
->set
.set_range
);
2780 data
->reqdata
.range
= data
->set
.set_range
; /* clone the range setting */
2781 data
->reqdata
.resume_from
= data
->set
.set_resume_from
;
2783 conn
->bits
.user_passwd
= (bool)(NULL
!= data
->set
.userpwd
);
2784 conn
->bits
.proxy_user_passwd
= (bool)(NULL
!= data
->set
.proxyuserpwd
);
2785 conn
->bits
.no_body
= data
->set
.opt_no_body
;
2786 conn
->bits
.tunnel_proxy
= data
->set
.tunnel_thru_httpproxy
;
2787 conn
->bits
.ftp_use_epsv
= data
->set
.ftp_use_epsv
;
2788 conn
->bits
.ftp_use_eprt
= data
->set
.ftp_use_eprt
;
2790 /* This initing continues below, see the comment "Continue connectdata
2791 * initialization here" */
2793 /***********************************************************
2794 * We need to allocate memory to store the path in. We get the size of the
2795 * full URL to be sure, and we need to make it at least 256 bytes since
2796 * other parts of the code will rely on this fact
2797 ***********************************************************/
2798 #define LEAST_PATH_ALLOC 256
2799 urllen
=strlen(data
->change
.url
);
2800 if(urllen
< LEAST_PATH_ALLOC
)
2801 urllen
=LEAST_PATH_ALLOC
;
2803 if (!data
->set
.source_url
/* 3rd party FTP */
2804 && data
->reqdata
.pathbuffer
) {
2805 /* Free the old buffer */
2806 free(data
->reqdata
.pathbuffer
);
2810 * We malloc() the buffers below urllen+2 to make room for to possibilities:
2811 * 1 - an extra terminating zero
2812 * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
2815 data
->reqdata
.pathbuffer
=(char *)malloc(urllen
+2);
2816 if(NULL
== data
->reqdata
.pathbuffer
)
2817 return CURLE_OUT_OF_MEMORY
; /* really bad error */
2818 data
->reqdata
.path
= data
->reqdata
.pathbuffer
;
2820 conn
->host
.rawalloc
=(char *)malloc(urllen
+2);
2821 if(NULL
== conn
->host
.rawalloc
)
2822 return CURLE_OUT_OF_MEMORY
;
2824 conn
->host
.name
= conn
->host
.rawalloc
;
2825 conn
->host
.name
[0] = 0;
2827 result
= ParseURLAndFillConnection(data
, conn
);
2828 if (result
!= CURLE_OK
) {
2832 /*************************************************************
2833 * Take care of proxy authentication stuff
2834 *************************************************************/
2835 if(conn
->bits
.proxy_user_passwd
) {
2836 char proxyuser
[MAX_CURL_USER_LENGTH
]="";
2837 char proxypasswd
[MAX_CURL_PASSWORD_LENGTH
]="";
2839 sscanf(data
->set
.proxyuserpwd
,
2840 "%" MAX_CURL_USER_LENGTH_TXT
"[^:]:"
2841 "%" MAX_CURL_PASSWORD_LENGTH_TXT
"[^\n]",
2842 proxyuser
, proxypasswd
);
2844 conn
->proxyuser
= curl_easy_unescape(data
, proxyuser
, 0, NULL
);
2845 if(!conn
->proxyuser
)
2846 return CURLE_OUT_OF_MEMORY
;
2848 conn
->proxypasswd
= curl_easy_unescape(data
, proxypasswd
, 0, NULL
);
2849 if(!conn
->proxypasswd
)
2850 return CURLE_OUT_OF_MEMORY
;
2853 #ifndef CURL_DISABLE_HTTP
2854 /*************************************************************
2855 * Detect what (if any) proxy to use
2856 *************************************************************/
2857 if(!conn
->bits
.httpproxy
) {
2858 /* If proxy was not specified, we check for default proxy environment
2859 * variables, to enable i.e Lynx compliance:
2861 * http_proxy=http://some.server.dom:port/
2862 * https_proxy=http://some.server.dom:port/
2863 * ftp_proxy=http://some.server.dom:port/
2864 * no_proxy=domain1.dom,host.domain2.dom
2865 * (a comma-separated list of hosts which should
2866 * not be proxied, or an asterisk to override
2867 * all proxy variables)
2868 * all_proxy=http://some.server.dom:port/
2869 * (seems to exist for the CERN www lib. Probably
2870 * the first to check for.)
2872 * For compatibility, the all-uppercase versions of these variables are
2873 * checked if the lowercase versions don't exist.
2875 char *no_proxy
=NULL
;
2876 char *no_proxy_tok_buf
;
2877 char proxy_env
[128];
2879 no_proxy
=curl_getenv("no_proxy");
2881 no_proxy
=curl_getenv("NO_PROXY");
2883 if(!no_proxy
|| !strequal("*", no_proxy
)) {
2884 /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2887 nope
=no_proxy
?strtok_r(no_proxy
, ", ", &no_proxy_tok_buf
):NULL
;
2890 char *endptr
= strchr(conn
->host
.name
, ':');
2892 namelen
=endptr
-conn
->host
.name
;
2894 namelen
=strlen(conn
->host
.name
);
2896 if(strlen(nope
) <= namelen
) {
2898 conn
->host
.name
+ namelen
- strlen(nope
);
2899 if(checkprefix(nope
, checkn
)) {
2900 /* no proxy for this host! */
2904 nope
=strtok_r(NULL
, ", ", &no_proxy_tok_buf
);
2907 /* It was not listed as without proxy */
2908 char *protop
= conn
->protostr
;
2909 char *envp
= proxy_env
;
2912 /* Now, build <protocol>_proxy and check for such a one to use */
2914 *envp
++ = (char)tolower((int)*protop
++);
2917 strcpy(envp
, "_proxy");
2919 /* read the protocol proxy: */
2920 prox
=curl_getenv(proxy_env
);
2923 * We don't try the uppercase version of HTTP_PROXY because of
2926 * When curl is used in a webserver application
2927 * environment (cgi or php), this environment variable can
2928 * be controlled by the web server user by setting the
2929 * http header 'Proxy:' to some value.
2931 * This can cause 'internal' http/ftp requests to be
2932 * arbitrarily redirected by any external attacker.
2934 if(!prox
&& !strequal("http_proxy", proxy_env
)) {
2935 /* There was no lowercase variable, try the uppercase version: */
2936 for(envp
= proxy_env
; *envp
; envp
++)
2937 *envp
= (char)toupper((int)*envp
);
2938 prox
=curl_getenv(proxy_env
);
2941 if(prox
&& *prox
) { /* don't count "" strings */
2942 proxy
= prox
; /* use this */
2945 proxy
= curl_getenv("all_proxy"); /* default proxy to use */
2947 proxy
=curl_getenv("ALL_PROXY");
2950 if(proxy
&& *proxy
) {
2951 long bits
= conn
->protocol
& (PROT_HTTPS
|PROT_SSL
|PROT_MISSING
);
2952 /* force this to become HTTP */
2953 conn
->protocol
= PROT_HTTP
| bits
;
2955 proxy_alloc
=TRUE
; /* this needs to be freed later */
2956 conn
->bits
.httpproxy
= TRUE
;
2958 } /* if (!nope) - it wasn't specified non-proxy */
2959 } /* NO_PROXY wasn't specified or '*' */
2962 } /* if not using proxy */
2963 #endif /* CURL_DISABLE_HTTP */
2965 /*************************************************************
2966 * No protocol part in URL was used, add it!
2967 *************************************************************/
2968 if(conn
->protocol
&PROT_MISSING
) {
2969 /* We're guessing prefixes here and if we're told to use a proxy or if
2970 we're gonna follow a Location: later or... then we need the protocol
2971 part added so that we have a valid URL. */
2974 reurl
= aprintf("%s://%s", conn
->protostr
, data
->change
.url
);
2977 return CURLE_OUT_OF_MEMORY
;
2979 data
->change
.url
= reurl
;
2980 data
->change
.url_alloc
= TRUE
; /* free this later */
2981 conn
->protocol
&= ~PROT_MISSING
; /* switch that one off again */
2984 #ifndef CURL_DISABLE_HTTP
2985 /************************************************************
2986 * RESUME on a HTTP page is a tricky business. First, let's just check that
2987 * 'range' isn't used, then set the range parameter and leave the resume as
2988 * it is to inform about this situation for later use. We will then
2989 * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2990 * server, we will get the document resumed. If we talk to a HTTP/1.0
2991 * server, we just fail since we can't rewind the file writing from within
2993 ***********************************************************/
2994 if(data
->reqdata
.resume_from
) {
2995 if(!data
->reqdata
.use_range
) {
2996 /* if it already was in use, we just skip this */
2997 data
->reqdata
.range
= aprintf("%" FORMAT_OFF_T
"-", data
->reqdata
.resume_from
);
2998 if(!data
->reqdata
.range
)
2999 return CURLE_OUT_OF_MEMORY
;
3000 data
->reqdata
.rangestringalloc
= TRUE
; /* mark as allocated */
3001 data
->reqdata
.use_range
= 1; /* switch on range usage */
3005 /*************************************************************
3006 * Setup internals depending on protocol
3007 *************************************************************/
3009 conn
->socktype
= SOCK_STREAM
; /* most of them are TCP streams */
3011 if (strequal(conn
->protostr
, "HTTP")) {
3012 #ifndef CURL_DISABLE_HTTP
3013 conn
->port
= PORT_HTTP
;
3014 conn
->remote_port
= PORT_HTTP
;
3015 conn
->protocol
|= PROT_HTTP
;
3016 conn
->curl_do
= Curl_http
;
3017 conn
->curl_do_more
= (Curl_do_more_func
)ZERO_NULL
;
3018 conn
->curl_done
= Curl_http_done
;
3019 conn
->curl_connect
= Curl_http_connect
;
3021 failf(data
, LIBCURL_NAME
3022 " was built with HTTP disabled, http: not supported!");
3023 return CURLE_UNSUPPORTED_PROTOCOL
;
3026 else if (strequal(conn
->protostr
, "HTTPS")) {
3027 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
3029 conn
->port
= PORT_HTTPS
;
3030 conn
->remote_port
= PORT_HTTPS
;
3031 conn
->protocol
|= PROT_HTTP
|PROT_HTTPS
|PROT_SSL
;
3033 conn
->curl_do
= Curl_http
;
3034 conn
->curl_do_more
= (Curl_do_more_func
)ZERO_NULL
;
3035 conn
->curl_done
= Curl_http_done
;
3036 conn
->curl_connect
= Curl_http_connect
;
3037 conn
->curl_connecting
= Curl_https_connecting
;
3038 conn
->curl_proto_getsock
= Curl_https_getsock
;
3041 failf(data
, LIBCURL_NAME
3042 " was built with SSL disabled, https: not supported!");
3043 return CURLE_UNSUPPORTED_PROTOCOL
;
3044 #endif /* !USE_SSL */
3046 else if(strequal(conn
->protostr
, "FTP") ||
3047 strequal(conn
->protostr
, "FTPS")) {
3049 #ifndef CURL_DISABLE_FTP
3051 int port
= PORT_FTP
;
3053 if(strequal(conn
->protostr
, "FTPS")) {
3055 conn
->protocol
|= PROT_FTPS
|PROT_SSL
;
3056 conn
->ssl
[SECONDARYSOCKET
].use
= TRUE
; /* send data securely */
3059 failf(data
, LIBCURL_NAME
3060 " was built with SSL disabled, ftps: not supported!");
3061 return CURLE_UNSUPPORTED_PROTOCOL
;
3062 #endif /* !USE_SSL */
3066 conn
->remote_port
= (unsigned short)port
;
3067 conn
->protocol
|= PROT_FTP
;
3069 if(proxy
&& *proxy
&& !data
->set
.tunnel_thru_httpproxy
) {
3070 /* Unless we have asked to tunnel ftp operations through the proxy, we
3071 switch and use HTTP operations only */
3072 #ifndef CURL_DISABLE_HTTP
3073 conn
->curl_do
= Curl_http
;
3074 conn
->curl_done
= Curl_http_done
;
3075 conn
->protocol
= PROT_HTTP
; /* switch to HTTP */
3077 failf(data
, "FTP over http proxy requires HTTP support built-in!");
3078 return CURLE_UNSUPPORTED_PROTOCOL
;
3082 conn
->curl_do
= Curl_ftp
;
3083 conn
->curl_do_more
= Curl_ftp_nextconnect
;
3084 conn
->curl_done
= Curl_ftp_done
;
3085 conn
->curl_connect
= Curl_ftp_connect
;
3086 conn
->curl_connecting
= Curl_ftp_multi_statemach
;
3087 conn
->curl_doing
= Curl_ftp_doing
;
3088 conn
->curl_proto_getsock
= Curl_ftp_getsock
;
3089 conn
->curl_doing_getsock
= Curl_ftp_getsock
;
3090 conn
->curl_disconnect
= Curl_ftp_disconnect
;
3093 data
->reqdata
.path
++; /* don't include the initial slash */
3095 /* FTP URLs support an extension like ";type=<typecode>" that
3096 * we'll try to get now! */
3097 type
=strstr(data
->reqdata
.path
, ";type=");
3099 type
=strstr(conn
->host
.rawalloc
, ";type=");
3103 *type
=0; /* it was in the middle of the hostname */
3104 command
= (char)toupper((int)type
[6]);
3106 case 'A': /* ASCII mode */
3107 data
->set
.prefer_ascii
= TRUE
;
3109 case 'D': /* directory mode */
3110 data
->set
.ftp_list_only
= TRUE
;
3112 case 'I': /* binary mode */
3114 /* switch off ASCII */
3115 data
->set
.prefer_ascii
= FALSE
;
3119 #else /* CURL_DISABLE_FTP */
3120 failf(data
, LIBCURL_NAME
3121 " was built with FTP disabled, ftp/ftps: not supported!");
3122 return CURLE_UNSUPPORTED_PROTOCOL
;
3125 else if(strequal(conn
->protostr
, "TELNET")) {
3126 #ifndef CURL_DISABLE_TELNET
3127 /* telnet testing factory */
3128 conn
->protocol
|= PROT_TELNET
;
3130 conn
->port
= PORT_TELNET
;
3131 conn
->remote_port
= PORT_TELNET
;
3132 conn
->curl_do
= Curl_telnet
;
3133 conn
->curl_done
= Curl_telnet_done
;
3135 failf(data
, LIBCURL_NAME
3136 " was built with TELNET disabled!");
3139 else if (strequal(conn
->protostr
, "DICT")) {
3140 #ifndef CURL_DISABLE_DICT
3141 conn
->protocol
|= PROT_DICT
;
3142 conn
->port
= PORT_DICT
;
3143 conn
->remote_port
= PORT_DICT
;
3144 conn
->curl_do
= Curl_dict
;
3145 /* no DICT-specific done */
3146 conn
->curl_done
= (Curl_done_func
)ZERO_NULL
;
3148 failf(data
, LIBCURL_NAME
3149 " was built with DICT disabled!");
3152 else if (strequal(conn
->protostr
, "LDAP")) {
3153 #ifndef CURL_DISABLE_LDAP
3154 conn
->protocol
|= PROT_LDAP
;
3155 conn
->port
= PORT_LDAP
;
3156 conn
->remote_port
= PORT_LDAP
;
3157 conn
->curl_do
= Curl_ldap
;
3158 /* no LDAP-specific done */
3159 conn
->curl_done
= (Curl_done_func
)ZERO_NULL
;
3161 failf(data
, LIBCURL_NAME
3162 " was built with LDAP disabled!");
3165 else if (strequal(conn
->protostr
, "FILE")) {
3166 #ifndef CURL_DISABLE_FILE
3167 conn
->protocol
|= PROT_FILE
;
3169 conn
->curl_do
= Curl_file
;
3170 conn
->curl_done
= Curl_file_done
;
3172 /* anyway, this is supposed to be the connect function so we better
3173 at least check that the file is present here! */
3174 result
= Curl_file_connect(conn
);
3176 /* Setup a "faked" transfer that'll do nothing */
3177 if(CURLE_OK
== result
) {
3179 conn
->bits
.tcpconnect
= TRUE
; /* we are "connected */
3180 ConnectionStore(data
, conn
);
3182 result
= Curl_setup_transfer(conn
, -1, -1, FALSE
, NULL
, /* no download */
3183 -1, NULL
); /* no upload */
3188 failf(data
, LIBCURL_NAME
3189 " was built with FILE disabled!");
3192 else if (strequal(conn
->protostr
, "TFTP")) {
3193 #ifndef CURL_DISABLE_TFTP
3195 conn
->socktype
= SOCK_DGRAM
; /* UDP datagram based */
3196 conn
->protocol
|= PROT_TFTP
;
3197 conn
->port
= PORT_TFTP
;
3198 conn
->remote_port
= PORT_TFTP
;
3199 conn
->curl_connect
= Curl_tftp_connect
;
3200 conn
->curl_do
= Curl_tftp
;
3201 conn
->curl_done
= Curl_tftp_done
;
3202 /* TFTP URLs support an extension like ";mode=<typecode>" that
3203 * we'll try to get now! */
3204 type
=strstr(data
->reqdata
.path
, ";mode=");
3206 type
=strstr(conn
->host
.rawalloc
, ";mode=");
3210 *type
=0; /* it was in the middle of the hostname */
3211 command
= (char)toupper((int)type
[6]);
3213 case 'A': /* ASCII mode */
3214 case 'N': /* NETASCII mode */
3215 data
->set
.prefer_ascii
= TRUE
;
3217 case 'O': /* octet mode */
3218 case 'I': /* binary mode */
3220 /* switch off ASCII */
3221 data
->set
.prefer_ascii
= FALSE
;
3226 failf(data
, LIBCURL_NAME
3227 " was built with TFTP disabled!");
3230 else if (strequal(conn
->protostr
, "SCP")) {
3232 conn
->port
= PORT_SSH
;
3233 conn
->remote_port
= PORT_SSH
;
3234 conn
->protocol
= PROT_SCP
;
3235 conn
->curl_connect
= Curl_ssh_connect
; /* ssh_connect? */
3236 conn
->curl_do
= Curl_scp_do
;
3237 conn
->curl_done
= Curl_scp_done
;
3238 conn
->curl_do_more
= (Curl_do_more_func
)ZERO_NULL
;
3240 failf(data
, LIBCURL_NAME
3241 " was built without LIBSSH2, scp: not supported!");
3242 return CURLE_UNSUPPORTED_PROTOCOL
;
3245 else if (strequal(conn
->protostr
, "SFTP")) {
3247 conn
->port
= PORT_SSH
;
3248 conn
->remote_port
= PORT_SSH
;
3249 conn
->protocol
= PROT_SFTP
;
3250 conn
->curl_connect
= Curl_ssh_connect
; /* ssh_connect? */
3251 conn
->curl_do
= Curl_sftp_do
;
3252 conn
->curl_done
= Curl_sftp_done
;
3253 conn
->curl_do_more
= (Curl_do_more_func
)NULL
;
3255 failf(data
, LIBCURL_NAME
3256 " was built without LIBSSH2, scp: not supported!");
3257 return CURLE_UNSUPPORTED_PROTOCOL
;
3261 /* We fell through all checks and thus we don't support the specified
3263 failf(data
, "Unsupported protocol: %s", conn
->protostr
);
3264 return CURLE_UNSUPPORTED_PROTOCOL
;
3267 if(proxy
&& *proxy
) {
3268 /* If this is supposed to use a proxy, we need to figure out the proxy
3269 host name name, so that we can re-use an existing connection
3270 that may exist registered to the same proxy host. */
3275 /* We need to make a duplicate of the proxy so that we can modify the
3276 string safely. If 'proxy_alloc' is TRUE, the string is already
3277 allocated and we can treat it as duplicated. */
3278 char *proxydup
=proxy_alloc
?proxy
:strdup(proxy
);
3280 /* We use 'proxyptr' to point to the proxy name from now on... */
3281 char *proxyptr
=proxydup
;
3285 if(NULL
== proxydup
) {
3286 failf(data
, "memory shortage");
3287 return CURLE_OUT_OF_MEMORY
;
3290 /* We do the proxy host string parsing here. We want the host name and the
3291 * port name. Accept a protocol:// prefix, even though it should just be
3295 /* Skip the protocol part if present */
3296 endofprot
=strstr(proxyptr
, "://");
3298 proxyptr
= endofprot
+3;
3300 /* Is there a username and password given in this proxy url? */
3301 atsign
= strchr(proxyptr
, '@');
3303 char proxyuser
[MAX_CURL_USER_LENGTH
];
3304 char proxypasswd
[MAX_CURL_PASSWORD_LENGTH
];
3307 if(1 <= sscanf(proxyptr
,
3308 "%" MAX_CURL_USER_LENGTH_TXT
"[^:]:"
3309 "%" MAX_CURL_PASSWORD_LENGTH_TXT
"[^@]",
3310 proxyuser
, proxypasswd
)) {
3311 CURLcode res
= CURLE_OK
;
3313 /* found user and password, rip them out. note that we are
3314 unescaping them, as there is otherwise no way to have a
3315 username or password with reserved characters like ':' in
3317 Curl_safefree(conn
->proxyuser
);
3318 conn
->proxyuser
= curl_easy_unescape(data
, proxyuser
, 0, NULL
);
3320 if(!conn
->proxyuser
)
3321 res
= CURLE_OUT_OF_MEMORY
;
3323 Curl_safefree(conn
->proxypasswd
);
3324 conn
->proxypasswd
= curl_easy_unescape(data
, proxypasswd
, 0, NULL
);
3326 if(!conn
->proxypasswd
)
3327 res
= CURLE_OUT_OF_MEMORY
;
3330 if(CURLE_OK
== res
) {
3331 conn
->bits
.proxy_user_passwd
= TRUE
; /* enable it */
3332 atsign
= strdup(atsign
+1); /* the right side of the @-letter */
3335 free(proxydup
); /* free the former proxy string */
3336 proxydup
= proxyptr
= atsign
; /* now use this instead */
3339 res
= CURLE_OUT_OF_MEMORY
;
3343 free(proxydup
); /* free the allocated proxy string */
3349 /* start scanning for port number at this point */
3352 /* detect and extract RFC2732-style IPv6-addresses */
3353 if(*proxyptr
== '[') {
3354 char *ptr
= ++proxyptr
; /* advance beyond the initial bracket */
3355 while(*ptr
&& (ISXDIGIT(*ptr
) || (*ptr
== ':')))
3358 /* yeps, it ended nicely with a bracket as well */
3362 /* Note that if this didn't end with a bracket, we still advanced the
3363 * proxyptr first, but I can't see anything wrong with that as no host
3364 * name nor a numeric can legally start with a bracket.
3368 /* Get port number off proxy.server.com:1080 */
3369 prox_portno
= strchr(portptr
, ':');
3371 *prox_portno
= 0x0; /* cut off number from host name */
3373 /* now set the local port number */
3374 conn
->port
= atoi(prox_portno
);
3376 else if(data
->set
.proxyport
) {
3377 /* None given in the proxy string, then get the default one if it is
3379 conn
->port
= data
->set
.proxyport
;
3382 /* now, clone the cleaned proxy host name */
3383 conn
->proxy
.rawalloc
= strdup(proxyptr
);
3384 conn
->proxy
.name
= conn
->proxy
.rawalloc
;
3386 free(proxydup
); /* free the duplicate pointer and not the modified */
3387 proxy
= NULL
; /* this may have just been freed */
3388 if(!conn
->proxy
.rawalloc
)
3389 return CURLE_OUT_OF_MEMORY
;
3392 /*************************************************************
3393 * If the protocol is using SSL and HTTP proxy is used, we set
3394 * the tunnel_proxy bit.
3395 *************************************************************/
3396 if((conn
->protocol
&PROT_SSL
) && conn
->bits
.httpproxy
)
3397 conn
->bits
.tunnel_proxy
= TRUE
;
3399 /*************************************************************
3400 * Take care of user and password authentication stuff
3401 *************************************************************/
3404 * Inputs: data->set.userpwd (CURLOPT_USERPWD)
3405 * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
3406 * data->set.use_netrc (CURLOPT_NETRC)
3409 * hard-coded defaults
3411 * Outputs: (almost :- all currently undefined)
3412 * conn->bits.user_passwd - non-zero if non-default passwords exist
3413 * conn->user - non-zero length if defined
3414 * conn->passwd - ditto
3415 * conn->host.name - remove user name and password
3418 /* At this point, we're hoping all the other special cases have
3419 * been taken care of, so conn->host.name is at most
3420 * [user[:password]]@]hostname
3422 * We need somewhere to put the embedded details, so do that first.
3425 user
[0] =0; /* to make everything well-defined */
3428 if (conn
->protocol
& (PROT_FTP
|PROT_HTTP
|PROT_SCP
|PROT_SFTP
)) {
3429 /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
3430 * possible user+password pair in a string like:
3431 * ftp://user:password@ftp.my.site:8021/README */
3432 char *ptr
=strchr(conn
->host
.name
, '@');
3433 char *userpass
= conn
->host
.name
;
3435 /* there's a user+password given here, to the left of the @ */
3437 conn
->host
.name
= ++ptr
;
3439 /* So the hostname is sane. Only bother interpreting the
3440 * results if we could care. It could still be wasted
3441 * work because it might be overtaken by the programmatically
3442 * set user/passwd, but doing that first adds more cases here :-(
3445 if (data
->set
.use_netrc
!= CURL_NETRC_REQUIRED
) {
3446 /* We could use the one in the URL */
3448 conn
->bits
.user_passwd
= 1; /* enable user+password */
3450 if(*userpass
!= ':') {
3451 /* the name is given, get user+password */
3452 sscanf(userpass
, "%" MAX_CURL_USER_LENGTH_TXT
"[^:@]:"
3453 "%" MAX_CURL_PASSWORD_LENGTH_TXT
"[^@]",
3457 /* no name given, get the password only */
3458 sscanf(userpass
, ":%" MAX_CURL_PASSWORD_LENGTH_TXT
"[^@]", passwd
);
3461 char *newname
=curl_easy_unescape(data
, user
, 0, NULL
);
3463 return CURLE_OUT_OF_MEMORY
;
3464 if(strlen(newname
) < sizeof(user
))
3465 strcpy(user
, newname
);
3467 /* if the new name is longer than accepted, then just use
3468 the unconverted name, it'll be wrong but what the heck */
3472 /* we have a password found in the URL, decode it! */
3473 char *newpasswd
=curl_easy_unescape(data
, passwd
, 0, NULL
);
3475 return CURLE_OUT_OF_MEMORY
;
3476 if(strlen(newpasswd
) < sizeof(passwd
))
3477 strcpy(passwd
, newpasswd
);
3485 /*************************************************************
3486 * Figure out the remote port number
3488 * No matter if we use a proxy or not, we have to figure out the remote
3489 * port number of various reasons.
3491 * To be able to detect port number flawlessly, we must not confuse them
3492 * IPv6-specified addresses in the [0::1] style. (RFC2732)
3494 * The conn->host.name is currently [user:passwd@]host[:port] where host
3495 * could be a hostname, IPv4 address or IPv6 address.
3496 *************************************************************/
3497 if((1 == sscanf(conn
->host
.name
, "[%*39[0-9a-fA-F:.]%c", &endbracket
)) &&
3498 (']' == endbracket
)) {
3499 /* this is a RFC2732-style specified IP-address */
3500 conn
->bits
.ipv6_ip
= TRUE
;
3502 conn
->host
.name
++; /* pass the starting bracket */
3503 tmp
= strchr(conn
->host
.name
, ']');
3504 *tmp
= 0; /* zero terminate */
3505 tmp
++; /* pass the ending bracket */
3507 tmp
= NULL
; /* no port number available */
3510 tmp
= strrchr(conn
->host
.name
, ':');
3512 if(data
->set
.use_port
&& data
->state
.allow_port
) {
3513 /* if set, we use this and ignore the port possibly given in the URL */
3514 conn
->remote_port
= (unsigned short)data
->set
.use_port
;
3516 *tmp
= '\0'; /* cut off the name there anyway - if there was a port
3517 number - since the port number is to be ignored! */
3518 if(conn
->bits
.httpproxy
) {
3519 /* we need to create new URL with the new port number */
3522 url
= aprintf("http://%s:%d%s", conn
->host
.name
, conn
->remote_port
,
3523 data
->reqdata
.path
);
3525 return CURLE_OUT_OF_MEMORY
;
3527 if(data
->change
.url_alloc
)
3528 free(data
->change
.url
);
3530 data
->change
.url
= url
;
3531 data
->change
.url_alloc
= TRUE
;
3535 /* no CURLOPT_PORT given, extract the one from the URL */
3540 port
=strtoul(tmp
+1, &rest
, 10); /* Port number must be decimal */
3542 if (rest
!= (tmp
+1) && *rest
== '\0') {
3543 /* The colon really did have only digits after it,
3544 * so it is either a port number or a mistake */
3546 if (port
> 0xffff) { /* Single unix standard says port numbers are
3548 failf(data
, "Port number too large: %lu", port
);
3549 return CURLE_URL_MALFORMAT
;
3552 *tmp
= '\0'; /* cut off the name there */
3553 conn
->remote_port
= (unsigned short)port
;
3557 /* Programmatically set password:
3558 * - always applies, if available
3559 * - takes precedence over the values we just set above
3560 * so scribble it over the top.
3561 * User-supplied passwords are assumed not to need unescaping.
3563 * user_password is set in "inherit initial knowledge' above,
3564 * so it doesn't have to be set in this block
3566 if (data
->set
.userpwd
!= NULL
) {
3567 /* the name is given, get user+password */
3568 sscanf(data
->set
.userpwd
,
3569 "%" MAX_CURL_USER_LENGTH_TXT
"[^:]:"
3570 "%" MAX_CURL_PASSWORD_LENGTH_TXT
"[^\n]",
3574 conn
->bits
.netrc
= FALSE
;
3575 if (data
->set
.use_netrc
!= CURL_NETRC_IGNORED
) {
3576 if(Curl_parsenetrc(conn
->host
.name
,
3578 data
->set
.netrc_file
)) {
3579 infof(data
, "Couldn't find host %s in the " DOT_CHAR
3580 "netrc file, using defaults\n",
3584 /* set bits.netrc TRUE to remember that we got the name from a .netrc
3585 file, so that it is safe to use even if we followed a Location: to a
3586 different host or similar. */
3587 conn
->bits
.netrc
= TRUE
;
3589 conn
->bits
.user_passwd
= 1; /* enable user+password */
3593 /* If our protocol needs a password and we have none, use the defaults */
3594 if ( (conn
->protocol
& PROT_FTP
) &&
3595 !conn
->bits
.user_passwd
) {
3597 conn
->user
= strdup(CURL_DEFAULT_USER
);
3598 conn
->passwd
= strdup(CURL_DEFAULT_PASSWORD
);
3599 /* This is the default password, so DON'T set conn->bits.user_passwd */
3602 /* store user + password, zero-length if not set */
3603 conn
->user
= strdup(user
);
3604 conn
->passwd
= strdup(passwd
);
3606 if(!conn
->user
|| !conn
->passwd
)
3607 return CURLE_OUT_OF_MEMORY
;
3609 /*************************************************************
3610 * Check the current list of connections to see if we can
3611 * re-use an already existing one or if we have to create a
3613 *************************************************************/
3615 /* get a cloned copy of the SSL config situation stored in the
3616 connection struct */
3617 if(!Curl_clone_ssl_config(&data
->set
.ssl
, &conn
->ssl_config
))
3618 return CURLE_OUT_OF_MEMORY
;
3620 /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3621 we only acknowledge this option if this is not a re-used connection
3622 already (which happens due to follow-location or during a HTTP
3623 authentication phase). */
3624 if(data
->set
.reuse_fresh
&& !data
->state
.this_is_a_follow
)
3627 reuse
= ConnectionExists(data
, conn
, &conn_temp
);
3631 * We already have a connection for this, we got the former connection
3632 * in the conn_temp variable and thus we need to cleanup the one we
3633 * just allocated before we can move along and use the previously
3636 struct connectdata
*old_conn
= conn
;
3638 if(old_conn
->proxy
.rawalloc
)
3639 free(old_conn
->proxy
.rawalloc
);
3641 /* free the SSL config struct from this connection struct as this was
3642 allocated in vain and is targeted for destruction */
3643 Curl_free_ssl_config(&conn
->ssl_config
);
3645 conn
= conn_temp
; /* use this connection from now on */
3647 conn
->data
= old_conn
->data
;
3649 /* get the user+password information from the old_conn struct since it may
3650 * be new for this request even when we re-use an existing connection */
3651 conn
->bits
.user_passwd
= old_conn
->bits
.user_passwd
;
3652 if (conn
->bits
.user_passwd
) {
3653 /* use the new user namd and password though */
3654 Curl_safefree(conn
->user
);
3655 Curl_safefree(conn
->passwd
);
3656 conn
->user
= old_conn
->user
;
3657 conn
->passwd
= old_conn
->passwd
;
3658 old_conn
->user
= NULL
;
3659 old_conn
->passwd
= NULL
;
3662 conn
->bits
.proxy_user_passwd
= old_conn
->bits
.proxy_user_passwd
;
3663 if (conn
->bits
.proxy_user_passwd
) {
3664 /* use the new proxy user name and proxy password though */
3665 Curl_safefree(conn
->proxyuser
);
3666 Curl_safefree(conn
->proxypasswd
);
3667 conn
->proxyuser
= old_conn
->proxyuser
;
3668 conn
->proxypasswd
= old_conn
->proxypasswd
;
3669 old_conn
->proxyuser
= NULL
;
3670 old_conn
->proxypasswd
= NULL
;
3673 /* host can change, when doing keepalive with a proxy ! */
3674 if (conn
->bits
.httpproxy
) {
3675 free(conn
->host
.rawalloc
);
3676 conn
->host
=old_conn
->host
;
3679 /* get the newly set value, not the old one */
3680 conn
->bits
.no_body
= old_conn
->bits
.no_body
;
3682 if (!conn
->bits
.httpproxy
)
3683 free(old_conn
->host
.rawalloc
); /* free the newly allocated name buffer */
3686 conn
->bits
.reuse
= TRUE
; /* yes, we're re-using here */
3687 conn
->bits
.chunk
= FALSE
; /* always assume not chunked unless told
3690 Curl_safefree(old_conn
->user
);
3691 Curl_safefree(old_conn
->passwd
);
3692 Curl_safefree(old_conn
->proxyuser
);
3693 Curl_safefree(old_conn
->proxypasswd
);
3694 Curl_llist_destroy(old_conn
->send_pipe
, NULL
);
3695 Curl_llist_destroy(old_conn
->recv_pipe
, NULL
);
3697 free(old_conn
); /* we don't need this anymore */
3700 * If we're doing a resumed transfer, we need to setup our stuff
3703 data
->reqdata
.resume_from
= data
->set
.set_resume_from
;
3704 if (data
->reqdata
.resume_from
) {
3705 if (data
->reqdata
.rangestringalloc
== TRUE
)
3706 free(data
->reqdata
.range
);
3707 data
->reqdata
.range
= aprintf("%" FORMAT_OFF_T
"-",
3708 data
->reqdata
.resume_from
);
3709 if(!data
->reqdata
.range
)
3710 return CURLE_OUT_OF_MEMORY
;
3712 /* tell ourselves to fetch this range */
3713 data
->reqdata
.use_range
= TRUE
; /* enable range download */
3714 data
->reqdata
.rangestringalloc
= TRUE
; /* mark range string allocated */
3716 else if (data
->set
.set_range
) {
3717 /* There is a range, but is not a resume, useful for random ftp access */
3718 data
->reqdata
.range
= strdup(data
->set
.set_range
);
3719 if(!data
->reqdata
.range
)
3720 return CURLE_OUT_OF_MEMORY
;
3721 data
->reqdata
.rangestringalloc
= TRUE
; /* mark range string allocated */
3722 data
->reqdata
.use_range
= TRUE
; /* enable range download */
3725 data
->reqdata
.use_range
= FALSE
; /* disable range download */
3727 *in_connect
= conn
; /* return this instead! */
3729 infof(data
, "Re-using existing connection! (#%ld) with host %s\n",
3731 conn
->bits
.httpproxy
?conn
->proxy
.dispname
:conn
->host
.dispname
);
3735 * This is a brand new connection, so let's store it in the connection
3738 ConnectionStore(data
, conn
);
3741 /* Continue connectdata initialization here. */
3745 * Inherit the proper values from the urldata struct AFTER we have arranged
3746 * the persistent connection stuff */
3747 conn
->fread
= data
->set
.fread
;
3748 conn
->fread_in
= data
->set
.in
;
3750 if ((conn
->protocol
&PROT_HTTP
) &&
3752 (data
->set
.infilesize
== -1) &&
3753 (data
->set
.httpversion
!= CURL_HTTP_VERSION_1_0
)) {
3754 /* HTTP, upload, unknown file size and not HTTP 1.0 */
3755 conn
->bits
.upload_chunky
= TRUE
;
3758 /* else, no chunky upload */
3759 conn
->bits
.upload_chunky
= FALSE
;
3763 /*************************************************************
3764 * Set timeout if that is being used, and we're not using an asynchronous
3766 *************************************************************/
3767 if((data
->set
.timeout
|| data
->set
.connecttimeout
) && !data
->set
.no_signal
) {
3768 /*************************************************************
3769 * Set signal handler to catch SIGALRM
3770 * Store the old value to be able to set it back later!
3771 *************************************************************/
3777 #ifdef HAVE_SIGACTION
3778 struct sigaction sigact
;
3779 sigaction(SIGALRM
, NULL
, &sigact
);
3780 keep_sigact
= sigact
;
3781 keep_copysig
= TRUE
; /* yes, we have a copy */
3782 sigact
.sa_handler
= alarmfunc
;
3784 /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3785 sigact
.sa_flags
&= ~SA_RESTART
;
3787 /* now set the new struct */
3788 sigaction(SIGALRM
, &sigact
, NULL
);
3789 #else /* HAVE_SIGACTION */
3790 /* no sigaction(), revert to the much lamer signal() */
3792 keep_sigact
= signal(SIGALRM
, alarmfunc
);
3794 #endif /* HAVE_SIGACTION */
3796 /* We set the timeout on the name resolving phase first, separately from
3797 * the download/upload part to allow a maximum time on everything. This is
3798 * a signal-based timeout, why it won't work and shouldn't be used in
3799 * multi-threaded environments. */
3802 shortest
= data
->set
.timeout
; /* default to this timeout value */
3803 if(shortest
&& data
->set
.connecttimeout
&&
3804 (data
->set
.connecttimeout
< shortest
))
3805 /* if both are set, pick the shortest */
3806 shortest
= data
->set
.connecttimeout
;
3808 /* if timeout is not set, use the connect timeout */
3809 shortest
= data
->set
.connecttimeout
;
3811 /* alarm() makes a signal get sent when the timeout fires off, and that
3812 will abort system calls */
3813 prev_alarm
= alarm((unsigned int) shortest
);
3814 /* We can expect the conn->created time to be "now", as that was just
3815 recently set in the beginning of this function and nothing slow
3816 has been done since then until now. */
3818 #endif /* SIGALRM */
3820 #endif /* USE_ARES */
3822 /*************************************************************
3823 * Resolve the name of the server or proxy
3824 *************************************************************/
3825 if(conn
->bits
.reuse
) {
3826 /* re-used connection, no resolving is necessary */
3828 /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
3830 if (conn
->bits
.httpproxy
)
3831 fix_hostname(data
, conn
, &conn
->host
);
3834 /* this is a fresh connect */
3836 /* set a pointer to the hostname we display */
3837 fix_hostname(data
, conn
, &conn
->host
);
3839 if(!conn
->proxy
.name
|| !*conn
->proxy
.name
) {
3840 /* If not connecting via a proxy, extract the port from the URL, if it is
3841 * there, thus overriding any defaults that might have been set above. */
3842 conn
->port
= conn
->remote_port
; /* it is the same port */
3844 /* Resolve target host right on */
3845 rc
= Curl_resolv(conn
, conn
->host
.name
, (int)conn
->port
, &hostaddr
);
3846 if(rc
== CURLRESOLV_PENDING
)
3849 else if(!hostaddr
) {
3850 failf(data
, "Couldn't resolve host '%s'", conn
->host
.dispname
);
3851 result
= CURLE_COULDNT_RESOLVE_HOST
;
3852 /* don't return yet, we need to clean up the timeout first */
3856 /* This is a proxy that hasn't been resolved yet. */
3858 /* IDN-fix the proxy name */
3859 fix_hostname(data
, conn
, &conn
->proxy
);
3862 rc
= Curl_resolv(conn
, conn
->proxy
.name
, (int)conn
->port
, &hostaddr
);
3864 if(rc
== CURLRESOLV_PENDING
)
3867 else if(!hostaddr
) {
3868 failf(data
, "Couldn't resolve proxy '%s'", conn
->proxy
.dispname
);
3869 result
= CURLE_COULDNT_RESOLVE_PROXY
;
3870 /* don't return yet, we need to clean up the timeout first */
3876 #if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
3877 if((data
->set
.timeout
|| data
->set
.connecttimeout
) && !data
->set
.no_signal
) {
3878 #ifdef HAVE_SIGACTION
3880 /* we got a struct as it looked before, now put that one back nice
3882 sigaction(SIGALRM
, &keep_sigact
, NULL
); /* put it back */
3886 /* restore the previous SIGALRM handler */
3887 signal(SIGALRM
, keep_sigact
);
3889 #endif /* HAVE_SIGACTION */
3891 /* switch back the alarm() to either zero or to what it was before minus
3892 the time we spent until now! */
3894 /* there was an alarm() set before us, now put it back */
3895 unsigned long elapsed_ms
= Curl_tvdiff(Curl_tvnow(), conn
->created
);
3896 unsigned long alarm_set
;
3898 /* the alarm period is counted in even number of seconds */
3899 alarm_set
= prev_alarm
- elapsed_ms
/1000;
3902 ((alarm_set
>= 0x80000000) && (prev_alarm
< 0x80000000)) ) {
3903 /* if the alarm time-left reached zero or turned "negative" (counted
3904 with unsigned values), we should fire off a SIGALRM here, but we
3905 won't, and zero would be to switch it off so we never set it to
3908 result
= CURLE_OPERATION_TIMEOUTED
;
3909 failf(data
, "Previous alarm fired off!");
3912 alarm((unsigned int)alarm_set
);
3915 alarm(0); /* just shut it off */
3922 /* SetupConnection() is called after the name resolve initiated in
3923 * CreateConnection() is all done.
3925 * NOTE: the argument 'hostaddr' is NULL when this function is called for a
3926 * re-used connection.
3928 * conn->data MUST already have been setup fine (in CreateConnection)
3931 static CURLcode
SetupConnection(struct connectdata
*conn
,
3932 struct Curl_dns_entry
*hostaddr
,
3933 bool *protocol_done
)
3935 CURLcode result
=CURLE_OK
;
3936 struct SessionHandle
*data
= conn
->data
;
3938 Curl_pgrsTime(data
, TIMER_NAMELOOKUP
);
3940 if(conn
->protocol
& PROT_FILE
) {
3941 /* There's nothing in this function to setup if we're only doing
3942 a file:// transfer */
3943 *protocol_done
= TRUE
;
3946 *protocol_done
= FALSE
; /* default to not done */
3948 /*************************************************************
3949 * Send user-agent to HTTP proxies even if the target protocol
3951 *************************************************************/
3952 if((conn
->protocol
&PROT_HTTP
) || conn
->bits
.httpproxy
) {
3953 if(data
->set
.useragent
) {
3954 Curl_safefree(conn
->allocptr
.uagent
);
3955 conn
->allocptr
.uagent
=
3956 aprintf("User-Agent: %s\r\n", data
->set
.useragent
);
3957 if(!conn
->allocptr
.uagent
)
3958 return CURLE_OUT_OF_MEMORY
;
3962 conn
->headerbytecount
= 0;
3964 #ifdef CURL_DO_LINEEND_CONV
3965 data
->state
.crlf_conversions
= 0; /* reset CRLF conversion counter */
3966 #endif /* CURL_DO_LINEEND_CONV */
3969 /* loop for CURL_SERVER_CLOSED_CONNECTION */
3971 if(CURL_SOCKET_BAD
== conn
->sock
[FIRSTSOCKET
]) {
3972 bool connected
= FALSE
;
3974 /* Connect only if not already connected! */
3975 result
= ConnectPlease(data
, conn
, hostaddr
, &connected
);
3978 result
= Curl_protocol_connect(conn
, protocol_done
);
3979 if(CURLE_OK
== result
)
3980 conn
->bits
.tcpconnect
= TRUE
;
3983 conn
->bits
.tcpconnect
= FALSE
;
3985 /* if the connection was closed by the server while exchanging
3986 authentication informations, retry with the new set
3987 authentication information */
3988 if(conn
->bits
.proxy_connect_closed
) {
3989 /* reset the error buffer */
3990 if (data
->set
.errorbuffer
)
3991 data
->set
.errorbuffer
[0] = '\0';
3992 data
->state
.errorbuf
= FALSE
;
3996 if(CURLE_OK
!= result
)
4000 Curl_pgrsTime(data
, TIMER_CONNECT
); /* we're connected already */
4001 conn
->bits
.tcpconnect
= TRUE
;
4002 *protocol_done
= TRUE
;
4003 if(data
->set
.verbose
)
4004 verboseconnect(conn
);
4006 /* Stop the loop now */
4010 conn
->now
= Curl_tvnow(); /* time this *after* the connect is done, we
4011 set this here perhaps a second time */
4015 * the check is quite a hack...
4016 * we're calling _fsetmode to fix the problem with fwrite converting newline
4017 * characters (you get mangled text files, and corrupted binary files when
4018 * you download to stdout and redirect it to a file). */
4020 if ((data
->set
.out
)->_handle
== NULL
) {
4021 _fsetmode(stdout
, "b");
4028 CURLcode
Curl_connect(struct SessionHandle
*data
,
4029 struct connectdata
**in_connect
,
4031 bool *protocol_done
)
4034 struct Curl_dns_entry
*dns
;
4036 *asyncp
= FALSE
; /* assume synchronous resolves by default */
4038 /* call the stuff that needs to be called */
4039 code
= CreateConnection(data
, in_connect
, &dns
, asyncp
);
4041 if(CURLE_OK
== code
) {
4044 /* If an address is available it means that we already have the name
4045 resolved, OR it isn't async. if this is a re-used connection 'dns'
4046 will be NULL here. Continue connecting from here */
4047 code
= SetupConnection(*in_connect
, dns
, protocol_done
);
4049 response will be received and treated async wise */
4052 if(CURLE_OK
!= code
) {
4053 /* We're not allowed to return failure with memory left allocated
4054 in the connectdata struct, free those here */
4056 Curl_disconnect(*in_connect
); /* close the connection */
4057 *in_connect
= NULL
; /* return a NULL */
4061 if ((*in_connect
)->is_in_pipeline
)
4062 data
->state
.is_in_pipeline
= TRUE
;
4068 /* Call this function after Curl_connect() has returned async=TRUE and
4069 then a successful name resolve has been received.
4071 Note: this function disconnects and frees the conn data in case of
4073 CURLcode
Curl_async_resolved(struct connectdata
*conn
,
4074 bool *protocol_done
)
4076 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
4077 defined(USE_THREADING_GETADDRINFO)
4078 CURLcode code
= SetupConnection(conn
, conn
->async
.dns
, protocol_done
);
4081 /* We're not allowed to return failure with memory left allocated
4082 in the connectdata struct, free those here */
4083 Curl_disconnect(conn
); /* close the connection */
4088 (void)protocol_done
;
4094 CURLcode
Curl_done(struct connectdata
**connp
,
4095 CURLcode status
, bool premature
) /* an error if this is called after an
4096 error was detected */
4099 struct connectdata
*conn
= *connp
;
4100 struct SessionHandle
*data
= conn
->data
;
4102 Curl_expire(data
, 0); /* stop timer */
4105 return CURLE_OK
; /* Curl_done() has already been called */
4107 conn
->bits
.done
= TRUE
; /* called just now! */
4109 if(Curl_removeHandleFromPipeline(data
, conn
->recv_pipe
) &&
4110 conn
->readchannel_inuse
)
4111 conn
->readchannel_inuse
= FALSE
;
4112 if(Curl_removeHandleFromPipeline(data
, conn
->send_pipe
) &&
4113 conn
->writechannel_inuse
)
4114 conn
->writechannel_inuse
= FALSE
;
4116 /* cleanups done even if the connection is re-used */
4117 if(data
->reqdata
.rangestringalloc
) {
4118 free(data
->reqdata
.range
);
4119 data
->reqdata
.rangestringalloc
= FALSE
;
4122 /* Cleanup possible redirect junk */
4123 if(data
->reqdata
.newurl
) {
4124 free(data
->reqdata
.newurl
);
4125 data
->reqdata
.newurl
= NULL
;
4128 if(conn
->dns_entry
) {
4129 Curl_resolv_unlock(data
, conn
->dns_entry
); /* done with this */
4130 conn
->dns_entry
= NULL
;
4133 /* this calls the protocol-specific function pointer previously set */
4135 result
= conn
->curl_done(conn
, status
, premature
);
4139 Curl_pgrsDone(conn
); /* done with the operation */
4141 /* for ares-using, make sure all possible outstanding requests are properly
4142 cancelled before we proceed */
4143 ares_cancel(data
->state
.areschannel
);
4145 /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
4146 forced us to close this no matter what we think.
4148 if conn->bits.close is TRUE, it means that the connection should be
4149 closed in spite of all our efforts to be nice, due to protocol
4150 restrictions in our or the server's end */
4151 if(data
->set
.reuse_forbid
|| conn
->bits
.close
) {
4152 CURLcode res2
= Curl_disconnect(conn
); /* close the connection */
4154 *connp
= NULL
; /* to make the caller of this function better detect that
4155 this was actually killed here */
4157 /* If we had an error already, make sure we return that one. But
4158 if we got a new error, return that. */
4163 ConnectionDone(conn
); /* the connection is no longer in use */
4165 /* remember the most recently used connection */
4166 data
->state
.lastconnect
= conn
->connectindex
;
4168 infof(data
, "Connection #%ld to host %s left intact\n",
4170 conn
->bits
.httpproxy
?conn
->proxy
.dispname
:conn
->host
.dispname
);
4176 CURLcode
Curl_do(struct connectdata
**connp
, bool *done
)
4178 CURLcode result
=CURLE_OK
;
4179 struct connectdata
*conn
= *connp
;
4180 struct SessionHandle
*data
= conn
->data
;
4182 conn
->bits
.done
= FALSE
; /* Curl_done() is not called yet */
4183 conn
->bits
.do_more
= FALSE
; /* by default there's no curl_do_more() to use */
4186 /* generic protocol-specific function pointer set in curl_connect() */
4187 result
= conn
->curl_do(conn
, done
);
4189 /* This was formerly done in transfer.c, but we better do it here */
4191 if((CURLE_SEND_ERROR
== result
) && conn
->bits
.reuse
) {
4192 /* This was a re-use of a connection and we got a write error in the
4193 * DO-phase. Then we DISCONNECT this connection and have another attempt
4194 * to CONNECT and then DO again! The retry cannot possibly find another
4195 * connection to re-use, since we only keep one possible connection for
4198 infof(data
, "Re-used connection seems dead, get a new one\n");
4200 conn
->bits
.close
= TRUE
; /* enforce close of this connection */
4201 result
= Curl_done(&conn
, result
, FALSE
); /* we are so done with this */
4203 /* conn may no longer be a good pointer */
4206 * According to bug report #1330310. We need to check for
4207 * CURLE_SEND_ERROR here as well. I figure this could happen when the
4208 * request failed on a FTP connection and thus Curl_done() itself tried
4209 * to use the connection (again). Slight Lack of feedback in the report,
4210 * but I don't think this extra check can do much harm.
4212 if((CURLE_OK
== result
) || (CURLE_SEND_ERROR
== result
)) {
4214 bool protocol_done
= TRUE
;
4216 /* Now, redo the connect and get a new connection */
4217 result
= Curl_connect(data
, connp
, &async
, &protocol_done
);
4218 if(CURLE_OK
== result
) {
4219 /* We have connected or sent away a name resolve query fine */
4221 conn
= *connp
; /* setup conn to again point to something nice */
4223 /* Now, if async is TRUE here, we need to wait for the name
4225 result
= Curl_wait_for_resolv(conn
, NULL
);
4229 /* Resolved, continue with the connection */
4230 result
= Curl_async_resolved(conn
, &protocol_done
);
4235 /* ... finally back to actually retry the DO phase */
4236 result
= conn
->curl_do(conn
, done
);
4244 CURLcode
Curl_do_more(struct connectdata
*conn
)
4246 CURLcode result
=CURLE_OK
;
4248 if(conn
->curl_do_more
)
4249 result
= conn
->curl_do_more(conn
);