~ubuntu-branches/ubuntu/natty/curl/natty-proposed

« back to all changes in this revision

Viewing changes to lib/url.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Schuldei
  • Date: 2009-05-24 21:12:19 UTC
  • mfrom: (1.1.12 upstream)
  • mto: (3.3.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20090524211219-7jgcwuhl04ixuqsm
Tags: upstream-7.19.5
ImportĀ upstreamĀ versionĀ 7.19.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: url.c,v 1.711 2008-04-30 21:20:09 bagder Exp $
 
21
 * $Id: url.c,v 1.798 2009-05-17 14:47:50 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
/* -- WIN32 approved -- */
60
60
#ifdef HAVE_SYS_IOCTL_H
61
61
#include <sys/ioctl.h>
62
62
#endif
63
 
#ifdef HAVE_SIGNAL_H
64
 
#include <signal.h>
65
 
#endif
66
63
 
67
64
#ifdef HAVE_SYS_PARAM_H
68
65
#include <sys/param.h>
73
70
#include <inet.h>
74
71
#endif
75
72
 
76
 
#ifdef HAVE_SETJMP_H
77
 
#include <setjmp.h>
78
 
#endif
79
 
 
80
73
#ifndef HAVE_SOCKET
81
74
#error "We can't compile without socket() support!"
82
75
#endif
122
115
#include "multiif.h"
123
116
#include "easyif.h"
124
117
#include "speedcheck.h"
 
118
#include "rawstr.h"
125
119
 
126
120
/* And now for the protocols */
127
121
#include "ftp.h"
138
132
#include "http_ntlm.h"
139
133
#include "socks.h"
140
134
 
141
 
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
142
 
#include "inet_ntoa_r.h"
143
 
#endif
144
 
 
145
135
#define _MPRINTF_REPLACE /* use our functions only */
146
136
#include <curl/mprintf.h>
147
137
 
148
 
#include "memory.h"
149
 
 
 
138
#include "curl_memory.h"
150
139
/* The last #include file should be: */
151
140
#include "memdebug.h"
152
141
 
153
 
#ifdef __SYMBIAN32__
154
 
#undef SIGALRM
155
 
#endif
156
 
 
157
142
/* Local static prototypes */
158
143
static long ConnectionKillOne(struct SessionHandle *data);
159
 
static bool ConnectionExists(struct SessionHandle *data,
160
 
                             struct connectdata *needle,
161
 
                             struct connectdata **usethis);
162
 
static long ConnectionStore(struct SessionHandle *data,
163
 
                            struct connectdata *conn);
164
 
static bool IsPipeliningPossible(const struct SessionHandle *handle);
165
144
static void conn_free(struct connectdata *conn);
166
 
 
167
145
static void signalPipeClose(struct curl_llist *pipeline);
168
146
 
169
 
static struct SessionHandle* gethandleathead(struct curl_llist *pipeline);
170
 
static CURLcode do_init(struct connectdata *conn);
171
 
static void do_complete(struct connectdata *conn);
172
 
 
173
 
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
174
 
static void flush_cookies(struct SessionHandle *data, int cleanup);
175
 
#endif
176
 
 
177
147
#ifdef CURL_DISABLE_VERBOSE_STRINGS
178
148
#define verboseconnect(x)  do { } while (0)
179
149
#endif
180
150
 
181
 
#ifndef USE_ARES
182
 
/* not for ares builds */
183
 
 
184
 
#ifndef WIN32
185
 
/* not for WIN32 builds */
186
 
 
187
 
#ifdef HAVE_SIGSETJMP
188
 
extern sigjmp_buf curl_jmpenv;
189
 
#endif
190
 
 
191
 
#ifdef SIGALRM
192
 
static
193
 
RETSIGTYPE alarmfunc(int sig)
194
 
{
195
 
  /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
196
 
  (void)sig;
197
 
#ifdef HAVE_SIGSETJMP
198
 
  siglongjmp(curl_jmpenv, 1);
199
 
#endif
200
 
  return;
201
 
}
202
 
#endif /* SIGALRM */
203
 
#endif /* WIN32 */
204
 
#endif /* USE_ARES */
205
151
 
206
152
/*
207
153
 * Protocol table.
272
218
  ZERO_NULL,                            /* doing */
273
219
  ZERO_NULL,                            /* proto_getsock */
274
220
  ZERO_NULL,                            /* doing_getsock */
 
221
  ZERO_NULL,                            /* perform_getsock */
275
222
  ZERO_NULL,                            /* disconnect */
276
223
  0,                                    /* defport */
277
224
  0                                     /* protocol */
286
233
static void close_connections(struct SessionHandle *data)
287
234
{
288
235
  /* Loop through all open connections and kill them one by one */
289
 
  while(-1 != ConnectionKillOne(data))
290
 
    ; /* empty loop */
 
236
  long i;
 
237
  do {
 
238
    i = ConnectionKillOne(data);
 
239
  } while(i != -1L);
291
240
}
292
241
 
293
242
void Curl_freeset(struct SessionHandle * data)
320
269
  return CURLE_OK;
321
270
}
322
271
 
 
272
static CURLcode setstropt_userpwd(char *option, char **user_storage,
 
273
                                  char **pwd_storage)
 
274
{
 
275
  char* separator;
 
276
  CURLcode result = CURLE_OK;
 
277
 
 
278
  if(!option)
 
279
    return result;
 
280
 
 
281
  separator = strchr(option, ':');
 
282
  if (separator != NULL) {
 
283
 
 
284
    /* store username part of option */
 
285
    char * p;
 
286
    size_t username_len = (size_t)(separator-option);
 
287
    p = malloc(username_len+1);
 
288
    if(!p)
 
289
      result = CURLE_OUT_OF_MEMORY;
 
290
    else {
 
291
      memcpy(p, option, username_len);
 
292
      p[username_len] = '\0';
 
293
      Curl_safefree(*user_storage);
 
294
      *user_storage = p;
 
295
    }
 
296
 
 
297
    /* store password part of option */
 
298
    if (result == CURLE_OK) {
 
299
      result = setstropt(pwd_storage, separator+1);
 
300
    }
 
301
  }
 
302
  else {
 
303
    result = setstropt(user_storage, option);
 
304
  }
 
305
  return result;
 
306
}
 
307
 
323
308
CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src)
324
309
{
325
310
  CURLcode r = CURLE_OK;
346
331
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
347
332
static void flush_cookies(struct SessionHandle *data, int cleanup)
348
333
{
349
 
  Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
350
334
  if(data->set.str[STRING_COOKIEJAR]) {
351
335
    if(data->change.cookielist) {
352
336
      /* If there is a list of cookie files to read, do it first so that
353
 
         we have all the told files read before we write the new jar */
 
337
         we have all the told files read before we write the new jar.
 
338
         Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
354
339
      Curl_cookie_loadfiles(data);
355
340
    }
356
341
 
 
342
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
 
343
 
357
344
    /* if we have a destination file for all the cookies to get dumped to */
358
345
    if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
359
346
      infof(data, "WARNING: failed to save cookies in %s\n",
364
351
      /* since nothing is written, we can just free the list of cookie file
365
352
         names */
366
353
      curl_slist_free_all(data->change.cookielist); /* clean up list */
 
354
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
367
355
  }
368
356
 
369
357
  if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
408
396
          if(data == (struct SessionHandle *) curr->ptr) {
409
397
            fprintf(stderr,
410
398
                    "MAJOR problem we %p are still in send pipe for %p done %d\n",
411
 
                    data, connptr, connptr->bits.done);
 
399
                    data, connptr, (int)connptr->bits.done);
412
400
          }
413
401
        }
414
402
      }
418
406
          if(data == (struct SessionHandle *) curr->ptr) {
419
407
            fprintf(stderr,
420
408
                    "MAJOR problem we %p are still in recv pipe for %p done %d\n",
421
 
                    data, connptr, connptr->bits.done);
 
409
                    data, connptr, (int)connptr->bits.done);
422
410
          }
423
411
        }
424
412
      }
428
416
          if(data == (struct SessionHandle *) curr->ptr) {
429
417
            fprintf(stderr,
430
418
                    "MAJOR problem we %p are still in pend pipe for %p done %d\n",
431
 
                    data, connptr, connptr->bits.done);
 
419
                    data, connptr, (int)connptr->bits.done);
432
420
          }
433
421
        }
434
422
      }
464
452
    return CURLE_OK;
465
453
  }
466
454
 
467
 
  if(data->dns.hostcachetype == HCACHE_PRIVATE)
 
455
  if(data->dns.hostcachetype == HCACHE_PRIVATE) {
468
456
    Curl_hash_destroy(data->dns.hostcache);
 
457
    data->dns.hostcachetype = HCACHE_NONE;
 
458
    data->dns.hostcache = NULL;
 
459
  }
469
460
 
470
461
  if(data->state.rangestringalloc)
471
462
    free(data->state.range);
478
469
  Curl_ssl_close_all(data);
479
470
  Curl_safefree(data->state.first_host);
480
471
  Curl_safefree(data->state.scratch);
 
472
  Curl_ssl_free_certinfo(data);
481
473
 
482
474
  if(data->change.referer_alloc)
483
475
    free(data->change.referer);
598
590
      data->state.lastconnect = -1;
599
591
  }
600
592
  if(newamount > 0) {
601
 
    newptr= (struct connectdata **)
602
 
      realloc(c->connects, sizeof(struct connectdata *) * newamount);
 
593
    newptr = realloc(c->connects, sizeof(struct connectdata *) * newamount);
603
594
    if(!newptr)
604
595
      /* we closed a few connections in vain, but so what? */
605
596
      return CURLE_OUT_OF_MEMORY;
631
622
  free(c);
632
623
}
633
624
 
 
625
/*
 
626
 * Initialize the UserDefined fields within a SessionHandle.
 
627
 * This may be safely called on a new or existing SessionHandle.
 
628
 */
 
629
CURLcode Curl_init_userdefined(struct UserDefined *set)
 
630
{
 
631
  CURLcode res = CURLE_OK;
 
632
 
 
633
  set->out = stdout; /* default output to stdout */
 
634
  set->in  = stdin;  /* default input from stdin */
 
635
  set->err  = stderr;  /* default stderr to stderr */
 
636
 
 
637
  /* use fwrite as default function to store output */
 
638
  set->fwrite_func = (curl_write_callback)fwrite;
 
639
 
 
640
  /* use fread as default function to read input */
 
641
  set->fread_func = (curl_read_callback)fread;
 
642
 
 
643
  set->seek_func = ZERO_NULL;
 
644
  set->seek_client = ZERO_NULL;
 
645
 
 
646
  /* conversion callbacks for non-ASCII hosts */
 
647
  set->convfromnetwork = ZERO_NULL;
 
648
  set->convtonetwork   = ZERO_NULL;
 
649
  set->convfromutf8    = ZERO_NULL;
 
650
 
 
651
  set->infilesize = -1;      /* we don't know any size */
 
652
  set->postfieldsize = -1;   /* unknown size */
 
653
  set->maxredirs = -1;       /* allow any amount by default */
 
654
 
 
655
  set->httpreq = HTTPREQ_GET; /* Default HTTP request */
 
656
  set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
 
657
  set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
 
658
  set->ftp_filemethod = FTPFILE_MULTICWD;
 
659
 
 
660
  set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
 
661
 
 
662
  /* Set the default size of the SSL session ID cache */
 
663
  set->ssl.numsessions = 5;
 
664
 
 
665
  set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
 
666
  set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
 
667
  set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
 
668
  set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
 
669
 
 
670
  /* make libcurl quiet by default: */
 
671
  set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
 
672
 
 
673
  /*
 
674
   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
 
675
   * switched off unless wanted.
 
676
   */
 
677
  set->ssl.verifypeer = TRUE;
 
678
  set->ssl.verifyhost = 2;
 
679
  set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
 
680
                                                      type */
 
681
  set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
 
682
 
 
683
  set->new_file_perms = 0644;    /* Default permissions */
 
684
  set->new_directory_perms = 0755; /* Default permissions */
 
685
 
 
686
  /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
 
687
     define since we internally only use the lower 16 bits for the passed
 
688
     in bitmask to not conflict with the private bits */
 
689
  set->allowed_protocols = PROT_EXTMASK;
 
690
  set->redir_protocols =
 
691
    PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
 
692
 
 
693
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
694
  /*
 
695
   * disallow unprotected protection negotiation NEC reference implementation
 
696
   * seem not to follow rfc1961 section 4.3/4.4
 
697
   */
 
698
  set->socks5_gssapi_nec = FALSE;
 
699
  /* set default gssapi service name */
 
700
  res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
 
701
                  (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
 
702
  if (res != CURLE_OK)
 
703
    return res;
 
704
#endif
 
705
 
 
706
  /* This is our preferred CA cert bundle/path since install time */
 
707
#if defined(CURL_CA_BUNDLE)
 
708
  res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
 
709
#elif defined(CURL_CA_PATH)
 
710
  res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
 
711
#endif
 
712
 
 
713
  return res;
 
714
}
 
715
 
634
716
/**
635
717
 * Curl_open()
636
718
 *
648
730
#endif
649
731
 
650
732
  /* Very simple start-up: alloc the struct, init it with zeroes and return */
651
 
  data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
 
733
  data = calloc(1, sizeof(struct SessionHandle));
652
734
  if(!data) {
653
735
    /* this is a very serious error */
654
736
    DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
672
754
 
673
755
  /* We do some initial setup here, all those fields that can't be just 0 */
674
756
 
675
 
  data->state.headerbuff=(char*)malloc(HEADERSIZE);
 
757
  data->state.headerbuff = malloc(HEADERSIZE);
676
758
  if(!data->state.headerbuff) {
677
759
    DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
678
760
    res = CURLE_OUT_OF_MEMORY;
679
761
  }
680
762
  else {
 
763
    Curl_easy_initHandleData(data);
 
764
    res = Curl_init_userdefined(&data->set);
 
765
 
681
766
    data->state.headersize=HEADERSIZE;
682
767
 
683
 
    data->set.out = stdout; /* default output to stdout */
684
 
    data->set.in  = stdin;  /* default input from stdin */
685
 
    data->set.err  = stderr;  /* default stderr to stderr */
686
 
 
687
 
    /* use fwrite as default function to store output */
688
 
    data->set.fwrite_func = (curl_write_callback)fwrite;
689
 
 
690
 
    /* use fread as default function to read input */
691
 
    data->set.fread_func = (curl_read_callback)fread;
692
 
 
693
 
    /* don't use a seek function by default */
694
 
    data->set.seek_func = ZERO_NULL;
695
 
    data->set.seek_client = ZERO_NULL;
696
 
 
697
 
    /* conversion callbacks for non-ASCII hosts */
698
 
    data->set.convfromnetwork = ZERO_NULL;
699
 
    data->set.convtonetwork   = ZERO_NULL;
700
 
    data->set.convfromutf8    = ZERO_NULL;
701
 
 
702
768
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
703
769
    /* conversion descriptors for iconv calls */
704
770
    data->outbound_cd = (iconv_t)-1;
706
772
    data->utf8_cd     = (iconv_t)-1;
707
773
#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
708
774
 
709
 
    data->set.infilesize = -1; /* we don't know any size */
710
 
    data->set.postfieldsize = -1;
711
 
    data->set.maxredirs = -1; /* allow any amount by default */
 
775
    /* most recent connection is not yet defined */
 
776
    data->state.lastconnect = -1;
 
777
 
 
778
    data->progress.flags |= PGRS_HIDE;
712
779
    data->state.current_speed = -1; /* init to negative == impossible */
713
780
 
714
 
    data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
715
 
    data->set.ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
716
 
    data->set.ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
717
 
    data->set.ftp_filemethod = FTPFILE_MULTICWD;
718
 
    data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
719
 
 
720
 
    /* make libcurl quiet by default: */
721
 
    data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
722
 
    data->progress.flags |= PGRS_HIDE;
723
 
 
724
 
    /* Set the default size of the SSL session ID cache */
725
 
    data->set.ssl.numsessions = 5;
726
 
 
727
 
    data->set.proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
728
 
    data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
729
 
    data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
730
 
    data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
731
 
 
732
781
    /* This no longer creates a connection cache here. It is instead made on
733
782
       the first call to curl_easy_perform() or when the handle is added to a
734
783
       multi stack. */
735
 
 
736
 
    data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
737
 
                                                        type */
738
 
    data->set.new_file_perms = 0644;    /* Default permissions */
739
 
    data->set.new_directory_perms = 0755; /* Default permissions */
740
 
 
741
 
    /* most recent connection is not yet defined */
742
 
    data->state.lastconnect = -1;
743
 
 
744
 
    Curl_easy_initHandleData(data);
745
 
 
746
 
    /*
747
 
     * libcurl 7.10 introduced SSL verification *by default*! This needs to be
748
 
     * switched off unless wanted.
749
 
     */
750
 
    data->set.ssl.verifypeer = TRUE;
751
 
    data->set.ssl.verifyhost = 2;
752
 
    data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */
753
 
    /* This is our preferred CA cert bundle/path since install time */
754
 
#if defined(CURL_CA_BUNDLE)
755
 
    res = setstropt(&data->set.str[STRING_SSL_CAFILE],
756
 
                         (char *) CURL_CA_BUNDLE);
757
 
#elif defined(CURL_CA_PATH)
758
 
    res = setstropt(&data->set.str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
759
 
#endif
760
784
  }
761
785
 
762
786
  if(res) {
787
811
    data->set.dns_cache_timeout = va_arg(param, long);
788
812
    break;
789
813
  case CURLOPT_DNS_USE_GLOBAL_CACHE:
790
 
    {
791
 
      /* remember we want this enabled */
792
 
      long use_cache = va_arg(param, long);
793
 
      data->set.global_dns_cache = (bool)(0 != use_cache);
794
 
    }
795
 
    break;
 
814
  {
 
815
    /* remember we want this enabled */
 
816
    long use_cache = va_arg(param, long);
 
817
    data->set.global_dns_cache = (bool)(0 != use_cache);
 
818
  }
 
819
  break;
796
820
  case CURLOPT_SSL_CIPHER_LIST:
797
821
    /* set a list of cipher we want to use in the SSL connection */
798
822
    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
799
 
                            va_arg(param, char *));
 
823
                       va_arg(param, char *));
800
824
    break;
801
825
 
802
826
  case CURLOPT_RANDOM_FILE:
805
829
     * the random SSL stuff with. The file is only used for reading.
806
830
     */
807
831
    result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
808
 
                            va_arg(param, char *));
 
832
                       va_arg(param, char *));
809
833
    break;
810
834
  case CURLOPT_EGDSOCKET:
811
835
    /*
812
836
     * The Entropy Gathering Daemon socket pathname
813
837
     */
814
838
    result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
815
 
                            va_arg(param, char *));
 
839
                       va_arg(param, char *));
816
840
    break;
817
841
  case CURLOPT_MAXCONNECTS:
818
842
    /*
863
887
     * Do not include the body part in the output data stream.
864
888
     */
865
889
    data->set.opt_no_body = (bool)(0 != va_arg(param, long));
866
 
 
867
 
    /* in HTTP lingo, no body means using the HEAD request and if unset there
868
 
       really is no perfect method that is the "opposite" of HEAD but in
869
 
       reality most people probably think GET then. The important thing is
870
 
       that we can't let it remain HEAD if the opt_no_body is set FALSE since
871
 
       then we'll behave wrong when getting HTTP. */
872
 
    data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET;
873
890
    break;
874
891
  case CURLOPT_FAILONERROR:
875
892
    /*
885
902
     * using the PUT request.
886
903
     */
887
904
    data->set.upload = (bool)(0 != va_arg(param, long));
888
 
    if(data->set.upload)
 
905
    if(data->set.upload) {
889
906
      /* If this is HTTP, PUT is what's needed to "upload" */
890
907
      data->set.httpreq = HTTPREQ_PUT;
 
908
      data->set.opt_no_body = FALSE; /* this is implied */
 
909
    }
 
910
    else
 
911
      /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
 
912
         then this can be changed to HEAD later on) */
 
913
      data->set.httpreq = HTTPREQ_GET;
891
914
    break;
892
915
  case CURLOPT_FILETIME:
893
916
    /*
901
924
     * An FTP option that modifies an upload to create missing directories on
902
925
     * the server.
903
926
     */
904
 
    data->set.ftp_create_missing_dirs = (bool)(0 != va_arg(param, long));
 
927
    data->set.ftp_create_missing_dirs = (int)va_arg(param, long);
905
928
    break;
906
929
  case CURLOPT_FTP_RESPONSE_TIMEOUT:
907
930
    /*
910
933
     */
911
934
    data->set.ftp_response_timeout = va_arg( param , long ) * 1000;
912
935
    break;
 
936
  case CURLOPT_TFTP_BLKSIZE:
 
937
    /*
 
938
     * TFTP option that specifies the block size to use for data transmission
 
939
     */
 
940
    data->set.tftp_blksize = va_arg(param, long);
 
941
    break;
913
942
  case CURLOPT_DIRLISTONLY:
914
943
    /*
915
944
     * An option that changes the command to one that asks for a list
940
969
     * Use this file instead of the $HOME/.netrc file
941
970
     */
942
971
    result = setstropt(&data->set.str[STRING_NETRC_FILE],
943
 
                            va_arg(param, char *));
 
972
                       va_arg(param, char *));
944
973
    break;
945
974
  case CURLOPT_TRANSFERTEXT:
946
975
    /*
993
1022
     */
994
1023
    argptr = va_arg(param, char *);
995
1024
    result = setstropt(&data->set.str[STRING_ENCODING],
996
 
                            (argptr && !*argptr)?
997
 
                            (char *) ALL_CONTENT_ENCODINGS: argptr);
 
1025
                       (argptr && !*argptr)?
 
1026
                       (char *) ALL_CONTENT_ENCODINGS: argptr);
998
1027
    break;
999
1028
 
1000
1029
  case CURLOPT_FOLLOWLOCATION:
1021
1050
    data->set.maxredirs = va_arg(param, long);
1022
1051
    break;
1023
1052
 
1024
 
  case CURLOPT_POST301:
 
1053
  case CURLOPT_POSTREDIR:
 
1054
  {
1025
1055
    /*
1026
 
     * Obey RFC 2616/10.3.2 and resubmit a POST as a POST after a 301.
 
1056
     * Set the behaviour of POST when redirecting
 
1057
     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
 
1058
     * CURL_REDIR_POST_301 - POST is kept as POST after 301
 
1059
     * CURL_REDIR_POST_302 - POST is kept as POST after 302
 
1060
     * CURL_REDIR_POST_ALL - POST is kept as POST after 301 and 302
 
1061
     * other - POST is kept as POST after 301 and 302
1027
1062
     */
1028
 
    data->set.post301 = (bool)(0 != va_arg(param, long));
1029
 
    break;
 
1063
    long postRedir = va_arg(param, long);
 
1064
    data->set.post301 = (bool)((postRedir & CURL_REDIR_POST_301)?TRUE:FALSE);
 
1065
    data->set.post302 = (bool)((postRedir & CURL_REDIR_POST_302)?TRUE:FALSE);
 
1066
  }
 
1067
  break;
1030
1068
 
1031
1069
  case CURLOPT_POST:
1032
1070
    /* Does this option serve a purpose anymore? Yes it does, when
1056
1094
       */
1057
1095
 
1058
1096
      if((data->set.postfieldsize < 0) ||
1059
 
          ((sizeof(curl_off_t) != sizeof(size_t)) &&
1060
 
           (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
 
1097
         ((sizeof(curl_off_t) != sizeof(size_t)) &&
 
1098
          (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1061
1099
        result = CURLE_OUT_OF_MEMORY;
1062
1100
      else {
1063
1101
        char * p;
1068
1106
           later address compare to detect the COPYPOSTFIELDS mode, and
1069
1107
           to mark that postfields is used rather than read function or
1070
1108
           form data.
1071
 
         */
 
1109
        */
1072
1110
        p = malloc((size_t)(data->set.postfieldsize?data->set.postfieldsize:1));
1073
1111
 
1074
1112
        if(!p)
1104
1142
    bigsize = va_arg(param, long);
1105
1143
 
1106
1144
    if(data->set.postfieldsize < bigsize &&
1107
 
        data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
 
1145
       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1108
1146
      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1109
1147
      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1110
1148
      data->set.postfields = NULL;
1111
 
      }
 
1149
    }
1112
1150
 
1113
1151
    data->set.postfieldsize = bigsize;
1114
1152
    break;
1121
1159
    bigsize = va_arg(param, curl_off_t);
1122
1160
 
1123
1161
    if(data->set.postfieldsize < bigsize &&
1124
 
        data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
 
1162
       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1125
1163
      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1126
1164
      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1127
1165
      data->set.postfields = NULL;
1128
 
      }
 
1166
    }
1129
1167
 
1130
1168
    data->set.postfieldsize = bigsize;
1131
1169
    break;
1148
1186
      data->change.referer_alloc = FALSE;
1149
1187
    }
1150
1188
    result = setstropt(&data->set.str[STRING_SET_REFERER],
1151
 
                            va_arg(param, char *));
 
1189
                       va_arg(param, char *));
1152
1190
    data->change.referer = data->set.str[STRING_SET_REFERER];
1153
1191
    break;
1154
1192
 
1157
1195
     * String to use in the HTTP User-Agent field
1158
1196
     */
1159
1197
    result = setstropt(&data->set.str[STRING_USERAGENT],
1160
 
                            va_arg(param, char *));
 
1198
                       va_arg(param, char *));
1161
1199
    break;
1162
1200
 
1163
1201
  case CURLOPT_HTTPHEADER:
1180
1218
     * Cookie string to send to the remote server in the request.
1181
1219
     */
1182
1220
    result = setstropt(&data->set.str[STRING_COOKIE],
1183
 
                            va_arg(param, char *));
 
1221
                       va_arg(param, char *));
1184
1222
    break;
1185
1223
 
1186
1224
  case CURLOPT_COOKIEFILE:
1206
1244
     * Set cookie file name to dump all cookies to when we're done.
1207
1245
     */
1208
1246
    result = setstropt(&data->set.str[STRING_COOKIEJAR],
1209
 
                            va_arg(param, char *));
 
1247
                       va_arg(param, char *));
1210
1248
 
1211
1249
    /*
1212
1250
     * Activate the cookie parser. This may or may not already
1241
1279
    if(argptr == NULL)
1242
1280
      break;
1243
1281
 
1244
 
    if(strequal(argptr, "ALL")) {
 
1282
    if(Curl_raw_equal(argptr, "ALL")) {
1245
1283
      /* clear all cookies */
1246
1284
      Curl_cookie_clearall(data->cookies);
1247
1285
      break;
1248
1286
    }
1249
 
    else if(strequal(argptr, "SESS")) {
 
1287
    else if(Curl_raw_equal(argptr, "SESS")) {
1250
1288
      /* clear session cookies */
1251
1289
      Curl_cookie_clearsess(data->cookies);
1252
1290
      break;
1253
1291
    }
1254
 
    else if(strequal(argptr, "FLUSH")) {
 
1292
    else if(Curl_raw_equal(argptr, "FLUSH")) {
1255
1293
      /* flush cookies to file */
1256
1294
      flush_cookies(data, 0);
1257
1295
      break;
1298
1336
    data->set.httpversion = va_arg(param, long);
1299
1337
    break;
1300
1338
 
1301
 
  case CURLOPT_HTTPPROXYTUNNEL:
1302
 
    /*
1303
 
     * Tunnel operations through the proxy instead of normal proxy use
1304
 
     */
1305
 
    data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long));
1306
 
    break;
1307
 
 
1308
1339
  case CURLOPT_CUSTOMREQUEST:
1309
1340
    /*
1310
1341
     * Set a custom string to use as request
1311
1342
     */
1312
1343
    result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1313
 
                            va_arg(param, char *));
 
1344
                       va_arg(param, char *));
1314
1345
 
1315
1346
    /* we don't set
1316
1347
       data->set.httpreq = HTTPREQ_CUSTOM;
1318
1349
       and this just changes the actual request keyword */
1319
1350
    break;
1320
1351
 
 
1352
  case CURLOPT_HTTPAUTH:
 
1353
    /*
 
1354
     * Set HTTP Authentication type BITMASK.
 
1355
     */
 
1356
  {
 
1357
    long auth = va_arg(param, long);
 
1358
 
 
1359
    /* the DIGEST_IE bit is only used to set a special marker, for all the
 
1360
       rest we need to handle it as normal DIGEST */
 
1361
    data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE);
 
1362
 
 
1363
    if(auth & CURLAUTH_DIGEST_IE) {
 
1364
      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
 
1365
      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
 
1366
    }
 
1367
 
 
1368
    /* switch off bits we can't support */
 
1369
#ifndef USE_NTLM
 
1370
    auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
 
1371
#endif
 
1372
#ifndef HAVE_GSSAPI
 
1373
    auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
 
1374
#endif
 
1375
    if(!auth)
 
1376
      return CURLE_FAILED_INIT; /* no supported types left! */
 
1377
 
 
1378
    data->set.httpauth = auth;
 
1379
  }
 
1380
  break;
 
1381
 
 
1382
#ifndef CURL_DISABLE_PROXY
 
1383
  case CURLOPT_HTTPPROXYTUNNEL:
 
1384
    /*
 
1385
     * Tunnel operations through the proxy instead of normal proxy use
 
1386
     */
 
1387
    data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long));
 
1388
    break;
 
1389
 
1321
1390
  case CURLOPT_PROXYPORT:
1322
1391
    /*
1323
1392
     * Explicitly set HTTP proxy port number.
1325
1394
    data->set.proxyport = va_arg(param, long);
1326
1395
    break;
1327
1396
 
1328
 
  case CURLOPT_HTTPAUTH:
1329
 
    /*
1330
 
     * Set HTTP Authentication type BITMASK.
1331
 
     */
1332
 
  {
1333
 
    long auth = va_arg(param, long);
1334
 
    /* switch off bits we can't support */
1335
 
#ifndef USE_NTLM
1336
 
    auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
1337
 
#endif
1338
 
#ifndef HAVE_GSSAPI
1339
 
    auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
1340
 
#endif
1341
 
    if(!auth)
1342
 
      return CURLE_FAILED_INIT; /* no supported types left! */
1343
 
 
1344
 
    data->set.httpauth = auth;
1345
 
  }
1346
 
  break;
1347
 
 
1348
1397
  case CURLOPT_PROXYAUTH:
1349
1398
    /*
1350
1399
     * Set HTTP Authentication type BITMASK.
1351
1400
     */
1352
1401
  {
1353
1402
    long auth = va_arg(param, long);
 
1403
 
 
1404
    /* the DIGEST_IE bit is only used to set a special marker, for all the
 
1405
       rest we need to handle it as normal DIGEST */
 
1406
    data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE);
 
1407
 
 
1408
    if(auth & CURLAUTH_DIGEST_IE) {
 
1409
      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
 
1410
      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
 
1411
    }
1354
1412
    /* switch off bits we can't support */
1355
1413
#ifndef USE_NTLM
1356
1414
    auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
1377
1435
     * to decide for us.
1378
1436
     */
1379
1437
    result = setstropt(&data->set.str[STRING_PROXY],
1380
 
                            va_arg(param, char *));
1381
 
    break;
 
1438
                       va_arg(param, char *));
 
1439
    break;
 
1440
 
 
1441
  case CURLOPT_PROXYTYPE:
 
1442
    /*
 
1443
     * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
 
1444
     */
 
1445
    data->set.proxytype = (curl_proxytype)va_arg(param, long);
 
1446
    break;
 
1447
 
 
1448
  case CURLOPT_PROXY_TRANSFER_MODE:
 
1449
    /*
 
1450
     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
 
1451
     */
 
1452
    switch (va_arg(param, long)) {
 
1453
    case 0:
 
1454
      data->set.proxy_transfer_mode = FALSE;
 
1455
      break;
 
1456
    case 1:
 
1457
      data->set.proxy_transfer_mode = TRUE;
 
1458
      break;
 
1459
    default:
 
1460
      /* reserve other values for future use */
 
1461
      result = CURLE_FAILED_INIT;
 
1462
      break;
 
1463
    }
 
1464
    break;
 
1465
#endif
 
1466
 
 
1467
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
1468
  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
 
1469
    /*
 
1470
     * Set gssapi service name
 
1471
     */
 
1472
    result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
 
1473
                       va_arg(param, char *));
 
1474
    break;
 
1475
 
 
1476
  case CURLOPT_SOCKS5_GSSAPI_NEC:
 
1477
    /*
 
1478
     * set flag for nec socks5 support
 
1479
     */
 
1480
    data->set.socks5_gssapi_nec = (bool)(0 != va_arg(param, long));
 
1481
    break;
 
1482
#endif
1382
1483
 
1383
1484
  case CURLOPT_WRITEHEADER:
1384
1485
    /*
1404
1505
     * Use FTP PORT, this also specifies which IP address to use
1405
1506
     */
1406
1507
    result = setstropt(&data->set.str[STRING_FTPPORT],
1407
 
                            va_arg(param, char *));
 
1508
                       va_arg(param, char *));
1408
1509
    data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]);
1409
1510
    break;
1410
1511
 
1458
1559
    break;
1459
1560
  case CURLOPT_MAX_SEND_SPEED_LARGE:
1460
1561
    /*
1461
 
     * The max speed limit that sends transfer more than
1462
 
     * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is
1463
 
     * throttled..
 
1562
     * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
 
1563
     * bytes per second the transfer is throttled..
1464
1564
     */
1465
1565
    data->set.max_send_speed=va_arg(param, curl_off_t);
1466
1566
    break;
1467
1567
  case CURLOPT_MAX_RECV_SPEED_LARGE:
1468
1568
    /*
1469
 
     * The max speed limit that sends transfer more than
1470
 
     * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is
1471
 
     * throttled..
 
1569
     * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
 
1570
     * second the transfer is throttled..
1472
1571
     */
1473
1572
    data->set.max_recv_speed=va_arg(param, curl_off_t);
1474
1573
    break;
1489
1588
      data->change.url_alloc=FALSE;
1490
1589
    }
1491
1590
    result = setstropt(&data->set.str[STRING_SET_URL],
1492
 
                            va_arg(param, char *));
 
1591
                       va_arg(param, char *));
1493
1592
    data->change.url = data->set.str[STRING_SET_URL];
1494
1593
    break;
1495
1594
  case CURLOPT_PORT:
1525
1624
    /*
1526
1625
     * user:password to use in the operation
1527
1626
     */
1528
 
    result = setstropt(&data->set.str[STRING_USERPWD],
1529
 
                            va_arg(param, char *));
 
1627
    result = setstropt_userpwd(va_arg(param, char *),
 
1628
                               &data->set.str[STRING_USERNAME],
 
1629
                               &data->set.str[STRING_PASSWORD]);
 
1630
    break;
 
1631
  case CURLOPT_USERNAME:
 
1632
    /*
 
1633
     * authentication user name to use in the operation
 
1634
     */
 
1635
    result = setstropt(&data->set.str[STRING_USERNAME],
 
1636
                       va_arg(param, char *));
 
1637
    break;
 
1638
  case CURLOPT_PASSWORD:
 
1639
    /*
 
1640
     * authentication password to use in the operation
 
1641
     */
 
1642
    result = setstropt(&data->set.str[STRING_PASSWORD],
 
1643
                       va_arg(param, char *));
1530
1644
    break;
1531
1645
  case CURLOPT_POSTQUOTE:
1532
1646
    /*
1563
1677
     */
1564
1678
    data->set.progress_client = va_arg(param, void *);
1565
1679
    break;
 
1680
 
 
1681
#ifndef CURL_DISABLE_PROXY
1566
1682
  case CURLOPT_PROXYUSERPWD:
1567
1683
    /*
1568
1684
     * user:password needed to use the proxy
1569
1685
     */
1570
 
    result = setstropt(&data->set.str[STRING_PROXYUSERPWD],
1571
 
                            va_arg(param, char *));
1572
 
    break;
 
1686
    result = setstropt_userpwd(va_arg(param, char *),
 
1687
                               &data->set.str[STRING_PROXYUSERNAME],
 
1688
                               &data->set.str[STRING_PROXYPASSWORD]);
 
1689
    break;
 
1690
  case CURLOPT_PROXYUSERNAME:
 
1691
    /*
 
1692
     * authentication user name to use in the operation
 
1693
     */
 
1694
    result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
 
1695
                       va_arg(param, char *));
 
1696
    break;
 
1697
  case CURLOPT_PROXYPASSWORD:
 
1698
    /*
 
1699
     * authentication password to use in the operation
 
1700
     */
 
1701
    result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
 
1702
                       va_arg(param, char *));
 
1703
    break;
 
1704
  case CURLOPT_NOPROXY:
 
1705
    /*
 
1706
     * proxy exception list
 
1707
     */
 
1708
    result = setstropt(&data->set.str[STRING_NOPROXY],
 
1709
                       va_arg(param, char *));
 
1710
    break;
 
1711
#endif
 
1712
 
1573
1713
  case CURLOPT_RANGE:
1574
1714
    /*
1575
1715
     * What range of the file you want to transfer
1576
1716
     */
1577
1717
    result = setstropt(&data->set.str[STRING_SET_RANGE],
1578
 
                            va_arg(param, char *));
 
1718
                       va_arg(param, char *));
1579
1719
    break;
1580
1720
  case CURLOPT_RESUME_FROM:
1581
1721
    /*
1685
1825
     * String that holds file name of the SSL certificate to use
1686
1826
     */
1687
1827
    result = setstropt(&data->set.str[STRING_CERT],
1688
 
                            va_arg(param, char *));
 
1828
                       va_arg(param, char *));
1689
1829
    break;
1690
1830
  case CURLOPT_SSLCERTTYPE:
1691
1831
    /*
1692
1832
     * String that holds file type of the SSL certificate to use
1693
1833
     */
1694
1834
    result = setstropt(&data->set.str[STRING_CERT_TYPE],
1695
 
                            va_arg(param, char *));
 
1835
                       va_arg(param, char *));
1696
1836
    break;
1697
1837
  case CURLOPT_SSLKEY:
1698
1838
    /*
1699
1839
     * String that holds file name of the SSL certificate to use
1700
1840
     */
1701
1841
    result = setstropt(&data->set.str[STRING_KEY],
1702
 
                            va_arg(param, char *));
 
1842
                       va_arg(param, char *));
1703
1843
    break;
1704
1844
  case CURLOPT_SSLKEYTYPE:
1705
1845
    /*
1706
1846
     * String that holds file type of the SSL certificate to use
1707
1847
     */
1708
1848
    result = setstropt(&data->set.str[STRING_KEY_TYPE],
1709
 
                            va_arg(param, char *));
 
1849
                       va_arg(param, char *));
1710
1850
    break;
1711
1851
  case CURLOPT_KEYPASSWD:
1712
1852
    /*
1713
1853
     * String that holds the SSL or SSH private key password.
1714
1854
     */
1715
1855
    result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1716
 
                            va_arg(param, char *));
 
1856
                       va_arg(param, char *));
1717
1857
    break;
1718
1858
  case CURLOPT_SSLENGINE:
1719
1859
    /*
1721
1861
     */
1722
1862
    argptr = va_arg(param, char *);
1723
1863
    if(argptr && argptr[0])
1724
 
       result = Curl_ssl_set_engine(data, argptr);
 
1864
      result = Curl_ssl_set_engine(data, argptr);
1725
1865
    break;
1726
1866
 
1727
1867
  case CURLOPT_SSLENGINE_DEFAULT:
1743
1883
     * performing an operation and thus what from-IP your connection will use.
1744
1884
     */
1745
1885
    result = setstropt(&data->set.str[STRING_DEVICE],
1746
 
                            va_arg(param, char *));
 
1886
                       va_arg(param, char *));
1747
1887
    break;
1748
1888
  case CURLOPT_LOCALPORT:
1749
1889
    /*
1762
1902
     * A string that defines the kerberos security level.
1763
1903
     */
1764
1904
    result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1765
 
                            va_arg(param, char *));
 
1905
                       va_arg(param, char *));
1766
1906
    data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]);
1767
1907
    break;
1768
1908
  case CURLOPT_SSL_VERIFYPEER:
1794
1934
     */
1795
1935
    data->set.ssl.fsslctxp = va_arg(param, void *);
1796
1936
    break;
 
1937
  case CURLOPT_CERTINFO:
 
1938
    data->set.ssl.certinfo = (bool)(0 != va_arg(param, long));
 
1939
    break;
1797
1940
#endif
1798
1941
  case CURLOPT_CAINFO:
1799
1942
    /*
1800
1943
     * Set CA info for SSL connection. Specify file name of the CA certificate
1801
1944
     */
1802
1945
    result = setstropt(&data->set.str[STRING_SSL_CAFILE],
1803
 
                            va_arg(param, char *));
 
1946
                       va_arg(param, char *));
1804
1947
    break;
1805
1948
  case CURLOPT_CAPATH:
1806
1949
    /*
1809
1952
     */
1810
1953
    /* This does not work on windows. */
1811
1954
    result = setstropt(&data->set.str[STRING_SSL_CAPATH],
1812
 
                            va_arg(param, char *));
 
1955
                       va_arg(param, char *));
 
1956
    break;
 
1957
  case CURLOPT_CRLFILE:
 
1958
    /*
 
1959
     * Set CRL file info for SSL connection. Specify file name of the CRL
 
1960
     * to check certificates revocation
 
1961
     */
 
1962
    result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
 
1963
                       va_arg(param, char *));
 
1964
    break;
 
1965
  case CURLOPT_ISSUERCERT:
 
1966
    /*
 
1967
     * Set Issuer certificate file
 
1968
     * to check certificates issuer
 
1969
     */
 
1970
    result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
 
1971
                       va_arg(param, char *));
1813
1972
    break;
1814
1973
  case CURLOPT_TELNETOPTIONS:
1815
1974
    /*
1840
1999
    break;
1841
2000
 
1842
2001
  case CURLOPT_SHARE:
1843
 
    {
1844
 
      struct Curl_share *set;
1845
 
      set = va_arg(param, struct Curl_share *);
1846
 
 
1847
 
      /* disconnect from old share, if any */
1848
 
      if(data->share) {
1849
 
        Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1850
 
 
1851
 
        if(data->dns.hostcachetype == HCACHE_SHARED) {
1852
 
          data->dns.hostcache = NULL;
1853
 
          data->dns.hostcachetype = HCACHE_NONE;
1854
 
        }
1855
 
 
1856
 
        if(data->share->cookies == data->cookies)
1857
 
          data->cookies = NULL;
1858
 
 
1859
 
        data->share->dirty--;
1860
 
 
1861
 
        Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1862
 
        data->share = NULL;
1863
 
      }
1864
 
 
1865
 
      /* use new share if it set */
1866
 
      data->share = set;
1867
 
      if(data->share) {
1868
 
 
1869
 
        Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1870
 
 
1871
 
        data->share->dirty++;
1872
 
 
1873
 
        if(data->share->hostcache) {
1874
 
          /* use shared host cache, first free the private one if any */
1875
 
          if(data->dns.hostcachetype == HCACHE_PRIVATE)
1876
 
            Curl_hash_destroy(data->dns.hostcache);
1877
 
 
1878
 
          data->dns.hostcache = data->share->hostcache;
1879
 
          data->dns.hostcachetype = HCACHE_SHARED;
1880
 
        }
 
2002
  {
 
2003
    struct Curl_share *set;
 
2004
    set = va_arg(param, struct Curl_share *);
 
2005
 
 
2006
    /* disconnect from old share, if any */
 
2007
    if(data->share) {
 
2008
      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
 
2009
 
 
2010
      if(data->dns.hostcachetype == HCACHE_SHARED) {
 
2011
        data->dns.hostcache = NULL;
 
2012
        data->dns.hostcachetype = HCACHE_NONE;
 
2013
      }
 
2014
 
 
2015
      if(data->share->cookies == data->cookies)
 
2016
        data->cookies = NULL;
 
2017
 
 
2018
      data->share->dirty--;
 
2019
 
 
2020
      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
 
2021
      data->share = NULL;
 
2022
    }
 
2023
 
 
2024
    /* use new share if it set */
 
2025
    data->share = set;
 
2026
    if(data->share) {
 
2027
 
 
2028
      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
 
2029
 
 
2030
      data->share->dirty++;
 
2031
 
 
2032
      if(data->share->hostcache) {
 
2033
        /* use shared host cache, first free the private one if any */
 
2034
        if(data->dns.hostcachetype == HCACHE_PRIVATE)
 
2035
          Curl_hash_destroy(data->dns.hostcache);
 
2036
 
 
2037
        data->dns.hostcache = data->share->hostcache;
 
2038
        data->dns.hostcachetype = HCACHE_SHARED;
 
2039
      }
1881
2040
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1882
 
        if(data->share->cookies) {
1883
 
          /* use shared cookie list, first free own one if any */
1884
 
          if(data->cookies)
1885
 
            Curl_cookie_cleanup(data->cookies);
1886
 
          /* enable cookies since we now use a share that uses cookies! */
1887
 
          data->cookies = data->share->cookies;
1888
 
        }
 
2041
      if(data->share->cookies) {
 
2042
        /* use shared cookie list, first free own one if any */
 
2043
        if(data->cookies)
 
2044
          Curl_cookie_cleanup(data->cookies);
 
2045
        /* enable cookies since we now use a share that uses cookies! */
 
2046
        data->cookies = data->share->cookies;
 
2047
      }
1889
2048
#endif   /* CURL_DISABLE_HTTP */
1890
 
        Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
 
2049
      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1891
2050
 
1892
 
      }
1893
 
      /* check for host cache not needed,
1894
 
       * it will be done by curl_easy_perform */
1895
2051
    }
1896
 
    break;
1897
 
 
1898
 
  case CURLOPT_PROXYTYPE:
1899
 
    /*
1900
 
     * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1901
 
     */
1902
 
    data->set.proxytype = (curl_proxytype)va_arg(param, long);
1903
 
    break;
 
2052
    /* check for host cache not needed,
 
2053
     * it will be done by curl_easy_perform */
 
2054
  }
 
2055
  break;
1904
2056
 
1905
2057
  case CURLOPT_PRIVATE:
1906
2058
    /*
1949
2101
    data->set.tcp_nodelay = (bool)(0 != va_arg(param, long));
1950
2102
    break;
1951
2103
 
1952
 
    /*
1953
 
      case CURLOPT_SOURCE_URL:
1954
 
      case CURLOPT_SOURCE_USERPWD:
1955
 
      case CURLOPT_SOURCE_QUOTE:
1956
 
      case CURLOPT_SOURCE_PREQUOTE:
1957
 
      case CURLOPT_SOURCE_POSTQUOTE:
1958
 
      These former 3rd party transfer options are deprecated */
1959
 
 
1960
2104
  case CURLOPT_FTP_ACCOUNT:
1961
2105
    result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
1962
 
                            va_arg(param, char *));
 
2106
                       va_arg(param, char *));
1963
2107
    break;
1964
2108
 
1965
2109
  case CURLOPT_IGNORE_CONTENT_LENGTH:
1975
2119
 
1976
2120
  case CURLOPT_FTP_ALTERNATIVE_TO_USER:
1977
2121
    result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
1978
 
                            va_arg(param, char *));
 
2122
                       va_arg(param, char *));
1979
2123
    break;
1980
2124
 
1981
2125
  case CURLOPT_SOCKOPTFUNCTION:
2020
2164
     * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2021
2165
     */
2022
2166
    result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2023
 
                            va_arg(param, char *));
 
2167
                       va_arg(param, char *));
2024
2168
    break;
2025
2169
 
2026
2170
  case CURLOPT_SSH_PRIVATE_KEYFILE:
2028
2172
     * Use this file instead of the $HOME/.ssh/id_dsa file
2029
2173
     */
2030
2174
    result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2031
 
                            va_arg(param, char *));
 
2175
                       va_arg(param, char *));
2032
2176
    break;
2033
2177
  case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2034
2178
    /*
2036
2180
     * for validation purposes.
2037
2181
     */
2038
2182
    result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2039
 
                            va_arg(param, char *));
 
2183
                       va_arg(param, char *));
2040
2184
    break;
2041
2185
  case CURLOPT_HTTP_TRANSFER_DECODING:
2042
2186
    /*
2065
2209
     */
2066
2210
    data->set.new_directory_perms = va_arg(param, long);
2067
2211
    break;
2068
 
  case CURLOPT_PROXY_TRANSFER_MODE:
 
2212
 
 
2213
  case CURLOPT_ADDRESS_SCOPE:
2069
2214
    /*
2070
 
     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
 
2215
     * We always get longs when passed plain numericals, but for this value we
 
2216
     * know that an unsigned int will always hold the value so we blindly
 
2217
     * typecast to this type
2071
2218
     */
2072
 
    switch (va_arg(param, long)) {
2073
 
      case 0:
2074
 
        data->set.proxy_transfer_mode = FALSE;
2075
 
        break;
2076
 
      case 1:
2077
 
        data->set.proxy_transfer_mode = TRUE;
2078
 
        break;
2079
 
      default:
2080
 
        /* reserve other values for future use */
2081
 
        result = CURLE_FAILED_INIT;
2082
 
        break;
2083
 
    }
 
2219
    data->set.scope = (unsigned int) va_arg(param, long);
 
2220
    break;
 
2221
 
 
2222
  case CURLOPT_PROTOCOLS:
 
2223
    /* set the bitmask for the protocols that are allowed to be used for the
 
2224
       transfer, which thus helps the app which takes URLs from users or other
 
2225
       external inputs and want to restrict what protocol(s) to deal
 
2226
       with. Defaults to CURLPROTO_ALL. */
 
2227
    data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
 
2228
    break;
 
2229
 
 
2230
  case CURLOPT_REDIR_PROTOCOLS:
 
2231
    /* set the bitmask for the protocols that libcurl is allowed to follow to,
 
2232
       as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
 
2233
       to be set in both bitmasks to be allowed to get redirected to. Defaults
 
2234
       to all protocols except FILE and SCP. */
 
2235
    data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
2084
2236
    break;
2085
2237
 
2086
2238
  default:
2115
2267
  Curl_safefree(conn->allocptr.ref);
2116
2268
  Curl_safefree(conn->allocptr.host);
2117
2269
  Curl_safefree(conn->allocptr.cookiehost);
2118
 
  Curl_safefree(conn->ip_addr_str);
2119
2270
  Curl_safefree(conn->trailer);
2120
2271
  Curl_safefree(conn->host.rawalloc); /* host name buffer */
2121
2272
  Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2162
2313
  Curl_expire(data, 0); /* shut off timers */
2163
2314
  Curl_hostcache_prune(data); /* kill old DNS cache entries */
2164
2315
 
2165
 
  if((conn->ntlm.state != NTLMSTATE_NONE) ||
2166
 
     (conn->proxyntlm.state != NTLMSTATE_NONE)) {
 
2316
  {
 
2317
    int has_host_ntlm = (conn->ntlm.state != NTLMSTATE_NONE);
 
2318
    int has_proxy_ntlm = (conn->proxyntlm.state != NTLMSTATE_NONE);
 
2319
 
2167
2320
    /* Authentication data is a mix of connection-related and sessionhandle-
2168
2321
       related stuff. NTLM is connection-related so when we close the shop
2169
2322
       we shall forget. */
2170
 
    data->state.authhost.done = FALSE;
2171
 
    data->state.authhost.picked =
2172
 
      data->state.authhost.want;
2173
 
 
2174
 
    data->state.authproxy.done = FALSE;
2175
 
    data->state.authproxy.picked =
2176
 
      data->state.authproxy.want;
2177
 
 
2178
 
    data->state.authproblem = FALSE;
2179
 
 
2180
 
    Curl_ntlm_cleanup(conn);
 
2323
 
 
2324
    if (has_host_ntlm) {
 
2325
      data->state.authhost.done = FALSE;
 
2326
      data->state.authhost.picked =
 
2327
        data->state.authhost.want;
 
2328
    }
 
2329
 
 
2330
    if (has_proxy_ntlm) {
 
2331
      data->state.authproxy.done = FALSE;
 
2332
      data->state.authproxy.picked =
 
2333
        data->state.authproxy.want;
 
2334
    }
 
2335
 
 
2336
    if (has_host_ntlm || has_proxy_ntlm) {
 
2337
      data->state.authproblem = FALSE;
 
2338
 
 
2339
      Curl_ntlm_cleanup(conn);
 
2340
    }
 
2341
  }
 
2342
 
 
2343
  /* Cleanup possible redirect junk */
 
2344
  if(data->req.newurl) {
 
2345
    free(data->req.newurl);
 
2346
    data->req.newurl = NULL;
2181
2347
  }
2182
2348
 
2183
2349
  if(conn->handler->disconnect)
2312
2478
  return NULL;
2313
2479
}
2314
2480
 
 
2481
/* remove the specified connection from all (possible) pipelines and related
 
2482
   queues */
 
2483
void Curl_getoff_all_pipelines(struct SessionHandle *data,
 
2484
                               struct connectdata *conn)
 
2485
{
 
2486
  bool recv_head = (bool)(conn->readchannel_inuse &&
 
2487
    (gethandleathead(conn->recv_pipe) == data));
 
2488
 
 
2489
  bool send_head = (bool)(conn->writechannel_inuse &&
 
2490
    (gethandleathead(conn->send_pipe) == data));
 
2491
 
 
2492
  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
 
2493
    conn->readchannel_inuse = FALSE;
 
2494
  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
 
2495
    conn->writechannel_inuse = FALSE;
 
2496
  Curl_removeHandleFromPipeline(data, conn->pend_pipe);
 
2497
}
 
2498
 
2315
2499
static void signalPipeClose(struct curl_llist *pipeline)
2316
2500
{
2317
2501
  struct curl_llist_element *curr;
2377
2561
                                  from the multi */
2378
2562
    }
2379
2563
 
 
2564
    if(!pipeLen && !check->inuse) {
 
2565
      /* The check for a dead socket makes sense only if there are no
 
2566
         handles in pipeline and the connection isn't already marked in
 
2567
         use */
 
2568
      bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
 
2569
      if(dead) {
 
2570
        check->data = data;
 
2571
        infof(data, "Connection #%d seems to be dead!\n", i);
 
2572
 
 
2573
        Curl_disconnect(check); /* disconnect resources */
 
2574
        data->state.connc->connects[i]=NULL; /* nothing here */
 
2575
 
 
2576
        continue;
 
2577
      }
 
2578
    }
 
2579
 
2380
2580
    if(canPipeline) {
2381
2581
      /* Make sure the pipe has only GET requests */
2382
2582
      struct SessionHandle* sh = gethandleathead(check->send_pipe);
2405
2605
      }
2406
2606
 
2407
2607
#ifdef CURLRES_ASYNCH
2408
 
      /* ip_addr_str is NULL only if the resolving of the name hasn't completed
2409
 
         yet and until then we don't re-use this connection */
2410
 
      if(!check->ip_addr_str) {
 
2608
      /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
 
2609
         completed yet and until then we don't re-use this connection */
 
2610
      if(!check->ip_addr_str[0]) {
2411
2611
        infof(data,
2412
2612
              "Connection #%ld hasn't finished name resolve, can't reuse\n",
2413
2613
              check->connectindex);
2438
2638
      /* don't do mixed proxy and non-proxy connections */
2439
2639
      continue;
2440
2640
 
 
2641
    if(!canPipeline && check->inuse)
 
2642
      /* this request can't be pipelined but the checked connection is already
 
2643
         in use so we skip it */
 
2644
      continue;
 
2645
 
2441
2646
    if(!needle->bits.httpproxy || needle->protocol&PROT_SSL ||
2442
2647
       (needle->bits.httpproxy && check->bits.httpproxy &&
2443
2648
        needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
2444
 
        strequal(needle->proxy.name, check->proxy.name) &&
 
2649
        Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
2445
2650
        (needle->port == check->port))) {
2446
2651
      /* The requested connection does not use a HTTP proxy or it uses SSL or
2447
2652
         it is a non-SSL protocol tunneled over the same http proxy name and
2448
2653
         port number */
2449
2654
 
2450
 
      if(strequal(needle->protostr, check->protostr) &&
2451
 
         strequal(needle->host.name, check->host.name) &&
 
2655
      if(Curl_raw_equal(needle->protostr, check->protostr) &&
 
2656
         Curl_raw_equal(needle->host.name, check->host.name) &&
2452
2657
         (needle->remote_port == check->remote_port) ) {
2453
2658
        if(needle->protocol & PROT_SSL) {
2454
2659
          /* This is SSL, verify that we're using the same
2487
2692
              is the checked one using the same host, port and type? */
2488
2693
      if(check->bits.proxy &&
2489
2694
         (needle->proxytype == check->proxytype) &&
2490
 
         strequal(needle->proxy.name, check->proxy.name) &&
 
2695
         Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
2491
2696
         needle->port == check->port) {
2492
2697
        /* This is the same proxy connection, use it! */
2493
2698
        match = TRUE;
2495
2700
    }
2496
2701
 
2497
2702
    if(match) {
2498
 
      if(pipeLen == 0) {
2499
 
        /* The check for a dead socket makes sense only if there
2500
 
           are no handles in pipeline */
2501
 
        bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
2502
 
        if(dead) {
2503
 
          check->data = data;
2504
 
          infof(data, "Connection #%d seems to be dead!\n", i);
2505
 
 
2506
 
          Curl_disconnect(check); /* disconnect resources */
2507
 
          data->state.connc->connects[i]=NULL; /* nothing here */
2508
 
 
2509
 
          return FALSE;
2510
 
        }
2511
 
      }
2512
 
 
2513
2703
      check->inuse = TRUE; /* mark this as being in use so that no other
2514
2704
                              handle in a multi stack may nick it */
2515
2705
 
2624
2814
  return i;
2625
2815
}
2626
2816
 
 
2817
/* after a TCP connection to the proxy has been verified, this function does
 
2818
   the next magic step.
 
2819
 
 
2820
   Note: this function (and its sub-functions) calls failf()
 
2821
 
 
2822
*/
 
2823
CURLcode Curl_connected_proxy(struct connectdata *conn)
 
2824
{
 
2825
  CURLcode result = CURLE_OK;
 
2826
  struct SessionHandle *data = conn->data;
 
2827
 
 
2828
  if(conn->bits.tcpconnect)
 
2829
    /* allow this to get called again from the multi interface when TCP is
 
2830
       found connected in the state machine, even though it has already been
 
2831
       called if the connection happened "instantly" */
 
2832
    return CURLE_OK;
 
2833
 
 
2834
  switch(data->set.proxytype) {
 
2835
#ifndef CURL_DISABLE_PROXY
 
2836
  case CURLPROXY_SOCKS5:
 
2837
  case CURLPROXY_SOCKS5_HOSTNAME:
 
2838
    result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
 
2839
                         conn->host.name, conn->remote_port,
 
2840
                         FIRSTSOCKET, conn);
 
2841
    break;
 
2842
  case CURLPROXY_SOCKS4:
 
2843
    result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
 
2844
                         conn->remote_port, FIRSTSOCKET, conn, FALSE);
 
2845
    break;
 
2846
  case CURLPROXY_SOCKS4A:
 
2847
    result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
 
2848
                         conn->remote_port, FIRSTSOCKET, conn, TRUE);
 
2849
    break;
 
2850
#endif /* CURL_DISABLE_PROXY */
 
2851
  case CURLPROXY_HTTP:
 
2852
  case CURLPROXY_HTTP_1_0:
 
2853
    /* do nothing here. handled later. */
 
2854
    break;
 
2855
  default:
 
2856
    break;
 
2857
  } /* switch proxytype */
 
2858
 
 
2859
  return result;
 
2860
}
 
2861
 
2627
2862
static CURLcode ConnectPlease(struct SessionHandle *data,
2628
2863
                              struct connectdata *conn,
2629
2864
                              struct Curl_dns_entry *hostaddr,
2648
2883
                           &addr,
2649
2884
                           connected);
2650
2885
  if(CURLE_OK == result) {
2651
 
    /* All is cool, then we store the current information */
 
2886
    /* All is cool, we store the current information */
2652
2887
    conn->dns_entry = hostaddr;
2653
2888
    conn->ip_addr = addr;
2654
2889
 
2655
 
    result = Curl_store_ip_addr(conn);
2656
 
 
2657
 
    if(CURLE_OK == result) {
2658
 
 
2659
 
      switch(data->set.proxytype) {
2660
 
      case CURLPROXY_SOCKS5:
2661
 
      case CURLPROXY_SOCKS5_HOSTNAME:
2662
 
        result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
2663
 
                             conn->host.name, conn->remote_port,
2664
 
                             FIRSTSOCKET, conn);
2665
 
        break;
2666
 
      case CURLPROXY_HTTP:
2667
 
        /* do nothing here. handled later. */
2668
 
        break;
2669
 
      case CURLPROXY_SOCKS4:
2670
 
        result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
2671
 
                             conn->remote_port, FIRSTSOCKET, conn, FALSE);
2672
 
        break;
2673
 
      case CURLPROXY_SOCKS4A:
2674
 
        result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
2675
 
                             conn->remote_port, FIRSTSOCKET, conn, TRUE);
2676
 
        break;
2677
 
      default:
2678
 
        failf(data, "unknown proxytype option given");
2679
 
        result = CURLE_COULDNT_CONNECT;
2680
 
        break;
2681
 
      }
2682
 
    }
 
2890
    if(*connected)
 
2891
      result = Curl_connected_proxy(conn);
2683
2892
  }
 
2893
 
2684
2894
  if(result)
2685
2895
    *connected = FALSE; /* mark it as not connected */
2686
2896
 
2839
3049
  char *uc_name = NULL;
2840
3050
  int rc;
2841
3051
#ifndef CURL_DISABLE_VERBOSE_STRINGS
2842
 
  char *tld_errmsg = (char *)"<no msg>";
 
3052
  const char *tld_errmsg = "<no msg>";
2843
3053
#else
2844
3054
  (void)data;
2845
3055
#endif
2853
3063
#ifndef CURL_DISABLE_VERBOSE_STRINGS
2854
3064
#ifdef HAVE_TLD_STRERROR
2855
3065
  if(rc != TLD_SUCCESS)
2856
 
    tld_errmsg = (char *)tld_strerror((Tld_rc)rc);
 
3066
    tld_errmsg = tld_strerror((Tld_rc)rc);
2857
3067
#endif
2858
3068
  if(rc == TLD_INVALID)
2859
3069
    infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2869
3079
}
2870
3080
#endif
2871
3081
 
 
3082
/*
 
3083
 * Perform any necessary IDN conversion of hostname
 
3084
 */
2872
3085
static void fix_hostname(struct SessionHandle *data,
2873
3086
                         struct connectdata *conn, struct hostname *host)
2874
3087
{
2909
3122
}
2910
3123
 
2911
3124
/*
 
3125
 * Allocate and initialize a new connectdata object.
 
3126
 */
 
3127
static struct connectdata *allocate_conn(void)
 
3128
{
 
3129
  struct connectdata *conn;
 
3130
 
 
3131
  conn = calloc(1, sizeof(struct connectdata));
 
3132
  if(!conn)
 
3133
    return NULL;
 
3134
 
 
3135
  conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
 
3136
                                           already from start to avoid NULL
 
3137
                                           situations and checks */
 
3138
 
 
3139
  /* and we setup a few fields in case we end up actually using this struct */
 
3140
 
 
3141
  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
 
3142
  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
 
3143
  conn->connectindex = -1;    /* no index */
 
3144
 
 
3145
  /* Default protocol-independent behavior doesn't support persistent
 
3146
     connections, so we set this to force-close. Protocols that support
 
3147
     this need to set this to FALSE in their "curl_do" functions. */
 
3148
  conn->bits.close = TRUE;
 
3149
 
 
3150
  /* Store creation time to help future close decision making */
 
3151
  conn->created = Curl_tvnow();
 
3152
 
 
3153
  return conn;
 
3154
}
 
3155
 
 
3156
/*
2912
3157
 * Parse URL and fill in the relevant members of the connection struct.
2913
3158
 */
2914
3159
static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
2916
3161
{
2917
3162
  char *at;
2918
3163
  char *tmp;
2919
 
 
2920
3164
  char *path = data->state.path;
 
3165
  int rc;
2921
3166
 
2922
3167
  /*************************************************************
2923
3168
   * Parse the URL.
2929
3174
   ************************************************************/
2930
3175
  if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
2931
3176
                  conn->protostr,
2932
 
                  path)) && strequal(conn->protostr, "file")) {
 
3177
                  path)) && Curl_raw_equal(conn->protostr, "file")) {
2933
3178
    if(path[0] == '/' && path[1] == '/') {
2934
3179
      /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
2935
3180
       * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2990
3235
       * The URL was badly formatted, let's try the browser-style _without_
2991
3236
       * protocol specified like 'http://'.
2992
3237
       */
2993
 
      if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
2994
 
                     conn->host.name, path)) ) {
 
3238
      if(1 > (rc = sscanf(data->change.url, "%[^\n/]%[^\n]",
 
3239
                          conn->host.name, path)) ) {
2995
3240
        /*
2996
3241
         * We couldn't even get this format.
 
3242
         * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
 
3243
         * assigned, but the return value is EOF!
2997
3244
         */
2998
 
        failf(data, "<url> malformed");
2999
 
        return CURLE_URL_MALFORMAT;
 
3245
#if defined(__DJGPP__) && (DJGPP_MINOR == 4)
 
3246
        if (!(rc == -1 && *conn->host.name))
 
3247
#endif
 
3248
        {
 
3249
          failf(data, "<url> malformed");
 
3250
          return CURLE_URL_MALFORMAT;
 
3251
        }
3000
3252
      }
3001
3253
 
3002
3254
      /*
3071
3323
    path[0] = '/';
3072
3324
  }
3073
3325
 
 
3326
  if (conn->host.name[0] == '[') {
 
3327
    /* This looks like an IPv6 address literal.  See if there is an address
 
3328
       scope.  */
 
3329
    char *percent = strstr (conn->host.name, "%25");
 
3330
    if (percent) {
 
3331
      char *endp;
 
3332
      unsigned long scope = strtoul (percent + 3, &endp, 10);
 
3333
      if (*endp == ']') {
 
3334
        /* The address scope was well formed.  Knock it out of the hostname.  */
 
3335
        memmove(percent, endp, strlen(endp)+1);
 
3336
        if (!data->state.this_is_a_follow)
 
3337
          /* Don't honour a scope given in a Location: header */
 
3338
          conn->scope = (unsigned int)scope;
 
3339
      } else
 
3340
        infof(data, "Invalid IPv6 address format\n");
 
3341
    }
 
3342
  }
 
3343
 
 
3344
  if (data->set.scope)
 
3345
    /* Override any scope that was set above.  */
 
3346
    conn->scope = data->set.scope;
 
3347
 
3074
3348
  /*
3075
3349
   * So if the URL was A://B/C,
3076
3350
   *   conn->protostr is A
3077
3351
   *   conn->host.name is B
3078
3352
   *   data->state.path is /C
3079
3353
   */
3080
 
 
 
3354
  (void)rc;
3081
3355
  return CURLE_OK;
3082
3356
}
3083
3357
 
3088
3362
  /* Do nothing */
3089
3363
}
3090
3364
 
 
3365
/*
 
3366
 * If we're doing a resumed transfer, we need to setup our stuff
 
3367
 * properly.
 
3368
 */
3091
3369
static CURLcode setup_range(struct SessionHandle *data)
3092
3370
{
3093
 
  /*
3094
 
   * If we're doing a resumed transfer, we need to setup our stuff
3095
 
   * properly.
3096
 
   */
3097
3371
  struct UrlState *s = &data->state;
3098
3372
  s->resume_from = data->set.set_resume_from;
3099
3373
  if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
3101
3375
      free(s->range);
3102
3376
 
3103
3377
    if(s->resume_from)
3104
 
      s->range = aprintf("%" FORMAT_OFF_T "-", s->resume_from);
 
3378
      s->range = aprintf("%" FORMAT_OFF_TU "-", s->resume_from);
3105
3379
    else
3106
3380
      s->range = strdup(data->set.str[STRING_SET_RANGE]);
3107
3381
 
3135
3409
  /* Scan protocol handler table. */
3136
3410
 
3137
3411
  for (pp = protocols; (p = *pp) != NULL; pp++)
3138
 
    if(strequal(p->scheme, conn->protostr)) {
3139
 
      /* Protocol found in table. Perform setup complement if some. */
 
3412
    if(Curl_raw_equal(p->scheme, conn->protostr)) {
 
3413
      /* Protocol found in table. Check if allowed */
 
3414
      if(!(data->set.allowed_protocols & p->protocol))
 
3415
        /* nope, get out */
 
3416
        break;
 
3417
 
 
3418
      /* it is allowed for "normal" request, now do an extra check if this is
 
3419
         the result of a redirect */
 
3420
      if(data->state.this_is_a_follow &&
 
3421
         !(data->set.redir_protocols & p->protocol))
 
3422
        /* nope, get out */
 
3423
        break;
 
3424
 
 
3425
      /* Perform setup complement if some. */
3140
3426
      conn->handler = p;
3141
3427
 
3142
3428
      if(p->setup_connection) {
3156
3442
 
3157
3443
  /* The protocol was not found in the table, but we don't have to assign it
3158
3444
     to anything since it is already assigned to a dummy-struct in the
3159
 
     CreateConnection() function when the connectdata struct is allocated. */
 
3445
     create_conn() function when the connectdata struct is allocated. */
3160
3446
  failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
3161
3447
        conn->protostr);
3162
3448
  return CURLE_UNSUPPORTED_PROTOCOL;
3163
3449
}
3164
3450
 
 
3451
#ifndef CURL_DISABLE_PROXY
 
3452
/****************************************************************
 
3453
* Checks if the host is in the noproxy list. returns true if it matches
 
3454
* and therefore the proxy should NOT be used.
 
3455
****************************************************************/
 
3456
static bool check_noproxy(const char* name, const char* no_proxy)
 
3457
{
 
3458
  /* no_proxy=domain1.dom,host.domain2.dom
 
3459
   *   (a comma-separated list of hosts which should
 
3460
   *   not be proxied, or an asterisk to override
 
3461
   *   all proxy variables)
 
3462
   */
 
3463
  size_t tok_start;
 
3464
  size_t tok_end;
 
3465
  const char* separator = ", ";
 
3466
  size_t no_proxy_len;
 
3467
  size_t namelen;
 
3468
  char *endptr;
 
3469
 
 
3470
  if(no_proxy && no_proxy[0]) {
 
3471
    if(Curl_raw_equal("*", no_proxy)) {
 
3472
      return TRUE;
 
3473
    }
 
3474
 
 
3475
    /* NO_PROXY was specified and it wasn't just an asterisk */
 
3476
 
 
3477
    no_proxy_len = strlen(no_proxy);
 
3478
    endptr = strchr(name, ':');
 
3479
    if(endptr)
 
3480
      namelen = endptr - name;
 
3481
    else
 
3482
      namelen = strlen(name);
 
3483
 
 
3484
    tok_start = 0;
 
3485
    for (tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
 
3486
      while (tok_start < no_proxy_len &&
 
3487
             strchr(separator, no_proxy[tok_start]) != NULL) {
 
3488
        /* Look for the beginning of the token. */
 
3489
        ++tok_start;
 
3490
      }
 
3491
 
 
3492
      if(tok_start == no_proxy_len)
 
3493
        break; /* It was all trailing separator chars, no more tokens. */
 
3494
 
 
3495
      for (tok_end = tok_start; tok_end < no_proxy_len &&
 
3496
             strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) {
 
3497
        /* Look for the end of the token. */
 
3498
      }
 
3499
 
 
3500
      /* To match previous behaviour, where it was necessary to specify
 
3501
       * ".local.com" to prevent matching "notlocal.com", we will leave
 
3502
       * the '.' off.
 
3503
       */
 
3504
      if(no_proxy[tok_start] == '.')
 
3505
        ++tok_start;
 
3506
 
 
3507
      if((tok_end - tok_start) <= namelen) {
 
3508
        /* Match the last part of the name to the domain we are checking. */
 
3509
        const char *checkn = name + namelen - (tok_end - tok_start);
 
3510
        if(Curl_raw_nequal(no_proxy + tok_start, checkn, tok_end - tok_start)) {
 
3511
          if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
 
3512
            /* We either have an exact match, or the previous character is a .
 
3513
             * so it is within the same domain, so no proxy for this host.
 
3514
             */
 
3515
            return TRUE;
 
3516
          }
 
3517
        }
 
3518
      } /* if((tok_end - tok_start) <= namelen) */
 
3519
    } /* for (tok_start = 0; tok_start < no_proxy_len;
 
3520
         tok_start = tok_end + 1) */
 
3521
  } /* NO_PROXY was specified and it wasn't just an asterisk */
 
3522
 
 
3523
  return FALSE;
 
3524
}
 
3525
 
3165
3526
/****************************************************************
3166
3527
* Detect what (if any) proxy to use. Remember that this selects a host
3167
3528
* name and is not limited to HTTP proxies only.
3190
3551
   * checked if the lowercase versions don't exist.
3191
3552
   */
3192
3553
  char *no_proxy=NULL;
3193
 
  char *no_proxy_tok_buf;
3194
3554
  char proxy_env[128];
3195
3555
 
3196
3556
  no_proxy=curl_getenv("no_proxy");
3197
3557
  if(!no_proxy)
3198
3558
    no_proxy=curl_getenv("NO_PROXY");
3199
3559
 
3200
 
  if(!no_proxy || !strequal("*", no_proxy)) {
3201
 
    /* NO_PROXY wasn't specified or it wasn't just an asterisk */
3202
 
    char *nope;
3203
 
 
3204
 
    nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
3205
 
    while(nope) {
3206
 
      size_t namelen;
3207
 
      char *endptr = strchr(conn->host.name, ':');
3208
 
      if(endptr)
3209
 
        namelen=endptr-conn->host.name;
3210
 
      else
3211
 
        namelen=strlen(conn->host.name);
3212
 
 
3213
 
      if(strlen(nope) <= namelen) {
3214
 
        char *checkn=
3215
 
          conn->host.name + namelen - strlen(nope);
3216
 
        if(checkprefix(nope, checkn)) {
3217
 
          /* no proxy for this host! */
3218
 
          break;
3219
 
        }
3220
 
      }
3221
 
      nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
3222
 
    }
3223
 
    if(!nope) {
3224
 
      /* It was not listed as without proxy */
3225
 
      char *protop = conn->protostr;
3226
 
      char *envp = proxy_env;
3227
 
      char *prox;
3228
 
 
3229
 
      /* Now, build <protocol>_proxy and check for such a one to use */
3230
 
      while(*protop)
3231
 
        *envp++ = (char)tolower((int)*protop++);
3232
 
 
3233
 
      /* append _proxy */
3234
 
      strcpy(envp, "_proxy");
3235
 
 
3236
 
      /* read the protocol proxy: */
 
3560
  if(!check_noproxy(conn->host.name, no_proxy)) {
 
3561
    /* It was not listed as without proxy */
 
3562
    char *protop = conn->protostr;
 
3563
    char *envp = proxy_env;
 
3564
    char *prox;
 
3565
 
 
3566
    /* Now, build <protocol>_proxy and check for such a one to use */
 
3567
    while(*protop)
 
3568
      *envp++ = (char)tolower((int)*protop++);
 
3569
 
 
3570
    /* append _proxy */
 
3571
    strcpy(envp, "_proxy");
 
3572
 
 
3573
    /* read the protocol proxy: */
 
3574
    prox=curl_getenv(proxy_env);
 
3575
 
 
3576
    /*
 
3577
     * We don't try the uppercase version of HTTP_PROXY because of
 
3578
     * security reasons:
 
3579
     *
 
3580
     * When curl is used in a webserver application
 
3581
     * environment (cgi or php), this environment variable can
 
3582
     * be controlled by the web server user by setting the
 
3583
     * http header 'Proxy:' to some value.
 
3584
     *
 
3585
     * This can cause 'internal' http/ftp requests to be
 
3586
     * arbitrarily redirected by any external attacker.
 
3587
     */
 
3588
    if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
 
3589
      /* There was no lowercase variable, try the uppercase version: */
 
3590
      Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
3237
3591
      prox=curl_getenv(proxy_env);
3238
 
 
3239
 
      /*
3240
 
       * We don't try the uppercase version of HTTP_PROXY because of
3241
 
       * security reasons:
3242
 
       *
3243
 
       * When curl is used in a webserver application
3244
 
       * environment (cgi or php), this environment variable can
3245
 
       * be controlled by the web server user by setting the
3246
 
       * http header 'Proxy:' to some value.
3247
 
       *
3248
 
       * This can cause 'internal' http/ftp requests to be
3249
 
       * arbitrarily redirected by any external attacker.
3250
 
       */
3251
 
      if(!prox && !strequal("http_proxy", proxy_env)) {
3252
 
        /* There was no lowercase variable, try the uppercase version: */
3253
 
        for(envp = proxy_env; *envp; envp++)
3254
 
          *envp = (char)toupper((int)*envp);
3255
 
        prox=curl_getenv(proxy_env);
3256
 
      }
3257
 
 
3258
 
      if(prox && *prox) { /* don't count "" strings */
3259
 
        proxy = prox; /* use this */
3260
 
      }
3261
 
      else {
3262
 
        proxy = curl_getenv("all_proxy"); /* default proxy to use */
3263
 
        if(!proxy)
3264
 
          proxy=curl_getenv("ALL_PROXY");
3265
 
      }
3266
 
 
3267
 
      if(proxy && *proxy) {
3268
 
        long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
3269
 
 
3270
 
        if(conn->proxytype == CURLPROXY_HTTP) {
3271
 
          /* force this connection's protocol to become HTTP */
3272
 
          conn->protocol = PROT_HTTP | bits;
3273
 
          conn->bits.proxy = conn->bits.httpproxy = TRUE;
3274
 
        }
3275
 
      }
3276
 
    } /* if(!nope) - it wasn't specified non-proxy */
3277
 
  } /* NO_PROXY wasn't specified or '*' */
 
3592
    }
 
3593
 
 
3594
    if(prox && *prox) { /* don't count "" strings */
 
3595
      proxy = prox; /* use this */
 
3596
    }
 
3597
    else {
 
3598
      proxy = curl_getenv("all_proxy"); /* default proxy to use */
 
3599
      if(!proxy)
 
3600
        proxy=curl_getenv("ALL_PROXY");
 
3601
    }
 
3602
  } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
 
3603
       non-proxy */
3278
3604
  if(no_proxy)
3279
3605
    free(no_proxy);
3280
3606
 
3286
3612
  return proxy;
3287
3613
}
3288
3614
 
3289
 
/* If this is supposed to use a proxy, we need to figure out the proxy
 
3615
/*
 
3616
 * If this is supposed to use a proxy, we need to figure out the proxy
3290
3617
 * host name, so that we can re-use an existing connection
3291
3618
 * that may exist registered to the same proxy host.
3292
3619
 * proxy will be freed before this function returns.
3320
3647
    proxypasswd[0] = 0;
3321
3648
 
3322
3649
    if(1 <= sscanf(proxyptr,
3323
 
                   "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
 
3650
                   "%" MAX_CURL_USER_LENGTH_TXT"[^:@]:"
3324
3651
                   "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
3325
3652
                   proxyuser, proxypasswd)) {
3326
3653
      CURLcode res = CURLE_OK;
3367
3694
  /* detect and extract RFC2732-style IPv6-addresses */
3368
3695
  if(*proxyptr == '[') {
3369
3696
    char *ptr = ++proxyptr; /* advance beyond the initial bracket */
3370
 
    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':')))
 
3697
    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') || (*ptr == '.')))
3371
3698
      ptr++;
3372
3699
    if(*ptr == ']') {
3373
3700
      /* yeps, it ended nicely with a bracket as well */
3374
 
      *ptr = 0;
3375
 
      portptr = ptr+1;
3376
 
    }
 
3701
      *ptr++ = 0;
 
3702
    } else
 
3703
      infof(data, "Invalid IPv6 address format\n");
 
3704
    portptr = ptr;
3377
3705
    /* Note that if this didn't end with a bracket, we still advanced the
3378
3706
     * proxyptr first, but I can't see anything wrong with that as no host
3379
3707
     * name nor a numeric can legally start with a bracket.
3412
3740
  return CURLE_OK;
3413
3741
}
3414
3742
 
3415
 
/* Extract the user and password from the authentication string */
 
3743
/*
 
3744
 * Extract the user and password from the authentication string
 
3745
 */
3416
3746
static CURLcode parse_proxy_auth(struct SessionHandle *data,
3417
3747
                                 struct connectdata *conn)
3418
3748
{
3419
3749
  char proxyuser[MAX_CURL_USER_LENGTH]="";
3420
3750
  char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
3421
3751
 
3422
 
  sscanf(data->set.str[STRING_PROXYUSERPWD],
3423
 
         "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3424
 
         "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3425
 
         proxyuser, proxypasswd);
 
3752
  if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
 
3753
    strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
 
3754
            MAX_CURL_USER_LENGTH);
 
3755
    proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
 
3756
  }
 
3757
  if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
 
3758
    strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
 
3759
            MAX_CURL_PASSWORD_LENGTH);
 
3760
    proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
 
3761
  }
3426
3762
 
3427
3763
  conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
3428
3764
  if(!conn->proxyuser)
3434
3770
 
3435
3771
  return CURLE_OK;
3436
3772
}
 
3773
#endif /* CURL_DISABLE_PROXY */
 
3774
 
 
3775
/*
 
3776
 *
 
3777
 * Parse a user name and password in the URL and strip it out of the host name
 
3778
 *
 
3779
 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
 
3780
 *         conn->host.name
 
3781
 *
 
3782
 * Outputs: (almost :- all currently undefined)
 
3783
 *          conn->bits.user_passwd  - non-zero if non-default passwords exist
 
3784
 *          user                    - non-zero length if defined
 
3785
 *          passwd                  -   ditto
 
3786
 *          conn->host.name         - remove user name and password
 
3787
 */
 
3788
static CURLcode parse_url_userpass(struct SessionHandle *data,
 
3789
                                   struct connectdata *conn,
 
3790
                                   char *user, char *passwd)
 
3791
{
 
3792
  /* At this point, we're hoping all the other special cases have
 
3793
   * been taken care of, so conn->host.name is at most
 
3794
   *    [user[:password]]@]hostname
 
3795
   *
 
3796
   * We need somewhere to put the embedded details, so do that first.
 
3797
   */
 
3798
 
 
3799
  user[0] =0;   /* to make everything well-defined */
 
3800
  passwd[0]=0;
 
3801
 
 
3802
  if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) {
 
3803
    /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
 
3804
     * possible user+password pair in a string like:
 
3805
     * ftp://user:password@ftp.my.site:8021/README */
 
3806
    char *ptr=strchr(conn->host.name, '@');
 
3807
    char *userpass = conn->host.name;
 
3808
    if(ptr != NULL) {
 
3809
      /* there's a user+password given here, to the left of the @ */
 
3810
 
 
3811
      conn->host.name = ++ptr;
 
3812
 
 
3813
      /* So the hostname is sane.  Only bother interpreting the
 
3814
       * results if we could care.  It could still be wasted
 
3815
       * work because it might be overtaken by the programmatically
 
3816
       * set user/passwd, but doing that first adds more cases here :-(
 
3817
       */
 
3818
 
 
3819
      if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
 
3820
        /* We could use the one in the URL */
 
3821
 
 
3822
        conn->bits.user_passwd = 1; /* enable user+password */
 
3823
 
 
3824
        if(*userpass != ':') {
 
3825
          /* the name is given, get user+password */
 
3826
          sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
 
3827
                 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
 
3828
                 user, passwd);
 
3829
        }
 
3830
        else
 
3831
          /* no name given, get the password only */
 
3832
          sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
 
3833
 
 
3834
        if(user[0]) {
 
3835
          char *newname=curl_easy_unescape(data, user, 0, NULL);
 
3836
          if(!newname)
 
3837
            return CURLE_OUT_OF_MEMORY;
 
3838
          if(strlen(newname) < MAX_CURL_USER_LENGTH)
 
3839
            strcpy(user, newname);
 
3840
 
 
3841
          /* if the new name is longer than accepted, then just use
 
3842
             the unconverted name, it'll be wrong but what the heck */
 
3843
          free(newname);
 
3844
        }
 
3845
        if(passwd[0]) {
 
3846
          /* we have a password found in the URL, decode it! */
 
3847
          char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
 
3848
          if(!newpasswd)
 
3849
            return CURLE_OUT_OF_MEMORY;
 
3850
          if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
 
3851
            strcpy(passwd, newpasswd);
 
3852
 
 
3853
          free(newpasswd);
 
3854
        }
 
3855
      }
 
3856
    }
 
3857
  }
 
3858
  return CURLE_OK;
 
3859
}
 
3860
 
 
3861
/*************************************************************
 
3862
 * Figure out the remote port number and fix it in the URL
 
3863
 *
 
3864
 * No matter if we use a proxy or not, we have to figure out the remote
 
3865
 * port number of various reasons.
 
3866
 *
 
3867
 * To be able to detect port number flawlessly, we must not confuse them
 
3868
 * IPv6-specified addresses in the [0::1] style. (RFC2732)
 
3869
 *
 
3870
 * The conn->host.name is currently [user:passwd@]host[:port] where host
 
3871
 * could be a hostname, IPv4 address or IPv6 address.
 
3872
 *
 
3873
 * The port number embedded in the URL is replaced, if necessary.
 
3874
 *************************************************************/
 
3875
static CURLcode parse_remote_port(struct SessionHandle *data,
 
3876
                                  struct connectdata *conn)
 
3877
{
 
3878
  char *portptr;
 
3879
  char endbracket;
 
3880
 
 
3881
  /* Note that at this point, the IPv6 address cannot contain any scope
 
3882
     suffix as that has already been removed in the ParseURLAndFillConnection()
 
3883
     function */
 
3884
  if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
 
3885
                  &endbracket)) &&
 
3886
     (']' == endbracket)) {
 
3887
    /* this is a RFC2732-style specified IP-address */
 
3888
    conn->bits.ipv6_ip = TRUE;
 
3889
 
 
3890
    conn->host.name++; /* skip over the starting bracket */
 
3891
    portptr = strchr(conn->host.name, ']');
 
3892
    *portptr++ = 0; /* zero terminate, killing the bracket */
 
3893
    if(':' != *portptr)
 
3894
      portptr = NULL; /* no port number available */
 
3895
  }
 
3896
  else
 
3897
    portptr = strrchr(conn->host.name, ':');
 
3898
 
 
3899
  if(data->set.use_port && data->state.allow_port) {
 
3900
    /* if set, we use this and ignore the port possibly given in the URL */
 
3901
    conn->remote_port = (unsigned short)data->set.use_port;
 
3902
    if(portptr)
 
3903
      *portptr = '\0'; /* cut off the name there anyway - if there was a port
 
3904
                      number - since the port number is to be ignored! */
 
3905
    if(conn->bits.httpproxy) {
 
3906
      /* we need to create new URL with the new port number */
 
3907
      char *url;
 
3908
      bool isftp = (bool)(Curl_raw_equal("ftp", conn->protostr) ||
 
3909
                          Curl_raw_equal("ftps", conn->protostr));
 
3910
 
 
3911
      /*
 
3912
       * This synthesized URL isn't always right--suffixes like ;type=A
 
3913
       * are stripped off. It would be better to work directly from the
 
3914
       * original URL and simply replace the port part of it.
 
3915
       */
 
3916
      url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr,
 
3917
             conn->bits.ipv6_ip?"[":"", conn->host.name,
 
3918
             conn->bits.ipv6_ip?"]":"", conn->remote_port,
 
3919
             isftp?"/":"", data->state.path);
 
3920
      if(!url)
 
3921
        return CURLE_OUT_OF_MEMORY;
 
3922
 
 
3923
      if(data->change.url_alloc)
 
3924
        free(data->change.url);
 
3925
 
 
3926
      data->change.url = url;
 
3927
      data->change.url_alloc = TRUE;
 
3928
    }
 
3929
  }
 
3930
  else if(portptr) {
 
3931
    /* no CURLOPT_PORT given, extract the one from the URL */
 
3932
 
 
3933
    char *rest;
 
3934
    unsigned long port;
 
3935
 
 
3936
    port=strtoul(portptr+1, &rest, 10);  /* Port number must be decimal */
 
3937
 
 
3938
    if(rest != (portptr+1) && *rest == '\0') {
 
3939
      /* The colon really did have only digits after it,
 
3940
       * so it is either a port number or a mistake */
 
3941
 
 
3942
      if(port > 0xffff) {   /* Single unix standard says port numbers are
 
3943
                              * 16 bits long */
 
3944
        failf(data, "Port number too large: %lu", port);
 
3945
        return CURLE_URL_MALFORMAT;
 
3946
      }
 
3947
 
 
3948
      *portptr = '\0'; /* cut off the name there */
 
3949
      conn->remote_port = (unsigned short)port;
 
3950
    }
 
3951
  }
 
3952
  return CURLE_OK;
 
3953
}
 
3954
 
 
3955
/*
 
3956
 * Override a user name and password from the URL with that in the
 
3957
 * CURLOPT_USERPWD option or a .netrc file, if applicable.
 
3958
 */
 
3959
static void override_userpass(struct SessionHandle *data,
 
3960
                              struct connectdata *conn,
 
3961
                              char *user, char *passwd)
 
3962
{
 
3963
  if(data->set.str[STRING_USERNAME] != NULL) {
 
3964
    strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
 
3965
    user[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
 
3966
  }
 
3967
  if(data->set.str[STRING_PASSWORD] != NULL) {
 
3968
    strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
 
3969
    passwd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
 
3970
  }
 
3971
 
 
3972
  conn->bits.netrc = FALSE;
 
3973
  if(data->set.use_netrc != CURL_NETRC_IGNORED) {
 
3974
    if(Curl_parsenetrc(conn->host.name,
 
3975
                       user, passwd,
 
3976
                       data->set.str[STRING_NETRC_FILE])) {
 
3977
      infof(data, "Couldn't find host %s in the "
 
3978
            DOT_CHAR "netrc file; using defaults\n",
 
3979
            conn->host.name);
 
3980
    }
 
3981
    else {
 
3982
      /* set bits.netrc TRUE to remember that we got the name from a .netrc
 
3983
         file, so that it is safe to use even if we followed a Location: to a
 
3984
         different host or similar. */
 
3985
      conn->bits.netrc = TRUE;
 
3986
 
 
3987
      conn->bits.user_passwd = 1; /* enable user+password */
 
3988
    }
 
3989
  }
 
3990
}
 
3991
 
 
3992
/*
 
3993
 * Set password so it's available in the connection.
 
3994
 */
 
3995
static CURLcode set_userpass(struct connectdata *conn,
 
3996
                             const char *user, const char *passwd)
 
3997
{
 
3998
  /* If our protocol needs a password and we have none, use the defaults */
 
3999
  if( (conn->protocol & PROT_FTP) &&
 
4000
       !conn->bits.user_passwd) {
 
4001
 
 
4002
    conn->user = strdup(CURL_DEFAULT_USER);
 
4003
    conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
 
4004
    /* This is the default password, so DON'T set conn->bits.user_passwd */
 
4005
  }
 
4006
  else {
 
4007
    /* store user + password, zero-length if not set */
 
4008
    conn->user = strdup(user);
 
4009
    conn->passwd = strdup(passwd);
 
4010
  }
 
4011
  if(!conn->user || !conn->passwd)
 
4012
    return CURLE_OUT_OF_MEMORY;
 
4013
 
 
4014
  return CURLE_OK;
 
4015
}
 
4016
 
 
4017
/*************************************************************
 
4018
 * Resolve the address of the server or proxy
 
4019
 *************************************************************/
 
4020
static CURLcode resolve_server(struct SessionHandle *data,
 
4021
                               struct connectdata *conn,
 
4022
                               struct Curl_dns_entry **addr,
 
4023
                               bool *async)
 
4024
{
 
4025
  CURLcode result=CURLE_OK;
 
4026
  long shortest = 0; /* default to no timeout */
 
4027
 
 
4028
  /*************************************************************
 
4029
   * Set timeout if that is being used
 
4030
   *************************************************************/
 
4031
  if(data->set.timeout || data->set.connecttimeout) {
 
4032
 
 
4033
    /* We set the timeout on the name resolving phase first, separately from
 
4034
     * the download/upload part to allow a maximum time on everything. This is
 
4035
     * a signal-based timeout, why it won't work and shouldn't be used in
 
4036
     * multi-threaded environments. */
 
4037
 
 
4038
    shortest = data->set.timeout; /* default to this timeout value */
 
4039
    if(shortest && data->set.connecttimeout &&
 
4040
       (data->set.connecttimeout < shortest))
 
4041
      /* if both are set, pick the shortest */
 
4042
      shortest = data->set.connecttimeout;
 
4043
    else if(!shortest)
 
4044
      /* if timeout is not set, use the connect timeout */
 
4045
      shortest = data->set.connecttimeout;
 
4046
  /* We can expect the conn->created time to be "now", as that was just
 
4047
     recently set in the beginning of this function and nothing slow
 
4048
     has been done since then until now. */
 
4049
  }
 
4050
 
 
4051
  /*************************************************************
 
4052
   * Resolve the name of the server or proxy
 
4053
   *************************************************************/
 
4054
  if(conn->bits.reuse) {
 
4055
    /* re-used connection, no resolving is necessary */
 
4056
    *addr = NULL;
 
4057
    /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
 
4058
 
 
4059
    if(conn->bits.proxy)
 
4060
      fix_hostname(data, conn, &conn->host);
 
4061
  }
 
4062
  else {
 
4063
    /* this is a fresh connect */
 
4064
    int rc;
 
4065
    struct Curl_dns_entry *hostaddr;
 
4066
 
 
4067
    /* set a pointer to the hostname we display */
 
4068
    fix_hostname(data, conn, &conn->host);
 
4069
 
 
4070
    if(!conn->proxy.name || !*conn->proxy.name) {
 
4071
      /* If not connecting via a proxy, extract the port from the URL, if it is
 
4072
       * there, thus overriding any defaults that might have been set above. */
 
4073
      conn->port =  conn->remote_port; /* it is the same port */
 
4074
 
 
4075
      /* Resolve target host right on */
 
4076
      rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
 
4077
                               &hostaddr, shortest);
 
4078
      if(rc == CURLRESOLV_PENDING)
 
4079
        *async = TRUE;
 
4080
 
 
4081
      else if (rc == CURLRESOLV_TIMEDOUT)
 
4082
        result = CURLE_OPERATION_TIMEDOUT;
 
4083
 
 
4084
      else if(!hostaddr) {
 
4085
        failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
 
4086
        result =  CURLE_COULDNT_RESOLVE_HOST;
 
4087
        /* don't return yet, we need to clean up the timeout first */
 
4088
      }
 
4089
    }
 
4090
    else {
 
4091
      /* This is a proxy that hasn't been resolved yet. */
 
4092
 
 
4093
      /* IDN-fix the proxy name */
 
4094
      fix_hostname(data, conn, &conn->proxy);
 
4095
 
 
4096
      /* resolve proxy */
 
4097
      rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
 
4098
                               &hostaddr, shortest);
 
4099
 
 
4100
      if(rc == CURLRESOLV_PENDING)
 
4101
        *async = TRUE;
 
4102
 
 
4103
      else if (rc == CURLRESOLV_TIMEDOUT)
 
4104
        result = CURLE_OPERATION_TIMEDOUT;
 
4105
 
 
4106
      else if(!hostaddr) {
 
4107
        failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
 
4108
        result = CURLE_COULDNT_RESOLVE_PROXY;
 
4109
        /* don't return yet, we need to clean up the timeout first */
 
4110
      }
 
4111
    }
 
4112
    *addr = hostaddr;
 
4113
  }
 
4114
 
 
4115
  return result;
 
4116
}
 
4117
 
 
4118
/*
 
4119
 * Cleanup the connection just allocated before we can move along and use the
 
4120
 * previously existing one.  All relevant data is copied over and old_conn is
 
4121
 * ready for freeing once this function returns.
 
4122
 */
 
4123
static void reuse_conn(struct connectdata *old_conn,
 
4124
                       struct connectdata *conn)
 
4125
{
 
4126
  if(old_conn->proxy.rawalloc)
 
4127
    free(old_conn->proxy.rawalloc);
 
4128
 
 
4129
  /* free the SSL config struct from this connection struct as this was
 
4130
     allocated in vain and is targeted for destruction */
 
4131
  Curl_free_ssl_config(&old_conn->ssl_config);
 
4132
 
 
4133
  conn->data = old_conn->data;
 
4134
 
 
4135
  /* get the user+password information from the old_conn struct since it may
 
4136
   * be new for this request even when we re-use an existing connection */
 
4137
  conn->bits.user_passwd = old_conn->bits.user_passwd;
 
4138
  if(conn->bits.user_passwd) {
 
4139
    /* use the new user name and password though */
 
4140
    Curl_safefree(conn->user);
 
4141
    Curl_safefree(conn->passwd);
 
4142
    conn->user = old_conn->user;
 
4143
    conn->passwd = old_conn->passwd;
 
4144
    old_conn->user = NULL;
 
4145
    old_conn->passwd = NULL;
 
4146
  }
 
4147
 
 
4148
  conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
 
4149
  if(conn->bits.proxy_user_passwd) {
 
4150
    /* use the new proxy user name and proxy password though */
 
4151
    Curl_safefree(conn->proxyuser);
 
4152
    Curl_safefree(conn->proxypasswd);
 
4153
    conn->proxyuser = old_conn->proxyuser;
 
4154
    conn->proxypasswd = old_conn->proxypasswd;
 
4155
    old_conn->proxyuser = NULL;
 
4156
    old_conn->proxypasswd = NULL;
 
4157
  }
 
4158
 
 
4159
  /* host can change, when doing keepalive with a proxy ! */
 
4160
  if(conn->bits.proxy) {
 
4161
    free(conn->host.rawalloc);
 
4162
    conn->host=old_conn->host;
 
4163
  }
 
4164
  else
 
4165
    free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
 
4166
 
 
4167
  /* re-use init */
 
4168
  conn->bits.reuse = TRUE; /* yes, we're re-using here */
 
4169
 
 
4170
  Curl_safefree(old_conn->user);
 
4171
  Curl_safefree(old_conn->passwd);
 
4172
  Curl_safefree(old_conn->proxyuser);
 
4173
  Curl_safefree(old_conn->proxypasswd);
 
4174
  Curl_llist_destroy(old_conn->send_pipe, NULL);
 
4175
  Curl_llist_destroy(old_conn->recv_pipe, NULL);
 
4176
  Curl_llist_destroy(old_conn->pend_pipe, NULL);
 
4177
  Curl_safefree(old_conn->master_buffer);
 
4178
}
3437
4179
 
3438
4180
/**
3439
 
 * CreateConnection() sets up a new connectdata struct, or re-uses an already
 
4181
 * create_conn() sets up a new connectdata struct, or re-uses an already
3440
4182
 * existing one, and resolves host name.
3441
4183
 *
3442
4184
 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
3449
4191
 *        connection is re-used it will be NULL.
3450
4192
 * @param async is set TRUE/FALSE depending on the nature of this lookup
3451
4193
 * @return CURLcode
3452
 
 * @see SetupConnection()
 
4194
 * @see setup_conn()
3453
4195
 *
3454
4196
 * *NOTE* this function assigns the conn->data pointer!
3455
4197
 */
3456
4198
 
3457
 
static CURLcode CreateConnection(struct SessionHandle *data,
3458
 
                                 struct connectdata **in_connect,
3459
 
                                 struct Curl_dns_entry **addr,
3460
 
                                 bool *async)
 
4199
static CURLcode create_conn(struct SessionHandle *data,
 
4200
                            struct connectdata **in_connect,
 
4201
                            struct Curl_dns_entry **addr,
 
4202
                            bool *async)
3461
4203
{
3462
 
 
3463
 
  char *tmp;
3464
4204
  CURLcode result=CURLE_OK;
3465
4205
  struct connectdata *conn;
3466
4206
  struct connectdata *conn_temp = NULL;
3467
4207
  size_t urllen;
3468
 
  struct Curl_dns_entry *hostaddr;
3469
 
#if defined(HAVE_ALARM) && !defined(USE_ARES)
3470
 
  unsigned int prev_alarm=0;
3471
 
#endif
3472
 
  char endbracket;
3473
4208
  char user[MAX_CURL_USER_LENGTH];
3474
4209
  char passwd[MAX_CURL_PASSWORD_LENGTH];
3475
 
  int rc;
3476
4210
  bool reuse;
3477
4211
  char *proxy = NULL;
3478
4212
 
3479
 
#ifndef USE_ARES
3480
 
#ifdef SIGALRM
3481
 
#ifdef HAVE_SIGACTION
3482
 
  struct sigaction keep_sigact;   /* store the old struct here */
3483
 
  bool keep_copysig=FALSE;        /* did copy it? */
3484
 
#else
3485
 
#ifdef HAVE_SIGNAL
3486
 
  void (*keep_sigact)(int);       /* store the old handler here */
3487
 
#endif /* HAVE_SIGNAL */
3488
 
#endif /* HAVE_SIGACTION */
3489
 
#endif /* SIGALRM */
3490
 
#endif /* USE_ARES */
3491
 
 
3492
4213
  *addr = NULL; /* nothing yet */
3493
4214
  *async = FALSE;
3494
4215
 
3504
4225
     to not have to modify everything at once, we allocate a temporary
3505
4226
     connection data struct and fill in for comparison purposes. */
3506
4227
 
3507
 
  conn = (struct connectdata *)calloc(1, sizeof(struct connectdata));
3508
 
  if(!conn) {
3509
 
    *in_connect = NULL; /* clear the pointer */
3510
 
    return CURLE_OUT_OF_MEMORY;
3511
 
  }
 
4228
  conn = allocate_conn();
 
4229
 
3512
4230
  /* We must set the return variable as soon as possible, so that our
3513
4231
     parent can cleanup any possible allocs we may have done before
3514
4232
     any failure */
3515
4233
  *in_connect = conn;
3516
4234
 
3517
 
  conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
3518
 
                                           already from start to avoid NULL
3519
 
                                           situations and checks */
3520
 
 
3521
 
  /* and we setup a few fields in case we end up actually using this struct */
 
4235
  if(!conn)
 
4236
    return CURLE_OUT_OF_MEMORY;
3522
4237
 
3523
4238
  conn->data = data; /* Setup the association between this connection
3524
4239
                        and the SessionHandle */
3525
4240
 
3526
 
  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
3527
 
  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3528
 
  conn->connectindex = -1;    /* no index */
3529
 
 
3530
4241
  conn->proxytype = data->set.proxytype; /* type */
 
4242
 
 
4243
#ifdef CURL_DISABLE_PROXY
 
4244
 
 
4245
  conn->bits.proxy = FALSE;
 
4246
  conn->bits.httpproxy = FALSE;
 
4247
  conn->bits.proxy_user_passwd = FALSE;
 
4248
  conn->bits.tunnel_proxy = FALSE;
 
4249
 
 
4250
#else /* CURL_DISABLE_PROXY */
 
4251
 
3531
4252
  conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] &&
3532
4253
                            *data->set.str[STRING_PROXY]);
3533
 
  conn->bits.httpproxy = (bool)(conn->bits.proxy
3534
 
                                && (conn->proxytype == CURLPROXY_HTTP));
3535
 
 
3536
 
 
3537
 
  /* Default protocol-independent behavior doesn't support persistent
3538
 
     connections, so we set this to force-close. Protocols that support
3539
 
     this need to set this to FALSE in their "curl_do" functions. */
3540
 
  conn->bits.close = TRUE;
3541
 
 
3542
 
  conn->readchannel_inuse = FALSE;
3543
 
  conn->writechannel_inuse = FALSE;
3544
 
 
3545
 
  conn->read_pos = 0;
3546
 
  conn->buf_len = 0;
3547
 
 
3548
 
  /* Store creation time to help future close decision making */
3549
 
  conn->created = Curl_tvnow();
3550
 
 
3551
 
  conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]);
3552
 
  conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]);
 
4254
  conn->bits.httpproxy = (bool)(conn->bits.proxy &&
 
4255
                                (conn->proxytype == CURLPROXY_HTTP ||
 
4256
                                 conn->proxytype == CURLPROXY_HTTP_1_0));
 
4257
  conn->bits.proxy_user_passwd =
 
4258
    (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]);
3553
4259
  conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
 
4260
 
 
4261
#endif /* CURL_DISABLE_PROXY */
 
4262
 
 
4263
  conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]);
3554
4264
  conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
3555
4265
  conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
3556
4266
 
3582
4292
  if(urllen < LEAST_PATH_ALLOC)
3583
4293
    urllen=LEAST_PATH_ALLOC;
3584
4294
 
3585
 
  /* Free the old buffer */
3586
 
  Curl_safefree(data->state.pathbuffer);
3587
 
 
3588
4295
  /*
3589
4296
   * We malloc() the buffers below urllen+2 to make room for to possibilities:
3590
4297
   * 1 - an extra terminating zero
3591
4298
   * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
3592
4299
   */
3593
4300
 
3594
 
  data->state.pathbuffer=(char *)malloc(urllen+2);
 
4301
  Curl_safefree(data->state.pathbuffer);
 
4302
  data->state.pathbuffer = malloc(urllen+2);
3595
4303
  if(NULL == data->state.pathbuffer)
3596
4304
    return CURLE_OUT_OF_MEMORY; /* really bad error */
3597
4305
  data->state.path = data->state.pathbuffer;
3598
4306
 
3599
 
  conn->host.rawalloc=(char *)malloc(urllen+2);
 
4307
  conn->host.rawalloc = malloc(urllen+2);
3600
4308
  if(NULL == conn->host.rawalloc)
3601
4309
    return CURLE_OUT_OF_MEMORY;
3602
4310
 
3609
4317
  }
3610
4318
 
3611
4319
  /*************************************************************
3612
 
   * Take care of proxy authentication stuff
3613
 
   *************************************************************/
3614
 
  if(conn->bits.proxy_user_passwd) {
3615
 
    result = parse_proxy_auth(data, conn);
3616
 
    if(result != CURLE_OK)
3617
 
        return result;
3618
 
  }
3619
 
 
3620
 
  /*************************************************************
3621
 
   * Detect what (if any) proxy to use
3622
 
   *************************************************************/
3623
 
  if(data->set.str[STRING_PROXY]) {
3624
 
    proxy = strdup(data->set.str[STRING_PROXY]);
3625
 
    /* if global proxy is set, this is it */
3626
 
    if(NULL == proxy) {
3627
 
      failf(data, "memory shortage");
3628
 
      return CURLE_OUT_OF_MEMORY;
3629
 
    }
3630
 
  }
3631
 
 
3632
 
  if(!proxy)
3633
 
    proxy = detect_proxy(conn);
3634
 
  if(proxy && !*proxy) {
3635
 
    free(proxy);  /* Don't bother with an empty proxy string */
3636
 
    proxy = NULL;
3637
 
  }
3638
 
  /* proxy must be freed later unless NULL */
3639
 
 
3640
 
  /*************************************************************
3641
4320
   * No protocol part in URL was used, add it!
3642
4321
   *************************************************************/
3643
4322
  if(conn->protocol&PROT_MISSING) {
3667
4346
    return result;
3668
4347
  }
3669
4348
 
3670
 
 
 
4349
  /*************************************************************
 
4350
   * Parse a user name and password in the URL and strip it out
 
4351
   * of the host name
 
4352
   *************************************************************/
 
4353
  result = parse_url_userpass(data, conn, user, passwd);
 
4354
  if(result != CURLE_OK)
 
4355
    return result;
 
4356
 
 
4357
#ifndef CURL_DISABLE_PROXY
 
4358
  /*************************************************************
 
4359
   * Extract the user and password from the authentication string
 
4360
   *************************************************************/
 
4361
  if(conn->bits.proxy_user_passwd) {
 
4362
    result = parse_proxy_auth(data, conn);
 
4363
    if(result != CURLE_OK)
 
4364
        return result;
 
4365
  }
 
4366
 
 
4367
  /*************************************************************
 
4368
   * Detect what (if any) proxy to use
 
4369
   *************************************************************/
 
4370
  if(data->set.str[STRING_PROXY]) {
 
4371
    proxy = strdup(data->set.str[STRING_PROXY]);
 
4372
    /* if global proxy is set, this is it */
 
4373
    if(NULL == proxy) {
 
4374
      failf(data, "memory shortage");
 
4375
      return CURLE_OUT_OF_MEMORY;
 
4376
    }
 
4377
  }
 
4378
 
 
4379
  if(!proxy)
 
4380
    proxy = detect_proxy(conn);
 
4381
  else if(data->set.str[STRING_NOPROXY]) {
 
4382
    if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
 
4383
      free(proxy);  /* proxy is in exception list */
 
4384
      proxy = NULL;
 
4385
    }
 
4386
  }
 
4387
  if(proxy && !*proxy) {
 
4388
    free(proxy);  /* Don't bother with an empty proxy string */
 
4389
    proxy = NULL;
 
4390
  }
 
4391
  /* proxy must be freed later unless NULL */
 
4392
  if(proxy && *proxy) {
 
4393
    long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
 
4394
 
 
4395
    if((conn->proxytype == CURLPROXY_HTTP) ||
 
4396
       (conn->proxytype == CURLPROXY_HTTP_1_0)) {
 
4397
      /* force this connection's protocol to become HTTP */
 
4398
      conn->protocol = PROT_HTTP | bits;
 
4399
      conn->bits.httpproxy = TRUE;
 
4400
    }
 
4401
    conn->bits.proxy = TRUE;
 
4402
  }
 
4403
  else {
 
4404
      /* we aren't using the proxy after all... */
 
4405
      conn->bits.proxy = FALSE;
 
4406
      conn->bits.httpproxy = FALSE;
 
4407
      conn->bits.proxy_user_passwd = FALSE;
 
4408
      conn->bits.tunnel_proxy = FALSE;
 
4409
  }
 
4410
#endif /* CURL_DISABLE_PROXY */
 
4411
 
 
4412
#ifndef CURL_DISABLE_PROXY
3671
4413
  /***********************************************************************
3672
4414
   * If this is supposed to use a proxy, we need to figure out the proxy
3673
4415
   * host name, so that we can re-use an existing connection
3680
4422
    if(result != CURLE_OK)
3681
4423
      return result;
3682
4424
  }
3683
 
 
 
4425
#endif /* CURL_DISABLE_PROXY */
3684
4426
 
3685
4427
  /***********************************************************************
3686
4428
   * file: is a special case in that it doesn't need a network connection
3700
4442
 
3701
4443
      ConnectionStore(data, conn);
3702
4444
 
 
4445
      /*
 
4446
       * Setup whatever necessary for a resumed transfer
 
4447
       */
3703
4448
      result = setup_range(data);
3704
4449
      if(result) {
3705
4450
        DEBUGASSERT(conn->handler->done);
3725
4470
    conn->bits.tunnel_proxy = TRUE;
3726
4471
 
3727
4472
  /*************************************************************
3728
 
   * Take care of user and password authentication stuff
 
4473
   * Figure out the remote port number and fix it in the URL
3729
4474
   *************************************************************/
3730
 
 
3731
 
  /*
3732
 
   * Inputs: data->set.userpwd   (CURLOPT_USERPWD)
3733
 
   *         data->set.fpasswd   (CURLOPT_PASSWDFUNCTION)
3734
 
   *         data->set.use_netrc (CURLOPT_NETRC)
3735
 
   *         conn->host.name
3736
 
   *         netrc file
3737
 
   *         hard-coded defaults
3738
 
   *
3739
 
   * Outputs: (almost :- all currently undefined)
3740
 
   *          conn->bits.user_passwd  - non-zero if non-default passwords exist
3741
 
   *          conn->user              - non-zero length if defined
3742
 
   *          conn->passwd            -   ditto
3743
 
   *          conn->host.name          - remove user name and password
3744
 
   */
3745
 
 
3746
 
  /* At this point, we're hoping all the other special cases have
3747
 
   * been taken care of, so conn->host.name is at most
3748
 
   *    [user[:password]]@]hostname
3749
 
   *
3750
 
   * We need somewhere to put the embedded details, so do that first.
3751
 
   */
3752
 
 
3753
 
  user[0] =0;   /* to make everything well-defined */
3754
 
  passwd[0]=0;
3755
 
 
3756
 
  if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) {
3757
 
    /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
3758
 
     * possible user+password pair in a string like:
3759
 
     * ftp://user:password@ftp.my.site:8021/README */
3760
 
    char *ptr=strchr(conn->host.name, '@');
3761
 
    char *userpass = conn->host.name;
3762
 
    if(ptr != NULL) {
3763
 
      /* there's a user+password given here, to the left of the @ */
3764
 
 
3765
 
      conn->host.name = ++ptr;
3766
 
 
3767
 
      /* So the hostname is sane.  Only bother interpreting the
3768
 
       * results if we could care.  It could still be wasted
3769
 
       * work because it might be overtaken by the programmatically
3770
 
       * set user/passwd, but doing that first adds more cases here :-(
3771
 
       */
3772
 
 
3773
 
      if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
3774
 
        /* We could use the one in the URL */
3775
 
 
3776
 
        conn->bits.user_passwd = 1; /* enable user+password */
3777
 
 
3778
 
        if(*userpass != ':') {
3779
 
          /* the name is given, get user+password */
3780
 
          sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
3781
 
                 "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
3782
 
                 user, passwd);
3783
 
        }
3784
 
        else
3785
 
          /* no name given, get the password only */
3786
 
          sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
3787
 
 
3788
 
        if(user[0]) {
3789
 
          char *newname=curl_easy_unescape(data, user, 0, NULL);
3790
 
          if(!newname)
3791
 
            return CURLE_OUT_OF_MEMORY;
3792
 
          if(strlen(newname) < sizeof(user))
3793
 
            strcpy(user, newname);
3794
 
 
3795
 
          /* if the new name is longer than accepted, then just use
3796
 
             the unconverted name, it'll be wrong but what the heck */
3797
 
          free(newname);
3798
 
        }
3799
 
        if(passwd[0]) {
3800
 
          /* we have a password found in the URL, decode it! */
3801
 
          char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
3802
 
          if(!newpasswd)
3803
 
            return CURLE_OUT_OF_MEMORY;
3804
 
          if(strlen(newpasswd) < sizeof(passwd))
3805
 
            strcpy(passwd, newpasswd);
3806
 
 
3807
 
          free(newpasswd);
3808
 
        }
3809
 
      }
3810
 
    }
3811
 
  }
 
4475
  result = parse_remote_port(data, conn);
 
4476
  if(result != CURLE_OK)
 
4477
    return result;
3812
4478
 
3813
4479
  /*************************************************************
3814
 
   * Figure out the remote port number
3815
 
   *
3816
 
   * No matter if we use a proxy or not, we have to figure out the remote
3817
 
   * port number of various reasons.
3818
 
   *
3819
 
   * To be able to detect port number flawlessly, we must not confuse them
3820
 
   * IPv6-specified addresses in the [0::1] style. (RFC2732)
3821
 
   *
3822
 
   * The conn->host.name is currently [user:passwd@]host[:port] where host
3823
 
   * could be a hostname, IPv4 address or IPv6 address.
 
4480
   * Check for an overridden user name and password, then set it
 
4481
   * for use
3824
4482
   *************************************************************/
3825
 
  if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
3826
 
     (']' == endbracket)) {
3827
 
    /* this is a RFC2732-style specified IP-address */
3828
 
    conn->bits.ipv6_ip = TRUE;
3829
 
 
3830
 
    conn->host.name++; /* pass the starting bracket */
3831
 
    tmp = strchr(conn->host.name, ']');
3832
 
    *tmp = 0; /* zero terminate */
3833
 
    tmp++; /* pass the ending bracket */
3834
 
    if(':' != *tmp)
3835
 
      tmp = NULL; /* no port number available */
3836
 
  }
3837
 
  else
3838
 
    tmp = strrchr(conn->host.name, ':');
3839
 
 
3840
 
  if(data->set.use_port && data->state.allow_port) {
3841
 
    /* if set, we use this and ignore the port possibly given in the URL */
3842
 
    conn->remote_port = (unsigned short)data->set.use_port;
3843
 
    if(tmp)
3844
 
      *tmp = '\0'; /* cut off the name there anyway - if there was a port
3845
 
                      number - since the port number is to be ignored! */
3846
 
    if(conn->bits.httpproxy) {
3847
 
      /* we need to create new URL with the new port number */
3848
 
      char *url;
3849
 
 
3850
 
      url = aprintf("%s://%s:%d%s", conn->protostr, conn->host.name,
3851
 
                    conn->remote_port, data->state.path);
3852
 
      if(!url)
3853
 
        return CURLE_OUT_OF_MEMORY;
3854
 
 
3855
 
      if(data->change.url_alloc)
3856
 
        free(data->change.url);
3857
 
 
3858
 
      data->change.url = url;
3859
 
      data->change.url_alloc = TRUE;
3860
 
    }
3861
 
  }
3862
 
  else if(tmp) {
3863
 
    /* no CURLOPT_PORT given, extract the one from the URL */
3864
 
 
3865
 
    char *rest;
3866
 
    unsigned long port;
3867
 
 
3868
 
    port=strtoul(tmp+1, &rest, 10);  /* Port number must be decimal */
3869
 
 
3870
 
    if(rest != (tmp+1) && *rest == '\0') {
3871
 
      /* The colon really did have only digits after it,
3872
 
       * so it is either a port number or a mistake */
3873
 
 
3874
 
      if(port > 0xffff) {   /* Single unix standard says port numbers are
3875
 
                              * 16 bits long */
3876
 
        failf(data, "Port number too large: %lu", port);
3877
 
        return CURLE_URL_MALFORMAT;
3878
 
      }
3879
 
 
3880
 
      *tmp = '\0'; /* cut off the name there */
3881
 
      conn->remote_port = (unsigned short)port;
3882
 
    }
3883
 
  }
3884
 
 
3885
 
  /* Programmatically set password:
3886
 
   *   - always applies, if available
3887
 
   *   - takes precedence over the values we just set above
3888
 
   * so scribble it over the top.
3889
 
   * User-supplied passwords are assumed not to need unescaping.
3890
 
   *
3891
 
   * user_password is set in "inherit initial knowledge' above,
3892
 
   * so it doesn't have to be set in this block
3893
 
   */
3894
 
  if(data->set.str[STRING_USERPWD] != NULL) {
3895
 
    /* the name is given, get user+password */
3896
 
    sscanf(data->set.str[STRING_USERPWD],
3897
 
           "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3898
 
           "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3899
 
           user, passwd);
3900
 
  }
3901
 
 
3902
 
  conn->bits.netrc = FALSE;
3903
 
  if(data->set.use_netrc != CURL_NETRC_IGNORED) {
3904
 
    if(Curl_parsenetrc(conn->host.name,
3905
 
                       user, passwd,
3906
 
                       data->set.str[STRING_NETRC_FILE])) {
3907
 
      infof(data, "Couldn't find host %s in the " DOT_CHAR
3908
 
            "netrc file, using defaults\n",
3909
 
            conn->host.name);
3910
 
    }
3911
 
    else {
3912
 
      /* set bits.netrc TRUE to remember that we got the name from a .netrc
3913
 
         file, so that it is safe to use even if we followed a Location: to a
3914
 
         different host or similar. */
3915
 
      conn->bits.netrc = TRUE;
3916
 
 
3917
 
      conn->bits.user_passwd = 1; /* enable user+password */
3918
 
    }
3919
 
  }
3920
 
 
3921
 
  /* If our protocol needs a password and we have none, use the defaults */
3922
 
  if( (conn->protocol & PROT_FTP) &&
3923
 
       !conn->bits.user_passwd) {
3924
 
 
3925
 
    conn->user = strdup(CURL_DEFAULT_USER);
3926
 
    conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3927
 
    /* This is the default password, so DON'T set conn->bits.user_passwd */
3928
 
  }
3929
 
  else {
3930
 
    /* store user + password, zero-length if not set */
3931
 
    conn->user = strdup(user);
3932
 
    conn->passwd = strdup(passwd);
3933
 
  }
3934
 
  if(!conn->user || !conn->passwd)
3935
 
    return CURLE_OUT_OF_MEMORY;
 
4483
  override_userpass(data, conn, user, passwd);
 
4484
  result = set_userpass(conn, user, passwd);
 
4485
  if(result != CURLE_OK)
 
4486
    return result;
3936
4487
 
3937
4488
  /*************************************************************
3938
4489
   * Check the current list of connections to see if we can
3951
4502
  */
3952
4503
  data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
3953
4504
  data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
 
4505
  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
 
4506
  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
3954
4507
  data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
3955
4508
  data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
3956
4509
  data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
3974
4527
     * just allocated before we can move along and use the previously
3975
4528
     * existing one.
3976
4529
     */
3977
 
    struct connectdata *old_conn = conn;
3978
 
 
3979
 
    if(old_conn->proxy.rawalloc)
3980
 
      free(old_conn->proxy.rawalloc);
3981
 
 
3982
 
    /* free the SSL config struct from this connection struct as this was
3983
 
       allocated in vain and is targeted for destruction */
3984
 
    Curl_free_ssl_config(&conn->ssl_config);
3985
 
 
3986
 
    conn = conn_temp;        /* use this connection from now on */
3987
 
 
3988
 
    conn->data = old_conn->data;
3989
 
 
3990
 
    /* get the user+password information from the old_conn struct since it may
3991
 
     * be new for this request even when we re-use an existing connection */
3992
 
    conn->bits.user_passwd = old_conn->bits.user_passwd;
3993
 
    if(conn->bits.user_passwd) {
3994
 
      /* use the new user namd and password though */
3995
 
      Curl_safefree(conn->user);
3996
 
      Curl_safefree(conn->passwd);
3997
 
      conn->user = old_conn->user;
3998
 
      conn->passwd = old_conn->passwd;
3999
 
      old_conn->user = NULL;
4000
 
      old_conn->passwd = NULL;
4001
 
    }
4002
 
 
4003
 
    conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
4004
 
    if(conn->bits.proxy_user_passwd) {
4005
 
      /* use the new proxy user name and proxy password though */
4006
 
      Curl_safefree(conn->proxyuser);
4007
 
      Curl_safefree(conn->proxypasswd);
4008
 
      conn->proxyuser = old_conn->proxyuser;
4009
 
      conn->proxypasswd = old_conn->proxypasswd;
4010
 
      old_conn->proxyuser = NULL;
4011
 
      old_conn->proxypasswd = NULL;
4012
 
    }
4013
 
 
4014
 
    /* host can change, when doing keepalive with a proxy ! */
4015
 
    if(conn->bits.proxy) {
4016
 
      free(conn->host.rawalloc);
4017
 
      conn->host=old_conn->host;
4018
 
    }
4019
 
    else
4020
 
      free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
4021
 
 
4022
 
    /* re-use init */
4023
 
    conn->bits.reuse = TRUE; /* yes, we're re-using here */
4024
 
 
4025
 
    Curl_safefree(old_conn->user);
4026
 
    Curl_safefree(old_conn->passwd);
4027
 
    Curl_safefree(old_conn->proxyuser);
4028
 
    Curl_safefree(old_conn->proxypasswd);
4029
 
    Curl_llist_destroy(old_conn->send_pipe, NULL);
4030
 
    Curl_llist_destroy(old_conn->recv_pipe, NULL);
4031
 
    Curl_llist_destroy(old_conn->pend_pipe, NULL);
4032
 
    Curl_safefree(old_conn->master_buffer);
4033
 
 
4034
 
    free(old_conn);          /* we don't need this anymore */
4035
 
 
4036
 
    *in_connect = conn;      /* return this instead! */
4037
 
 
 
4530
    reuse_conn(conn, conn_temp);
 
4531
    free(conn);          /* we don't need this anymore */
 
4532
    conn = conn_temp;
 
4533
    *in_connect = conn;
4038
4534
    infof(data, "Re-using existing connection! (#%ld) with host %s\n",
4039
4535
          conn->connectindex,
4040
4536
          conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
 
4537
    /* copy this IP address to the common buffer for the easy handle so that
 
4538
       the address can actually survice the removal of this connection. strcpy
 
4539
       is safe since the target buffer is big enough to hold the largest
 
4540
       possible IP address */
 
4541
    strcpy(data->info.ip, conn->ip_addr_str);
 
4542
 
4041
4543
  }
4042
4544
  else {
4043
4545
    /*
4047
4549
    ConnectionStore(data, conn);
4048
4550
  }
4049
4551
 
 
4552
  /*
 
4553
   * Setup whatever necessary for a resumed transfer
 
4554
   */
4050
4555
  result = setup_range(data);
4051
4556
  if(result)
4052
4557
    return result;
4054
4559
  /* Continue connectdata initialization here. */
4055
4560
 
4056
4561
  /*
4057
 
   *
4058
4562
   * Inherit the proper values from the urldata struct AFTER we have arranged
4059
 
   * the persistent connection stuff */
 
4563
   * the persistent connection stuff
 
4564
   */
4060
4565
  conn->fread_func = data->set.fread_func;
4061
4566
  conn->fread_in = data->set.in;
4062
4567
  conn->seek_func = data->set.seek_func;
4063
4568
  conn->seek_client = data->set.seek_client;
4064
4569
 
4065
 
#ifndef USE_ARES
4066
 
  /*************************************************************
4067
 
   * Set timeout if that is being used, and we're not using an asynchronous
4068
 
   * name resolve.
4069
 
   *************************************************************/
4070
 
  if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
4071
 
    /*************************************************************
4072
 
     * Set signal handler to catch SIGALRM
4073
 
     * Store the old value to be able to set it back later!
4074
 
     *************************************************************/
4075
 
 
4076
 
#ifdef SIGALRM
4077
 
#ifdef HAVE_ALARM
4078
 
    long shortest;
4079
 
#endif
4080
 
#ifdef HAVE_SIGACTION
4081
 
    struct sigaction sigact;
4082
 
    sigaction(SIGALRM, NULL, &sigact);
4083
 
    keep_sigact = sigact;
4084
 
    keep_copysig = TRUE; /* yes, we have a copy */
4085
 
    sigact.sa_handler = alarmfunc;
4086
 
#ifdef SA_RESTART
4087
 
    /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
4088
 
    sigact.sa_flags &= ~SA_RESTART;
4089
 
#endif
4090
 
    /* now set the new struct */
4091
 
    sigaction(SIGALRM, &sigact, NULL);
4092
 
#else /* HAVE_SIGACTION */
4093
 
    /* no sigaction(), revert to the much lamer signal() */
4094
 
#ifdef HAVE_SIGNAL
4095
 
    keep_sigact = signal(SIGALRM, alarmfunc);
4096
 
#endif
4097
 
#endif /* HAVE_SIGACTION */
4098
 
 
4099
 
    /* We set the timeout on the name resolving phase first, separately from
4100
 
     * the download/upload part to allow a maximum time on everything. This is
4101
 
     * a signal-based timeout, why it won't work and shouldn't be used in
4102
 
     * multi-threaded environments. */
4103
 
 
4104
 
#ifdef HAVE_ALARM
4105
 
    shortest = data->set.timeout; /* default to this timeout value */
4106
 
    if(shortest && data->set.connecttimeout &&
4107
 
       (data->set.connecttimeout < shortest))
4108
 
      /* if both are set, pick the shortest */
4109
 
      shortest = data->set.connecttimeout;
4110
 
    else if(!shortest)
4111
 
      /* if timeout is not set, use the connect timeout */
4112
 
      shortest = data->set.connecttimeout;
4113
 
 
4114
 
    if(shortest < 1000)
4115
 
      /* the alarm() function only provide integer second resolution, so if
4116
 
         we want to wait less than one second we must bail out already now. */
4117
 
      return CURLE_OPERATION_TIMEDOUT;
4118
 
 
4119
 
    /* alarm() makes a signal get sent when the timeout fires off, and that
4120
 
       will abort system calls */
4121
 
    prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest));
4122
 
    /* We can expect the conn->created time to be "now", as that was just
4123
 
       recently set in the beginning of this function and nothing slow
4124
 
       has been done since then until now. */
4125
 
#endif
4126
 
#endif /* SIGALRM */
4127
 
  }
4128
 
#endif /* USE_ARES */
4129
 
 
4130
 
  /*************************************************************
4131
 
   * Resolve the name of the server or proxy
4132
 
   *************************************************************/
4133
 
  if(conn->bits.reuse) {
4134
 
    /* re-used connection, no resolving is necessary */
4135
 
    hostaddr = NULL;
4136
 
    /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
4137
 
 
4138
 
    if(conn->bits.proxy)
4139
 
      fix_hostname(data, conn, &conn->host);
4140
 
  }
4141
 
  else {
4142
 
    /* this is a fresh connect */
4143
 
 
4144
 
    /* set a pointer to the hostname we display */
4145
 
    fix_hostname(data, conn, &conn->host);
4146
 
 
4147
 
    if(!conn->proxy.name || !*conn->proxy.name) {
4148
 
      /* If not connecting via a proxy, extract the port from the URL, if it is
4149
 
       * there, thus overriding any defaults that might have been set above. */
4150
 
      conn->port =  conn->remote_port; /* it is the same port */
4151
 
 
4152
 
      /* Resolve target host right on */
4153
 
      rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
4154
 
      if(rc == CURLRESOLV_PENDING)
4155
 
        *async = TRUE;
4156
 
 
4157
 
      else if(!hostaddr) {
4158
 
        failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
4159
 
        result =  CURLE_COULDNT_RESOLVE_HOST;
4160
 
        /* don't return yet, we need to clean up the timeout first */
4161
 
      }
4162
 
    }
4163
 
    else {
4164
 
      /* This is a proxy that hasn't been resolved yet. */
4165
 
 
4166
 
      /* IDN-fix the proxy name */
4167
 
      fix_hostname(data, conn, &conn->proxy);
4168
 
 
4169
 
      /* resolve proxy */
4170
 
      rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
4171
 
 
4172
 
      if(rc == CURLRESOLV_PENDING)
4173
 
        *async = TRUE;
4174
 
 
4175
 
      else if(!hostaddr) {
4176
 
        failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
4177
 
        result = CURLE_COULDNT_RESOLVE_PROXY;
4178
 
        /* don't return yet, we need to clean up the timeout first */
4179
 
      }
4180
 
    }
4181
 
  }
4182
 
  *addr = hostaddr;
4183
 
 
4184
 
#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
4185
 
  if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
4186
 
#ifdef HAVE_SIGACTION
4187
 
    if(keep_copysig) {
4188
 
      /* we got a struct as it looked before, now put that one back nice
4189
 
         and clean */
4190
 
      sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
4191
 
    }
4192
 
#else
4193
 
#ifdef HAVE_SIGNAL
4194
 
    /* restore the previous SIGALRM handler */
4195
 
    signal(SIGALRM, keep_sigact);
4196
 
#endif
4197
 
#endif /* HAVE_SIGACTION */
4198
 
 
4199
 
    /* switch back the alarm() to either zero or to what it was before minus
4200
 
       the time we spent until now! */
4201
 
    if(prev_alarm) {
4202
 
      /* there was an alarm() set before us, now put it back */
4203
 
      unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
4204
 
      unsigned long alarm_set;
4205
 
 
4206
 
      /* the alarm period is counted in even number of seconds */
4207
 
      alarm_set = prev_alarm - elapsed_ms/1000;
4208
 
 
4209
 
      if(!alarm_set ||
4210
 
         ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
4211
 
        /* if the alarm time-left reached zero or turned "negative" (counted
4212
 
           with unsigned values), we should fire off a SIGALRM here, but we
4213
 
           won't, and zero would be to switch it off so we never set it to
4214
 
           less than 1! */
4215
 
        alarm(1);
4216
 
        result = CURLE_OPERATION_TIMEDOUT;
4217
 
        failf(data, "Previous alarm fired off!");
4218
 
      }
4219
 
      else
4220
 
        alarm((unsigned int)alarm_set);
4221
 
    }
4222
 
    else
4223
 
      alarm(0); /* just shut it off */
4224
 
  }
4225
 
#endif
 
4570
  /*************************************************************
 
4571
   * Resolve the address of the server or proxy
 
4572
   *************************************************************/
 
4573
  result = resolve_server(data, conn, addr, async);
4226
4574
 
4227
4575
  return result;
4228
4576
}
4229
4577
 
4230
 
/* SetupConnection() is called after the name resolve initiated in
4231
 
 * CreateConnection() is all done.
 
4578
/* setup_conn() is called after the name resolve initiated in
 
4579
 * create_conn() is all done.
4232
4580
 *
4233
4581
 * NOTE: the argument 'hostaddr' is NULL when this function is called for a
4234
4582
 * re-used connection.
4235
4583
 *
4236
 
 * conn->data MUST already have been setup fine (in CreateConnection)
 
4584
 * conn->data MUST already have been setup fine (in create_conn)
4237
4585
 */
4238
4586
 
4239
 
static CURLcode SetupConnection(struct connectdata *conn,
4240
 
                                struct Curl_dns_entry *hostaddr,
4241
 
                                bool *protocol_done)
 
4587
static CURLcode setup_conn(struct connectdata *conn,
 
4588
                           struct Curl_dns_entry *hostaddr,
 
4589
                           bool *protocol_done)
4242
4590
{
4243
4591
  CURLcode result=CURLE_OK;
4244
4592
  struct SessionHandle *data = conn->data;
4259
4607
     lingering set from a previous invoke */
4260
4608
  conn->bits.proxy_connect_closed = FALSE;
4261
4609
 
4262
 
  /*************************************************************
4263
 
   * Set user-agent for HTTP
4264
 
   *************************************************************/
4265
 
  if((conn->protocol&PROT_HTTP) && data->set.str[STRING_USERAGENT]) {
 
4610
  /*
 
4611
   * Set user-agent. Used for HTTP, but since we can attempt to tunnel
 
4612
   * basically anything through a http proxy we can't limit this based on
 
4613
   * protocol.
 
4614
   */
 
4615
  if(data->set.str[STRING_USERAGENT]) {
4266
4616
    Curl_safefree(conn->allocptr.uagent);
4267
4617
    conn->allocptr.uagent =
4268
4618
      aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
4282
4632
    if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
4283
4633
      bool connected = FALSE;
4284
4634
 
4285
 
      /* Connect only if not already connected! */
 
4635
      /* Connect only if not already connected!
 
4636
       *
 
4637
       * NOTE: hostaddr can be NULL when passed to this function, but that is
 
4638
       * only for the case where we re-use an existing connection and thus
 
4639
       * this code section will not be reached with hostaddr == NULL.
 
4640
       */
4286
4641
      result = ConnectPlease(data, conn, hostaddr, &connected);
4287
4642
 
4288
4643
      if(connected) {
4309
4664
    }
4310
4665
    else {
4311
4666
      Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
 
4667
      Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
4312
4668
      conn->bits.tcpconnect = TRUE;
4313
4669
      *protocol_done = TRUE;
4314
4670
      if(data->set.verbose)
4322
4678
                               set this here perhaps a second time */
4323
4679
 
4324
4680
#ifdef __EMX__
4325
 
  /* 20000330 mgs
4326
 
   * the check is quite a hack...
4327
 
   * we're calling _fsetmode to fix the problem with fwrite converting newline
4328
 
   * characters (you get mangled text files, and corrupted binary files when
4329
 
   * you download to stdout and redirect it to a file). */
 
4681
  /*
 
4682
   * This check is quite a hack. We're calling _fsetmode to fix the problem
 
4683
   * with fwrite converting newline characters (you get mangled text files,
 
4684
   * and corrupted binary files when you download to stdout and redirect it to
 
4685
   * a file).
 
4686
   */
4330
4687
 
4331
4688
  if((data->set.out)->_handle == NULL) {
4332
4689
    _fsetmode(stdout, "b");
4333
4690
  }
4334
4691
#endif
4335
4692
 
4336
 
  return CURLE_OK;
 
4693
  return result;
4337
4694
}
4338
4695
 
4339
4696
CURLcode Curl_connect(struct SessionHandle *data,
4347
4704
  *asyncp = FALSE; /* assume synchronous resolves by default */
4348
4705
 
4349
4706
  /* call the stuff that needs to be called */
4350
 
  code = CreateConnection(data, in_connect, &dns, asyncp);
 
4707
  code = create_conn(data, in_connect, &dns, asyncp);
4351
4708
 
4352
4709
  if(CURLE_OK == code) {
4353
4710
    /* no error */
4354
 
    if((*in_connect)->send_pipe->size +
4355
 
       (*in_connect)->recv_pipe->size != 0)
 
4711
    if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
4356
4712
      /* pipelining */
4357
4713
      *protocol_done = TRUE;
4358
4714
    else {
 
4715
 
4359
4716
      if(dns || !*asyncp)
4360
4717
        /* If an address is available it means that we already have the name
4361
4718
           resolved, OR it isn't async. if this is a re-used connection 'dns'
4362
4719
           will be NULL here. Continue connecting from here */
4363
 
        code = SetupConnection(*in_connect, dns, protocol_done);
4364
 
      /* else
4365
 
         response will be received and treated async wise */
 
4720
        code = setup_conn(*in_connect, dns, protocol_done);
 
4721
 
 
4722
      if(dns && code) {
 
4723
        /* We have the dns entry info already but failed to connect to the
 
4724
         * host and thus we must make sure to unlock the dns entry again
 
4725
         * before returning failure from here.
 
4726
         */
 
4727
        Curl_resolv_unlock(data, dns);
 
4728
      }
4366
4729
    }
4367
4730
  }
4368
4731
 
4369
 
  if(CURLE_OK != code && *in_connect) {
 
4732
  if(code && *in_connect) {
4370
4733
    /* We're not allowed to return failure with memory left allocated
4371
4734
       in the connectdata struct, free those here */
4372
4735
    Curl_disconnect(*in_connect); /* close the connection */
4386
4749
{
4387
4750
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
4388
4751
    defined(USE_THREADING_GETADDRINFO)
4389
 
  CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
 
4752
  CURLcode code = setup_conn(conn, conn->async.dns, protocol_done);
4390
4753
 
4391
4754
  if(code)
4392
4755
    /* We're not allowed to return failure with memory left allocated
4418
4781
 
4419
4782
  Curl_expire(data, 0); /* stop timer */
4420
4783
 
4421
 
  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
4422
 
     conn->readchannel_inuse)
4423
 
    conn->readchannel_inuse = FALSE;
4424
 
  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
4425
 
     conn->writechannel_inuse)
4426
 
    conn->writechannel_inuse = FALSE;
4427
 
  Curl_removeHandleFromPipeline(data, conn->pend_pipe);
4428
 
 
4429
 
  if(conn->bits.done ||
4430
 
     (conn->send_pipe->size + conn->recv_pipe->size != 0 &&
 
4784
  if(conn->bits.done)
 
4785
    /* Stop if Curl_done() has already been called */
 
4786
    return CURLE_OK;
 
4787
 
 
4788
  Curl_getoff_all_pipelines(data, conn);
 
4789
 
 
4790
  if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
4431
4791
      !data->set.reuse_forbid &&
4432
4792
      !conn->bits.close))
4433
 
    /* Stop if Curl_done() has already been called or pipeline
4434
 
       is not empty and we do not have to close connection. */
 
4793
    /* Stop if pipeline is not empty and we do not have to close
 
4794
       connection. */
4435
4795
    return CURLE_OK;
4436
4796
 
4437
4797
  conn->bits.done = TRUE; /* called just now! */
4482
4842
     state it is for re-using, so we're forced to close it. In a perfect world
4483
4843
     we can add code that keep track of if we really must close it here or not,
4484
4844
     but currently we have no such detail knowledge.
 
4845
 
 
4846
     connectindex == -1 here means that the connection has no spot in the
 
4847
     connection cache and thus we must disconnect it here.
4485
4848
  */
4486
 
  if(data->set.reuse_forbid || conn->bits.close || premature) {
 
4849
  if(data->set.reuse_forbid || conn->bits.close || premature ||
 
4850
     (-1 == conn->connectindex)) {
4487
4851
    CURLcode res2 = Curl_disconnect(conn); /* close the connection */
4488
4852
 
4489
4853
    /* If we had an error already, make sure we return that one. But
4514
4878
 * do_init() inits the readwrite session. This is inited each time (in the DO
4515
4879
 * function before the protocol-specific DO functions are invoked) for a
4516
4880
 * transfer, sometimes multiple times on the same SessionHandle. Make sure
4517
 
 * nothing in here depends on stuff that are setup dynamicly for the transfer.
 
4881
 * nothing in here depends on stuff that are setup dynamically for the
 
4882
 * transfer.
4518
4883
 */
4519
4884
 
4520
4885
static CURLcode do_init(struct connectdata *conn)
4524
4889
 
4525
4890
  conn->bits.done = FALSE; /* Curl_done() is not called yet */
4526
4891
  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
 
4892
  data->state.expect100header = FALSE;
 
4893
 
 
4894
  if(data->set.opt_no_body)
 
4895
    /* in HTTP lingo, no body means using the HEAD request... */
 
4896
    data->set.httpreq = HTTPREQ_HEAD;
 
4897
  else if(HTTPREQ_HEAD == data->set.httpreq)
 
4898
    /* ... but if unset there really is no perfect method that is the
 
4899
       "opposite" of HEAD but in reality most people probably think GET
 
4900
       then. The important thing is that we can't let it remain HEAD if the
 
4901
       opt_no_body is set FALSE since then we'll behave wrong when getting
 
4902
       HTTP. */
 
4903
    data->set.httpreq = HTTPREQ_GET;
4527
4904
 
4528
4905
  /* NB: the content encoding software depends on this initialization */
4529
4906
  Curl_easy_initHandleData(data);
4531
4908
  k->start = Curl_tvnow(); /* start time */
4532
4909
  k->now = k->start;   /* current time is now */
4533
4910
  k->header = TRUE; /* assume header */
4534
 
  k->httpversion = -1; /* unknown at this point */
4535
4911
 
4536
4912
  k->bytecount = 0;
4537
4913