~ubuntu-branches/ubuntu/vivid/curl/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-0138.patch/lib/url.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-04-01 09:25:23 UTC
  • Revision ID: package-import@ubuntu.com-20140401092523-y4maf7lz4aufo1l5
Tags: 7.35.0-1ubuntu2
* SECURITY UPDATE: wrong re-use of connections
  - debian/patches/CVE-2014-0138.patch: fix possible issues with NTLM
    HTTP logic, and extend new connection logic to other protocols in
    lib/http.c, lib/url.c, lib/urldata.h, add new tests to
    tests/data/Makefile.am, tests/data/test1418, tests/data/test1419.
  - CVE-2014-0138
* SECURITY UPDATE: incorrect wildcard SSL certificate validation with
  literal IP addresses
  - debian/patches/CVE-2014-0139.patch: fix wildcard logic in
    lib/hostcheck.c, added tests to tests/data/Makefile.am,
    tests/data/test1397, tests/unit/Makefile.inc, tests/unit/unit1397.c.
  - CVE-2014-0139
* debian/patches/fix_test172.path: fix expired cookie causing test to
  fail.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *                                  _   _ ____  _
 
3
 *  Project                     ___| | | |  _ \| |
 
4
 *                             / __| | | | |_) | |
 
5
 *                            | (__| |_| |  _ <| |___
 
6
 *                             \___|\___/|_| \_\_____|
 
7
 *
 
8
 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
 
9
 *
 
10
 * This software is licensed as described in the file COPYING, which
 
11
 * you should have received as part of this distribution. The terms
 
12
 * are also available at http://curl.haxx.se/docs/copyright.html.
 
13
 *
 
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 
15
 * copies of the Software, and permit persons to whom the Software is
 
16
 * furnished to do so, under the terms of the COPYING file.
 
17
 *
 
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 
19
 * KIND, either express or implied.
 
20
 *
 
21
 ***************************************************************************/
 
22
 
 
23
#include "curl_setup.h"
 
24
 
 
25
#ifdef HAVE_NETINET_IN_H
 
26
#include <netinet/in.h>
 
27
#endif
 
28
#ifdef HAVE_NETDB_H
 
29
#include <netdb.h>
 
30
#endif
 
31
#ifdef HAVE_ARPA_INET_H
 
32
#include <arpa/inet.h>
 
33
#endif
 
34
#ifdef HAVE_NET_IF_H
 
35
#include <net/if.h>
 
36
#endif
 
37
#ifdef HAVE_SYS_IOCTL_H
 
38
#include <sys/ioctl.h>
 
39
#endif
 
40
 
 
41
#ifdef HAVE_SYS_PARAM_H
 
42
#include <sys/param.h>
 
43
#endif
 
44
 
 
45
#ifdef __VMS
 
46
#include <in.h>
 
47
#include <inet.h>
 
48
#endif
 
49
 
 
50
#ifndef HAVE_SOCKET
 
51
#error "We can't compile without socket() support!"
 
52
#endif
 
53
 
 
54
#ifdef HAVE_LIMITS_H
 
55
#include <limits.h>
 
56
#endif
 
57
 
 
58
#ifdef USE_LIBIDN
 
59
#include <idna.h>
 
60
#include <tld.h>
 
61
#include <stringprep.h>
 
62
#ifdef HAVE_IDN_FREE_H
 
63
#include <idn-free.h>
 
64
#else
 
65
/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
 
66
void idn_free (void *ptr);
 
67
#endif
 
68
#ifndef HAVE_IDN_FREE
 
69
/* if idn_free() was not found in this version of libidn use free() instead */
 
70
#define idn_free(x) (free)(x)
 
71
#endif
 
72
#elif defined(USE_WIN32_IDN)
 
73
/* prototype for curl_win32_idn_to_ascii() */
 
74
int curl_win32_idn_to_ascii(const char *in, char **out);
 
75
#endif  /* USE_LIBIDN */
 
76
 
 
77
#include "urldata.h"
 
78
#include "netrc.h"
 
79
 
 
80
#include "formdata.h"
 
81
#include "vtls/vtls.h"
 
82
#include "hostip.h"
 
83
#include "transfer.h"
 
84
#include "sendf.h"
 
85
#include "progress.h"
 
86
#include "cookie.h"
 
87
#include "strequal.h"
 
88
#include "strerror.h"
 
89
#include "escape.h"
 
90
#include "strtok.h"
 
91
#include "share.h"
 
92
#include "content_encoding.h"
 
93
#include "http_digest.h"
 
94
#include "http_negotiate.h"
 
95
#include "select.h"
 
96
#include "multiif.h"
 
97
#include "easyif.h"
 
98
#include "speedcheck.h"
 
99
#include "rawstr.h"
 
100
#include "warnless.h"
 
101
#include "non-ascii.h"
 
102
#include "inet_pton.h"
 
103
 
 
104
/* And now for the protocols */
 
105
#include "ftp.h"
 
106
#include "dict.h"
 
107
#include "telnet.h"
 
108
#include "tftp.h"
 
109
#include "http.h"
 
110
#include "file.h"
 
111
#include "curl_ldap.h"
 
112
#include "ssh.h"
 
113
#include "imap.h"
 
114
#include "url.h"
 
115
#include "connect.h"
 
116
#include "inet_ntop.h"
 
117
#include "curl_ntlm.h"
 
118
#include "curl_ntlm_wb.h"
 
119
#include "socks.h"
 
120
#include "curl_rtmp.h"
 
121
#include "gopher.h"
 
122
#include "http_proxy.h"
 
123
#include "bundles.h"
 
124
#include "conncache.h"
 
125
#include "multihandle.h"
 
126
#include "pipeline.h"
 
127
#include "dotdot.h"
 
128
 
 
129
#define _MPRINTF_REPLACE /* use our functions only */
 
130
#include <curl/mprintf.h>
 
131
 
 
132
#include "curl_memory.h"
 
133
/* The last #include file should be: */
 
134
#include "memdebug.h"
 
135
 
 
136
/* Local static prototypes */
 
137
static struct connectdata *
 
138
find_oldest_idle_connection(struct SessionHandle *data);
 
139
static struct connectdata *
 
140
find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
 
141
                                      struct connectbundle *bundle);
 
142
static void conn_free(struct connectdata *conn);
 
143
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
 
144
static CURLcode do_init(struct connectdata *conn);
 
145
static CURLcode parse_url_login(struct SessionHandle *data,
 
146
                                struct connectdata *conn,
 
147
                                char **userptr, char **passwdptr,
 
148
                                char **optionsptr);
 
149
static CURLcode parse_login_details(const char *login, const size_t len,
 
150
                                    char **userptr, char **passwdptr,
 
151
                                    char **optionsptr);
 
152
/*
 
153
 * Protocol table.
 
154
 */
 
155
 
 
156
static const struct Curl_handler * const protocols[] = {
 
157
 
 
158
#ifndef CURL_DISABLE_HTTP
 
159
  &Curl_handler_http,
 
160
#endif
 
161
 
 
162
#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
 
163
  &Curl_handler_https,
 
164
#endif
 
165
 
 
166
#ifndef CURL_DISABLE_FTP
 
167
  &Curl_handler_ftp,
 
168
#endif
 
169
 
 
170
#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
 
171
  &Curl_handler_ftps,
 
172
#endif
 
173
 
 
174
#ifndef CURL_DISABLE_TELNET
 
175
  &Curl_handler_telnet,
 
176
#endif
 
177
 
 
178
#ifndef CURL_DISABLE_DICT
 
179
  &Curl_handler_dict,
 
180
#endif
 
181
 
 
182
#ifndef CURL_DISABLE_LDAP
 
183
  &Curl_handler_ldap,
 
184
#if !defined(CURL_DISABLE_LDAPS) && \
 
185
    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
 
186
     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
 
187
  &Curl_handler_ldaps,
 
188
#endif
 
189
#endif
 
190
 
 
191
#ifndef CURL_DISABLE_FILE
 
192
  &Curl_handler_file,
 
193
#endif
 
194
 
 
195
#ifndef CURL_DISABLE_TFTP
 
196
  &Curl_handler_tftp,
 
197
#endif
 
198
 
 
199
#ifdef USE_LIBSSH2
 
200
  &Curl_handler_scp,
 
201
  &Curl_handler_sftp,
 
202
#endif
 
203
 
 
204
#ifndef CURL_DISABLE_IMAP
 
205
  &Curl_handler_imap,
 
206
#ifdef USE_SSL
 
207
  &Curl_handler_imaps,
 
208
#endif
 
209
#endif
 
210
 
 
211
#ifndef CURL_DISABLE_POP3
 
212
  &Curl_handler_pop3,
 
213
#ifdef USE_SSL
 
214
  &Curl_handler_pop3s,
 
215
#endif
 
216
#endif
 
217
 
 
218
#ifndef CURL_DISABLE_SMTP
 
219
  &Curl_handler_smtp,
 
220
#ifdef USE_SSL
 
221
  &Curl_handler_smtps,
 
222
#endif
 
223
#endif
 
224
 
 
225
#ifndef CURL_DISABLE_RTSP
 
226
  &Curl_handler_rtsp,
 
227
#endif
 
228
 
 
229
#ifndef CURL_DISABLE_GOPHER
 
230
  &Curl_handler_gopher,
 
231
#endif
 
232
 
 
233
#ifdef USE_LIBRTMP
 
234
  &Curl_handler_rtmp,
 
235
  &Curl_handler_rtmpt,
 
236
  &Curl_handler_rtmpe,
 
237
  &Curl_handler_rtmpte,
 
238
  &Curl_handler_rtmps,
 
239
  &Curl_handler_rtmpts,
 
240
#endif
 
241
 
 
242
  (struct Curl_handler *) NULL
 
243
};
 
244
 
 
245
/*
 
246
 * Dummy handler for undefined protocol schemes.
 
247
 */
 
248
 
 
249
static const struct Curl_handler Curl_handler_dummy = {
 
250
  "<no protocol>",                      /* scheme */
 
251
  ZERO_NULL,                            /* setup_connection */
 
252
  ZERO_NULL,                            /* do_it */
 
253
  ZERO_NULL,                            /* done */
 
254
  ZERO_NULL,                            /* do_more */
 
255
  ZERO_NULL,                            /* connect_it */
 
256
  ZERO_NULL,                            /* connecting */
 
257
  ZERO_NULL,                            /* doing */
 
258
  ZERO_NULL,                            /* proto_getsock */
 
259
  ZERO_NULL,                            /* doing_getsock */
 
260
  ZERO_NULL,                            /* domore_getsock */
 
261
  ZERO_NULL,                            /* perform_getsock */
 
262
  ZERO_NULL,                            /* disconnect */
 
263
  ZERO_NULL,                            /* readwrite */
 
264
  0,                                    /* defport */
 
265
  0,                                    /* protocol */
 
266
  PROTOPT_NONE                          /* flags */
 
267
};
 
268
 
 
269
void Curl_freeset(struct SessionHandle *data)
 
270
{
 
271
  /* Free all dynamic strings stored in the data->set substructure. */
 
272
  enum dupstring i;
 
273
  for(i=(enum dupstring)0; i < STRING_LAST; i++)
 
274
    Curl_safefree(data->set.str[i]);
 
275
 
 
276
  if(data->change.referer_alloc) {
 
277
    Curl_safefree(data->change.referer);
 
278
    data->change.referer_alloc = FALSE;
 
279
  }
 
280
  data->change.referer = NULL;
 
281
}
 
282
 
 
283
static CURLcode setstropt(char **charp, char *s)
 
284
{
 
285
  /* Release the previous storage at `charp' and replace by a dynamic storage
 
286
     copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
 
287
 
 
288
  Curl_safefree(*charp);
 
289
 
 
290
  if(s) {
 
291
    s = strdup(s);
 
292
 
 
293
    if(!s)
 
294
      return CURLE_OUT_OF_MEMORY;
 
295
 
 
296
    *charp = s;
 
297
  }
 
298
 
 
299
  return CURLE_OK;
 
300
}
 
301
 
 
302
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
 
303
{
 
304
  CURLcode result = CURLE_OK;
 
305
  char *user = NULL;
 
306
  char *passwd = NULL;
 
307
 
 
308
  /* Parse the login details if specified. It not then we treat NULL as a hint
 
309
     to clear the existing data */
 
310
  if(option) {
 
311
    result = parse_login_details(option, strlen(option),
 
312
                                 (userp ? &user : NULL),
 
313
                                 (passwdp ? &passwd : NULL),
 
314
                                 NULL);
 
315
  }
 
316
 
 
317
  if(!result) {
 
318
    /* Store the username part of option if required */
 
319
    if(userp) {
 
320
      if(!user && option && option[0] == ':') {
 
321
        /* Allocate an empty string instead of returning NULL as user name */
 
322
        user = strdup("");
 
323
        if(!user)
 
324
          result = CURLE_OUT_OF_MEMORY;
 
325
      }
 
326
 
 
327
      Curl_safefree(*userp);
 
328
      *userp = user;
 
329
    }
 
330
 
 
331
    /* Store the password part of option if required */
 
332
    if(passwdp) {
 
333
      Curl_safefree(*passwdp);
 
334
      *passwdp = passwd;
 
335
    }
 
336
  }
 
337
 
 
338
  return result;
 
339
}
 
340
 
 
341
CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
 
342
{
 
343
  CURLcode r = CURLE_OK;
 
344
  enum dupstring i;
 
345
 
 
346
  /* Copy src->set into dst->set first, then deal with the strings
 
347
     afterwards */
 
348
  dst->set = src->set;
 
349
 
 
350
  /* clear all string pointers first */
 
351
  memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
 
352
 
 
353
  /* duplicate all strings */
 
354
  for(i=(enum dupstring)0; i< STRING_LAST; i++) {
 
355
    r = setstropt(&dst->set.str[i], src->set.str[i]);
 
356
    if(r != CURLE_OK)
 
357
      break;
 
358
  }
 
359
 
 
360
  /* If a failure occurred, freeing has to be performed externally. */
 
361
  return r;
 
362
}
 
363
 
 
364
/*
 
365
 * This is the internal function curl_easy_cleanup() calls. This should
 
366
 * cleanup and free all resources associated with this sessionhandle.
 
367
 *
 
368
 * NOTE: if we ever add something that attempts to write to a socket or
 
369
 * similar here, we must ignore SIGPIPE first. It is currently only done
 
370
 * when curl_easy_perform() is invoked.
 
371
 */
 
372
 
 
373
CURLcode Curl_close(struct SessionHandle *data)
 
374
{
 
375
  struct Curl_multi *m;
 
376
 
 
377
  if(!data)
 
378
    return CURLE_OK;
 
379
 
 
380
  Curl_expire(data, 0); /* shut off timers */
 
381
 
 
382
  m = data->multi;
 
383
 
 
384
  if(m)
 
385
    /* This handle is still part of a multi handle, take care of this first
 
386
       and detach this handle from there. */
 
387
    curl_multi_remove_handle(data->multi, data);
 
388
 
 
389
  if(data->multi_easy)
 
390
    /* when curl_easy_perform() is used, it creates its own multi handle to
 
391
       use and this is the one */
 
392
    curl_multi_cleanup(data->multi_easy);
 
393
 
 
394
  /* Destroy the timeout list that is held in the easy handle. It is
 
395
     /normally/ done by curl_multi_remove_handle() but this is "just in
 
396
     case" */
 
397
  if(data->state.timeoutlist) {
 
398
    Curl_llist_destroy(data->state.timeoutlist, NULL);
 
399
    data->state.timeoutlist = NULL;
 
400
  }
 
401
 
 
402
  data->magic = 0; /* force a clear AFTER the possibly enforced removal from
 
403
                      the multi handle, since that function uses the magic
 
404
                      field! */
 
405
 
 
406
  if(data->state.rangestringalloc)
 
407
    free(data->state.range);
 
408
 
 
409
  /* Free the pathbuffer */
 
410
  Curl_safefree(data->state.pathbuffer);
 
411
  data->state.path = NULL;
 
412
 
 
413
  /* freed here just in case DONE wasn't called */
 
414
  Curl_free_request_state(data);
 
415
 
 
416
  /* Close down all open SSL info and sessions */
 
417
  Curl_ssl_close_all(data);
 
418
  Curl_safefree(data->state.first_host);
 
419
  Curl_safefree(data->state.scratch);
 
420
  Curl_ssl_free_certinfo(data);
 
421
 
 
422
  if(data->change.referer_alloc) {
 
423
    Curl_safefree(data->change.referer);
 
424
    data->change.referer_alloc = FALSE;
 
425
  }
 
426
  data->change.referer = NULL;
 
427
 
 
428
  if(data->change.url_alloc) {
 
429
    Curl_safefree(data->change.url);
 
430
    data->change.url_alloc = FALSE;
 
431
  }
 
432
  data->change.url = NULL;
 
433
 
 
434
  Curl_safefree(data->state.headerbuff);
 
435
 
 
436
  Curl_flush_cookies(data, 1);
 
437
 
 
438
  Curl_digest_cleanup(data);
 
439
 
 
440
  Curl_safefree(data->info.contenttype);
 
441
  Curl_safefree(data->info.wouldredirect);
 
442
 
 
443
  /* this destroys the channel and we cannot use it anymore after this */
 
444
  Curl_resolver_cleanup(data->state.resolver);
 
445
 
 
446
  Curl_convert_close(data);
 
447
 
 
448
  /* No longer a dirty share, if it exists */
 
449
  if(data->share) {
 
450
    Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
 
451
    data->share->dirty--;
 
452
    Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
 
453
  }
 
454
 
 
455
  Curl_freeset(data);
 
456
  free(data);
 
457
  return CURLE_OK;
 
458
}
 
459
 
 
460
/*
 
461
 * Initialize the UserDefined fields within a SessionHandle.
 
462
 * This may be safely called on a new or existing SessionHandle.
 
463
 */
 
464
CURLcode Curl_init_userdefined(struct UserDefined *set)
 
465
{
 
466
  CURLcode res = CURLE_OK;
 
467
 
 
468
  set->out = stdout; /* default output to stdout */
 
469
  set->in  = stdin;  /* default input from stdin */
 
470
  set->err  = stderr;  /* default stderr to stderr */
 
471
 
 
472
  /* use fwrite as default function to store output */
 
473
  set->fwrite_func = (curl_write_callback)fwrite;
 
474
 
 
475
  /* use fread as default function to read input */
 
476
  set->fread_func = (curl_read_callback)fread;
 
477
  set->is_fread_set = 0;
 
478
  set->is_fwrite_set = 0;
 
479
 
 
480
  set->seek_func = ZERO_NULL;
 
481
  set->seek_client = ZERO_NULL;
 
482
 
 
483
  /* conversion callbacks for non-ASCII hosts */
 
484
  set->convfromnetwork = ZERO_NULL;
 
485
  set->convtonetwork   = ZERO_NULL;
 
486
  set->convfromutf8    = ZERO_NULL;
 
487
 
 
488
  set->infilesize = -1;      /* we don't know any size */
 
489
  set->postfieldsize = -1;   /* unknown size */
 
490
  set->maxredirs = -1;       /* allow any amount by default */
 
491
 
 
492
  set->httpreq = HTTPREQ_GET; /* Default HTTP request */
 
493
  set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
 
494
  set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
 
495
  set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
 
496
  set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
 
497
  set->ftp_filemethod = FTPFILE_MULTICWD;
 
498
 
 
499
  set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
 
500
 
 
501
  /* Set the default size of the SSL session ID cache */
 
502
  set->ssl.max_ssl_sessions = 5;
 
503
 
 
504
  set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
 
505
  set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
 
506
  set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
 
507
  set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
 
508
 
 
509
  /* make libcurl quiet by default: */
 
510
  set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
 
511
 
 
512
  /*
 
513
   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
 
514
   * switched off unless wanted.
 
515
   */
 
516
  set->ssl.verifypeer = TRUE;
 
517
  set->ssl.verifyhost = TRUE;
 
518
#ifdef USE_TLS_SRP
 
519
  set->ssl.authtype = CURL_TLSAUTH_NONE;
 
520
#endif
 
521
  set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
 
522
                                                      type */
 
523
  set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
 
524
 
 
525
  set->new_file_perms = 0644;    /* Default permissions */
 
526
  set->new_directory_perms = 0755; /* Default permissions */
 
527
 
 
528
  /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
 
529
     define since we internally only use the lower 16 bits for the passed
 
530
     in bitmask to not conflict with the private bits */
 
531
  set->allowed_protocols = CURLPROTO_ALL;
 
532
  set->redir_protocols =
 
533
    CURLPROTO_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
 
534
 
 
535
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
536
  /*
 
537
   * disallow unprotected protection negotiation NEC reference implementation
 
538
   * seem not to follow rfc1961 section 4.3/4.4
 
539
   */
 
540
  set->socks5_gssapi_nec = FALSE;
 
541
  /* set default gssapi service name */
 
542
  res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
 
543
                  (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
 
544
  if(res != CURLE_OK)
 
545
    return res;
 
546
#endif
 
547
 
 
548
  /* This is our preferred CA cert bundle/path since install time */
 
549
#if defined(CURL_CA_BUNDLE)
 
550
  res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
 
551
#elif defined(CURL_CA_PATH)
 
552
  res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
 
553
#endif
 
554
 
 
555
  set->wildcardmatch  = FALSE;
 
556
  set->chunk_bgn      = ZERO_NULL;
 
557
  set->chunk_end      = ZERO_NULL;
 
558
 
 
559
  /* tcp keepalives are disabled by default, but provide reasonable values for
 
560
   * the interval and idle times.
 
561
   */
 
562
  set->tcp_keepalive = FALSE;
 
563
  set->tcp_keepintvl = 60;
 
564
  set->tcp_keepidle = 60;
 
565
 
 
566
  return res;
 
567
}
 
568
 
 
569
/**
 
570
 * Curl_open()
 
571
 *
 
572
 * @param curl is a pointer to a sessionhandle pointer that gets set by this
 
573
 * function.
 
574
 * @return CURLcode
 
575
 */
 
576
 
 
577
CURLcode Curl_open(struct SessionHandle **curl)
 
578
{
 
579
  CURLcode res = CURLE_OK;
 
580
  struct SessionHandle *data;
 
581
  CURLcode status;
 
582
 
 
583
  /* Very simple start-up: alloc the struct, init it with zeroes and return */
 
584
  data = calloc(1, sizeof(struct SessionHandle));
 
585
  if(!data) {
 
586
    /* this is a very serious error */
 
587
    DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
 
588
    return CURLE_OUT_OF_MEMORY;
 
589
  }
 
590
 
 
591
  data->magic = CURLEASY_MAGIC_NUMBER;
 
592
 
 
593
  status = Curl_resolver_init(&data->state.resolver);
 
594
  if(status) {
 
595
    DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
 
596
    free(data);
 
597
    return status;
 
598
  }
 
599
 
 
600
  /* We do some initial setup here, all those fields that can't be just 0 */
 
601
 
 
602
  data->state.headerbuff = malloc(HEADERSIZE);
 
603
  if(!data->state.headerbuff) {
 
604
    DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
 
605
    res = CURLE_OUT_OF_MEMORY;
 
606
  }
 
607
  else {
 
608
    res = Curl_init_userdefined(&data->set);
 
609
 
 
610
    data->state.headersize=HEADERSIZE;
 
611
 
 
612
    Curl_convert_init(data);
 
613
 
 
614
    /* most recent connection is not yet defined */
 
615
    data->state.lastconnect = NULL;
 
616
 
 
617
    data->progress.flags |= PGRS_HIDE;
 
618
    data->state.current_speed = -1; /* init to negative == impossible */
 
619
 
 
620
    data->wildcard.state = CURLWC_INIT;
 
621
    data->wildcard.filelist = NULL;
 
622
    data->set.fnmatch = ZERO_NULL;
 
623
    data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
 
624
  }
 
625
 
 
626
  if(res) {
 
627
    Curl_resolver_cleanup(data->state.resolver);
 
628
    if(data->state.headerbuff)
 
629
      free(data->state.headerbuff);
 
630
    Curl_freeset(data);
 
631
    free(data);
 
632
    data = NULL;
 
633
  }
 
634
  else
 
635
    *curl = data;
 
636
 
 
637
  return res;
 
638
}
 
639
 
 
640
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
 
641
                     va_list param)
 
642
{
 
643
  char *argptr;
 
644
  CURLcode result = CURLE_OK;
 
645
  long arg;
 
646
#ifndef CURL_DISABLE_HTTP
 
647
  curl_off_t bigsize;
 
648
#endif
 
649
 
 
650
  switch(option) {
 
651
  case CURLOPT_DNS_CACHE_TIMEOUT:
 
652
    data->set.dns_cache_timeout = va_arg(param, long);
 
653
    break;
 
654
  case CURLOPT_DNS_USE_GLOBAL_CACHE:
 
655
    /* remember we want this enabled */
 
656
    arg = va_arg(param, long);
 
657
    data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
 
658
    break;
 
659
  case CURLOPT_SSL_CIPHER_LIST:
 
660
    /* set a list of cipher we want to use in the SSL connection */
 
661
    result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
 
662
                       va_arg(param, char *));
 
663
    break;
 
664
 
 
665
  case CURLOPT_RANDOM_FILE:
 
666
    /*
 
667
     * This is the path name to a file that contains random data to seed
 
668
     * the random SSL stuff with. The file is only used for reading.
 
669
     */
 
670
    result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
 
671
                       va_arg(param, char *));
 
672
    break;
 
673
  case CURLOPT_EGDSOCKET:
 
674
    /*
 
675
     * The Entropy Gathering Daemon socket pathname
 
676
     */
 
677
    result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
 
678
                       va_arg(param, char *));
 
679
    break;
 
680
  case CURLOPT_MAXCONNECTS:
 
681
    /*
 
682
     * Set the absolute number of maximum simultaneous alive connection that
 
683
     * libcurl is allowed to have.
 
684
     */
 
685
    data->set.maxconnects = va_arg(param, long);
 
686
    break;
 
687
  case CURLOPT_FORBID_REUSE:
 
688
    /*
 
689
     * When this transfer is done, it must not be left to be reused by a
 
690
     * subsequent transfer but shall be closed immediately.
 
691
     */
 
692
    data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
 
693
    break;
 
694
  case CURLOPT_FRESH_CONNECT:
 
695
    /*
 
696
     * This transfer shall not use a previously cached connection but
 
697
     * should be made with a fresh new connect!
 
698
     */
 
699
    data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
 
700
    break;
 
701
  case CURLOPT_VERBOSE:
 
702
    /*
 
703
     * Verbose means infof() calls that give a lot of information about
 
704
     * the connection and transfer procedures as well as internal choices.
 
705
     */
 
706
    data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
 
707
    break;
 
708
  case CURLOPT_HEADER:
 
709
    /*
 
710
     * Set to include the header in the general data output stream.
 
711
     */
 
712
    data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
 
713
    break;
 
714
  case CURLOPT_NOPROGRESS:
 
715
    /*
 
716
     * Shut off the internal supported progress meter
 
717
     */
 
718
    data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
 
719
    if(data->set.hide_progress)
 
720
      data->progress.flags |= PGRS_HIDE;
 
721
    else
 
722
      data->progress.flags &= ~PGRS_HIDE;
 
723
    break;
 
724
  case CURLOPT_NOBODY:
 
725
    /*
 
726
     * Do not include the body part in the output data stream.
 
727
     */
 
728
    data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
 
729
    break;
 
730
  case CURLOPT_FAILONERROR:
 
731
    /*
 
732
     * Don't output the >=300 error code HTML-page, but instead only
 
733
     * return error.
 
734
     */
 
735
    data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
 
736
    break;
 
737
  case CURLOPT_UPLOAD:
 
738
  case CURLOPT_PUT:
 
739
    /*
 
740
     * We want to sent data to the remote host. If this is HTTP, that equals
 
741
     * using the PUT request.
 
742
     */
 
743
    data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
 
744
    if(data->set.upload) {
 
745
      /* If this is HTTP, PUT is what's needed to "upload" */
 
746
      data->set.httpreq = HTTPREQ_PUT;
 
747
      data->set.opt_no_body = FALSE; /* this is implied */
 
748
    }
 
749
    else
 
750
      /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
 
751
         then this can be changed to HEAD later on) */
 
752
      data->set.httpreq = HTTPREQ_GET;
 
753
    break;
 
754
  case CURLOPT_FILETIME:
 
755
    /*
 
756
     * Try to get the file time of the remote document. The time will
 
757
     * later (possibly) become available using curl_easy_getinfo().
 
758
     */
 
759
    data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
 
760
    break;
 
761
  case CURLOPT_FTP_CREATE_MISSING_DIRS:
 
762
    /*
 
763
     * An FTP option that modifies an upload to create missing directories on
 
764
     * the server.
 
765
     */
 
766
    switch(va_arg(param, long)) {
 
767
    case 0:
 
768
      data->set.ftp_create_missing_dirs = 0;
 
769
      break;
 
770
    case 1:
 
771
      data->set.ftp_create_missing_dirs = 1;
 
772
      break;
 
773
    case 2:
 
774
      data->set.ftp_create_missing_dirs = 2;
 
775
      break;
 
776
    default:
 
777
      /* reserve other values for future use */
 
778
      result = CURLE_UNKNOWN_OPTION;
 
779
      break;
 
780
    }
 
781
    break;
 
782
  case CURLOPT_SERVER_RESPONSE_TIMEOUT:
 
783
    /*
 
784
     * Option that specifies how quickly an server response must be obtained
 
785
     * before it is considered failure. For pingpong protocols.
 
786
     */
 
787
    data->set.server_response_timeout = va_arg( param , long ) * 1000;
 
788
    break;
 
789
  case CURLOPT_TFTP_BLKSIZE:
 
790
    /*
 
791
     * TFTP option that specifies the block size to use for data transmission
 
792
     */
 
793
    data->set.tftp_blksize = va_arg(param, long);
 
794
    break;
 
795
  case CURLOPT_DIRLISTONLY:
 
796
    /*
 
797
     * An option that changes the command to one that asks for a list
 
798
     * only, no file info details.
 
799
     */
 
800
    data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
 
801
    break;
 
802
  case CURLOPT_APPEND:
 
803
    /*
 
804
     * We want to upload and append to an existing file.
 
805
     */
 
806
    data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
 
807
    break;
 
808
  case CURLOPT_FTP_FILEMETHOD:
 
809
    /*
 
810
     * How do access files over FTP.
 
811
     */
 
812
    data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
 
813
    break;
 
814
  case CURLOPT_NETRC:
 
815
    /*
 
816
     * Parse the $HOME/.netrc file
 
817
     */
 
818
    data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
 
819
    break;
 
820
  case CURLOPT_NETRC_FILE:
 
821
    /*
 
822
     * Use this file instead of the $HOME/.netrc file
 
823
     */
 
824
    result = setstropt(&data->set.str[STRING_NETRC_FILE],
 
825
                       va_arg(param, char *));
 
826
    break;
 
827
  case CURLOPT_TRANSFERTEXT:
 
828
    /*
 
829
     * This option was previously named 'FTPASCII'. Renamed to work with
 
830
     * more protocols than merely FTP.
 
831
     *
 
832
     * Transfer using ASCII (instead of BINARY).
 
833
     */
 
834
    data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
 
835
    break;
 
836
  case CURLOPT_TIMECONDITION:
 
837
    /*
 
838
     * Set HTTP time condition. This must be one of the defines in the
 
839
     * curl/curl.h header file.
 
840
     */
 
841
    data->set.timecondition = (curl_TimeCond)va_arg(param, long);
 
842
    break;
 
843
  case CURLOPT_TIMEVALUE:
 
844
    /*
 
845
     * This is the value to compare with the remote document with the
 
846
     * method set with CURLOPT_TIMECONDITION
 
847
     */
 
848
    data->set.timevalue = (time_t)va_arg(param, long);
 
849
    break;
 
850
  case CURLOPT_SSLVERSION:
 
851
    /*
 
852
     * Set explicit SSL version to try to connect with, as some SSL
 
853
     * implementations are lame.
 
854
     */
 
855
    data->set.ssl.version = va_arg(param, long);
 
856
    break;
 
857
 
 
858
#ifndef CURL_DISABLE_HTTP
 
859
  case CURLOPT_AUTOREFERER:
 
860
    /*
 
861
     * Switch on automatic referer that gets set if curl follows locations.
 
862
     */
 
863
    data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
 
864
    break;
 
865
 
 
866
  case CURLOPT_ACCEPT_ENCODING:
 
867
    /*
 
868
     * String to use at the value of Accept-Encoding header.
 
869
     *
 
870
     * If the encoding is set to "" we use an Accept-Encoding header that
 
871
     * encompasses all the encodings we support.
 
872
     * If the encoding is set to NULL we don't send an Accept-Encoding header
 
873
     * and ignore an received Content-Encoding header.
 
874
     *
 
875
     */
 
876
    argptr = va_arg(param, char *);
 
877
    result = setstropt(&data->set.str[STRING_ENCODING],
 
878
                       (argptr && !*argptr)?
 
879
                       (char *) ALL_CONTENT_ENCODINGS: argptr);
 
880
    break;
 
881
 
 
882
  case CURLOPT_TRANSFER_ENCODING:
 
883
    data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
 
884
    break;
 
885
 
 
886
  case CURLOPT_FOLLOWLOCATION:
 
887
    /*
 
888
     * Follow Location: header hints on a HTTP-server.
 
889
     */
 
890
    data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
 
891
    break;
 
892
 
 
893
  case CURLOPT_UNRESTRICTED_AUTH:
 
894
    /*
 
895
     * Send authentication (user+password) when following locations, even when
 
896
     * hostname changed.
 
897
     */
 
898
    data->set.http_disable_hostname_check_before_authentication =
 
899
      (0 != va_arg(param, long))?TRUE:FALSE;
 
900
    break;
 
901
 
 
902
  case CURLOPT_MAXREDIRS:
 
903
    /*
 
904
     * The maximum amount of hops you allow curl to follow Location:
 
905
     * headers. This should mostly be used to detect never-ending loops.
 
906
     */
 
907
    data->set.maxredirs = va_arg(param, long);
 
908
    break;
 
909
 
 
910
  case CURLOPT_POSTREDIR:
 
911
  {
 
912
    /*
 
913
     * Set the behaviour of POST when redirecting
 
914
     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
 
915
     * CURL_REDIR_POST_301 - POST is kept as POST after 301
 
916
     * CURL_REDIR_POST_302 - POST is kept as POST after 302
 
917
     * CURL_REDIR_POST_303 - POST is kept as POST after 303
 
918
     * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
 
919
     * other - POST is kept as POST after 301 and 302
 
920
     */
 
921
    int postRedir = curlx_sltosi(va_arg(param, long));
 
922
    data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
 
923
  }
 
924
  break;
 
925
 
 
926
  case CURLOPT_POST:
 
927
    /* Does this option serve a purpose anymore? Yes it does, when
 
928
       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
 
929
       callback! */
 
930
    if(va_arg(param, long)) {
 
931
      data->set.httpreq = HTTPREQ_POST;
 
932
      data->set.opt_no_body = FALSE; /* this is implied */
 
933
    }
 
934
    else
 
935
      data->set.httpreq = HTTPREQ_GET;
 
936
    break;
 
937
 
 
938
  case CURLOPT_COPYPOSTFIELDS:
 
939
    /*
 
940
     * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
 
941
     * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
 
942
     *  CURLOPT_COPYPOSTFIELDS and not altered later.
 
943
     */
 
944
    argptr = va_arg(param, char *);
 
945
 
 
946
    if(!argptr || data->set.postfieldsize == -1)
 
947
      result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
 
948
    else {
 
949
      /*
 
950
       *  Check that requested length does not overflow the size_t type.
 
951
       */
 
952
 
 
953
      if((data->set.postfieldsize < 0) ||
 
954
         ((sizeof(curl_off_t) != sizeof(size_t)) &&
 
955
          (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
 
956
        result = CURLE_OUT_OF_MEMORY;
 
957
      else {
 
958
        char * p;
 
959
 
 
960
        (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
 
961
 
 
962
        /* Allocate even when size == 0. This satisfies the need of possible
 
963
           later address compare to detect the COPYPOSTFIELDS mode, and
 
964
           to mark that postfields is used rather than read function or
 
965
           form data.
 
966
        */
 
967
        p = malloc((size_t)(data->set.postfieldsize?
 
968
                            data->set.postfieldsize:1));
 
969
 
 
970
        if(!p)
 
971
          result = CURLE_OUT_OF_MEMORY;
 
972
        else {
 
973
          if(data->set.postfieldsize)
 
974
            memcpy(p, argptr, (size_t)data->set.postfieldsize);
 
975
 
 
976
          data->set.str[STRING_COPYPOSTFIELDS] = p;
 
977
        }
 
978
      }
 
979
    }
 
980
 
 
981
    data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
 
982
    data->set.httpreq = HTTPREQ_POST;
 
983
    break;
 
984
 
 
985
  case CURLOPT_POSTFIELDS:
 
986
    /*
 
987
     * Like above, but use static data instead of copying it.
 
988
     */
 
989
    data->set.postfields = va_arg(param, void *);
 
990
    /* Release old copied data. */
 
991
    (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
 
992
    data->set.httpreq = HTTPREQ_POST;
 
993
    break;
 
994
 
 
995
  case CURLOPT_POSTFIELDSIZE:
 
996
    /*
 
997
     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
 
998
     * figure it out. Enables binary posts.
 
999
     */
 
1000
    bigsize = va_arg(param, long);
 
1001
 
 
1002
    if(data->set.postfieldsize < bigsize &&
 
1003
       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
 
1004
      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
 
1005
      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
 
1006
      data->set.postfields = NULL;
 
1007
    }
 
1008
 
 
1009
    data->set.postfieldsize = bigsize;
 
1010
    break;
 
1011
 
 
1012
  case CURLOPT_POSTFIELDSIZE_LARGE:
 
1013
    /*
 
1014
     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
 
1015
     * figure it out. Enables binary posts.
 
1016
     */
 
1017
    bigsize = va_arg(param, curl_off_t);
 
1018
 
 
1019
    if(data->set.postfieldsize < bigsize &&
 
1020
       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
 
1021
      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
 
1022
      (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
 
1023
      data->set.postfields = NULL;
 
1024
    }
 
1025
 
 
1026
    data->set.postfieldsize = bigsize;
 
1027
    break;
 
1028
 
 
1029
  case CURLOPT_HTTPPOST:
 
1030
    /*
 
1031
     * Set to make us do HTTP POST
 
1032
     */
 
1033
    data->set.httppost = va_arg(param, struct curl_httppost *);
 
1034
    data->set.httpreq = HTTPREQ_POST_FORM;
 
1035
    data->set.opt_no_body = FALSE; /* this is implied */
 
1036
    break;
 
1037
 
 
1038
  case CURLOPT_REFERER:
 
1039
    /*
 
1040
     * String to set in the HTTP Referer: field.
 
1041
     */
 
1042
    if(data->change.referer_alloc) {
 
1043
      Curl_safefree(data->change.referer);
 
1044
      data->change.referer_alloc = FALSE;
 
1045
    }
 
1046
    result = setstropt(&data->set.str[STRING_SET_REFERER],
 
1047
                       va_arg(param, char *));
 
1048
    data->change.referer = data->set.str[STRING_SET_REFERER];
 
1049
    break;
 
1050
 
 
1051
  case CURLOPT_USERAGENT:
 
1052
    /*
 
1053
     * String to use in the HTTP User-Agent field
 
1054
     */
 
1055
    result = setstropt(&data->set.str[STRING_USERAGENT],
 
1056
                       va_arg(param, char *));
 
1057
    break;
 
1058
 
 
1059
  case CURLOPT_HTTPHEADER:
 
1060
    /*
 
1061
     * Set a list with HTTP headers to use (or replace internals with)
 
1062
     */
 
1063
    data->set.headers = va_arg(param, struct curl_slist *);
 
1064
    break;
 
1065
 
 
1066
  case CURLOPT_HTTP200ALIASES:
 
1067
    /*
 
1068
     * Set a list of aliases for HTTP 200 in response header
 
1069
     */
 
1070
    data->set.http200aliases = va_arg(param, struct curl_slist *);
 
1071
    break;
 
1072
 
 
1073
#if !defined(CURL_DISABLE_COOKIES)
 
1074
  case CURLOPT_COOKIE:
 
1075
    /*
 
1076
     * Cookie string to send to the remote server in the request.
 
1077
     */
 
1078
    result = setstropt(&data->set.str[STRING_COOKIE],
 
1079
                       va_arg(param, char *));
 
1080
    break;
 
1081
 
 
1082
  case CURLOPT_COOKIEFILE:
 
1083
    /*
 
1084
     * Set cookie file to read and parse. Can be used multiple times.
 
1085
     */
 
1086
    argptr = (char *)va_arg(param, void *);
 
1087
    if(argptr) {
 
1088
      struct curl_slist *cl;
 
1089
      /* append the cookie file name to the list of file names, and deal with
 
1090
         them later */
 
1091
      cl = curl_slist_append(data->change.cookielist, argptr);
 
1092
      if(!cl) {
 
1093
        curl_slist_free_all(data->change.cookielist);
 
1094
        data->change.cookielist = NULL;
 
1095
        return CURLE_OUT_OF_MEMORY;
 
1096
      }
 
1097
      data->change.cookielist = cl; /* store the list for later use */
 
1098
    }
 
1099
    break;
 
1100
 
 
1101
  case CURLOPT_COOKIEJAR:
 
1102
    /*
 
1103
     * Set cookie file name to dump all cookies to when we're done.
 
1104
     */
 
1105
    result = setstropt(&data->set.str[STRING_COOKIEJAR],
 
1106
                       va_arg(param, char *));
 
1107
 
 
1108
    /*
 
1109
     * Activate the cookie parser. This may or may not already
 
1110
     * have been made.
 
1111
     */
 
1112
    data->cookies = Curl_cookie_init(data, NULL, data->cookies,
 
1113
                                     data->set.cookiesession);
 
1114
    break;
 
1115
 
 
1116
  case CURLOPT_COOKIESESSION:
 
1117
    /*
 
1118
     * Set this option to TRUE to start a new "cookie session". It will
 
1119
     * prevent the forthcoming read-cookies-from-file actions to accept
 
1120
     * cookies that are marked as being session cookies, as they belong to a
 
1121
     * previous session.
 
1122
     *
 
1123
     * In the original Netscape cookie spec, "session cookies" are cookies
 
1124
     * with no expire date set. RFC2109 describes the same action if no
 
1125
     * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
 
1126
     * a 'Discard' action that can enforce the discard even for cookies that
 
1127
     * have a Max-Age.
 
1128
     *
 
1129
     * We run mostly with the original cookie spec, as hardly anyone implements
 
1130
     * anything else.
 
1131
     */
 
1132
    data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
 
1133
    break;
 
1134
 
 
1135
  case CURLOPT_COOKIELIST:
 
1136
    argptr = va_arg(param, char *);
 
1137
 
 
1138
    if(argptr == NULL)
 
1139
      break;
 
1140
 
 
1141
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
 
1142
 
 
1143
    if(Curl_raw_equal(argptr, "ALL")) {
 
1144
      /* clear all cookies */
 
1145
      Curl_cookie_clearall(data->cookies);
 
1146
    }
 
1147
    else if(Curl_raw_equal(argptr, "SESS")) {
 
1148
      /* clear session cookies */
 
1149
      Curl_cookie_clearsess(data->cookies);
 
1150
    }
 
1151
    else if(Curl_raw_equal(argptr, "FLUSH")) {
 
1152
      /* flush cookies to file */
 
1153
      Curl_flush_cookies(data, 0);
 
1154
    }
 
1155
    else {
 
1156
      if(!data->cookies)
 
1157
        /* if cookie engine was not running, activate it */
 
1158
        data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
 
1159
 
 
1160
      argptr = strdup(argptr);
 
1161
      if(!argptr) {
 
1162
        result = CURLE_OUT_OF_MEMORY;
 
1163
      }
 
1164
      else {
 
1165
 
 
1166
        if(checkprefix("Set-Cookie:", argptr))
 
1167
          /* HTTP Header format line */
 
1168
          Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
 
1169
 
 
1170
        else
 
1171
          /* Netscape format line */
 
1172
          Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
 
1173
 
 
1174
        free(argptr);
 
1175
      }
 
1176
    }
 
1177
    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
 
1178
 
 
1179
    break;
 
1180
#endif /* CURL_DISABLE_COOKIES */
 
1181
 
 
1182
  case CURLOPT_HTTPGET:
 
1183
    /*
 
1184
     * Set to force us do HTTP GET
 
1185
     */
 
1186
    if(va_arg(param, long)) {
 
1187
      data->set.httpreq = HTTPREQ_GET;
 
1188
      data->set.upload = FALSE; /* switch off upload */
 
1189
      data->set.opt_no_body = FALSE; /* this is implied */
 
1190
    }
 
1191
    break;
 
1192
 
 
1193
  case CURLOPT_HTTP_VERSION:
 
1194
    /*
 
1195
     * This sets a requested HTTP version to be used. The value is one of
 
1196
     * the listed enums in curl/curl.h.
 
1197
     */
 
1198
    arg = va_arg(param, long);
 
1199
#ifndef USE_NGHTTP2
 
1200
    if(arg == CURL_HTTP_VERSION_2_0)
 
1201
      return CURLE_UNSUPPORTED_PROTOCOL;
 
1202
#endif
 
1203
    data->set.httpversion = arg;
 
1204
    break;
 
1205
 
 
1206
  case CURLOPT_HTTPAUTH:
 
1207
    /*
 
1208
     * Set HTTP Authentication type BITMASK.
 
1209
     */
 
1210
  {
 
1211
    int bitcheck;
 
1212
    bool authbits;
 
1213
    unsigned long auth = va_arg(param, unsigned long);
 
1214
 
 
1215
    if(auth == CURLAUTH_NONE) {
 
1216
      data->set.httpauth = auth;
 
1217
      break;
 
1218
    }
 
1219
 
 
1220
    /* the DIGEST_IE bit is only used to set a special marker, for all the
 
1221
       rest we need to handle it as normal DIGEST */
 
1222
    data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
 
1223
 
 
1224
    if(auth & CURLAUTH_DIGEST_IE) {
 
1225
      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
 
1226
      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
 
1227
    }
 
1228
 
 
1229
    /* switch off bits we can't support */
 
1230
#ifndef USE_NTLM
 
1231
    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
 
1232
    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
 
1233
#elif !defined(NTLM_WB_ENABLED)
 
1234
    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
 
1235
#endif
 
1236
#ifndef USE_HTTP_NEGOTIATE
 
1237
    auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
 
1238
                                       WINDOWS_SSPI */
 
1239
#endif
 
1240
 
 
1241
    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
 
1242
    bitcheck = 0;
 
1243
    authbits = FALSE;
 
1244
    while(bitcheck < 31) {
 
1245
      if(auth & (1UL << bitcheck++)) {
 
1246
        authbits = TRUE;
 
1247
        break;
 
1248
      }
 
1249
    }
 
1250
    if(!authbits)
 
1251
      return CURLE_NOT_BUILT_IN; /* no supported types left! */
 
1252
 
 
1253
    data->set.httpauth = auth;
 
1254
  }
 
1255
  break;
 
1256
 
 
1257
#endif   /* CURL_DISABLE_HTTP */
 
1258
 
 
1259
  case CURLOPT_CUSTOMREQUEST:
 
1260
    /*
 
1261
     * Set a custom string to use as request
 
1262
     */
 
1263
    result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
 
1264
                       va_arg(param, char *));
 
1265
 
 
1266
    /* we don't set
 
1267
       data->set.httpreq = HTTPREQ_CUSTOM;
 
1268
       here, we continue as if we were using the already set type
 
1269
       and this just changes the actual request keyword */
 
1270
    break;
 
1271
 
 
1272
#ifndef CURL_DISABLE_PROXY
 
1273
  case CURLOPT_HTTPPROXYTUNNEL:
 
1274
    /*
 
1275
     * Tunnel operations through the proxy instead of normal proxy use
 
1276
     */
 
1277
    data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
 
1278
    break;
 
1279
 
 
1280
  case CURLOPT_PROXYPORT:
 
1281
    /*
 
1282
     * Explicitly set HTTP proxy port number.
 
1283
     */
 
1284
    data->set.proxyport = va_arg(param, long);
 
1285
    break;
 
1286
 
 
1287
  case CURLOPT_PROXYAUTH:
 
1288
    /*
 
1289
     * Set HTTP Authentication type BITMASK.
 
1290
     */
 
1291
  {
 
1292
    int bitcheck;
 
1293
    bool authbits;
 
1294
    unsigned long auth = va_arg(param, unsigned long);
 
1295
 
 
1296
    if(auth == CURLAUTH_NONE) {
 
1297
      data->set.proxyauth = auth;
 
1298
      break;
 
1299
    }
 
1300
 
 
1301
    /* the DIGEST_IE bit is only used to set a special marker, for all the
 
1302
       rest we need to handle it as normal DIGEST */
 
1303
    data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
 
1304
 
 
1305
    if(auth & CURLAUTH_DIGEST_IE) {
 
1306
      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
 
1307
      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
 
1308
    }
 
1309
    /* switch off bits we can't support */
 
1310
#ifndef USE_NTLM
 
1311
    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
 
1312
    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
 
1313
#elif !defined(NTLM_WB_ENABLED)
 
1314
    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
 
1315
#endif
 
1316
#ifndef USE_HTTP_NEGOTIATE
 
1317
    auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
 
1318
                                       WINDOWS_SSPI */
 
1319
#endif
 
1320
 
 
1321
    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
 
1322
    bitcheck = 0;
 
1323
    authbits = FALSE;
 
1324
    while(bitcheck < 31) {
 
1325
      if(auth & (1UL << bitcheck++)) {
 
1326
        authbits = TRUE;
 
1327
        break;
 
1328
      }
 
1329
    }
 
1330
    if(!authbits)
 
1331
      return CURLE_NOT_BUILT_IN; /* no supported types left! */
 
1332
 
 
1333
    data->set.proxyauth = auth;
 
1334
  }
 
1335
  break;
 
1336
 
 
1337
  case CURLOPT_PROXY:
 
1338
    /*
 
1339
     * Set proxy server:port to use as HTTP proxy.
 
1340
     *
 
1341
     * If the proxy is set to "" we explicitly say that we don't want to use a
 
1342
     * proxy (even though there might be environment variables saying so).
 
1343
     *
 
1344
     * Setting it to NULL, means no proxy but allows the environment variables
 
1345
     * to decide for us.
 
1346
     */
 
1347
    result = setstropt(&data->set.str[STRING_PROXY],
 
1348
                       va_arg(param, char *));
 
1349
    break;
 
1350
 
 
1351
  case CURLOPT_PROXYTYPE:
 
1352
    /*
 
1353
     * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
 
1354
     */
 
1355
    data->set.proxytype = (curl_proxytype)va_arg(param, long);
 
1356
    break;
 
1357
 
 
1358
  case CURLOPT_PROXY_TRANSFER_MODE:
 
1359
    /*
 
1360
     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
 
1361
     */
 
1362
    switch (va_arg(param, long)) {
 
1363
    case 0:
 
1364
      data->set.proxy_transfer_mode = FALSE;
 
1365
      break;
 
1366
    case 1:
 
1367
      data->set.proxy_transfer_mode = TRUE;
 
1368
      break;
 
1369
    default:
 
1370
      /* reserve other values for future use */
 
1371
      result = CURLE_UNKNOWN_OPTION;
 
1372
      break;
 
1373
    }
 
1374
    break;
 
1375
#endif   /* CURL_DISABLE_PROXY */
 
1376
 
 
1377
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
1378
  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
 
1379
    /*
 
1380
     * Set gssapi service name
 
1381
     */
 
1382
    result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
 
1383
                       va_arg(param, char *));
 
1384
    break;
 
1385
 
 
1386
  case CURLOPT_SOCKS5_GSSAPI_NEC:
 
1387
    /*
 
1388
     * set flag for nec socks5 support
 
1389
     */
 
1390
    data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
 
1391
    break;
 
1392
#endif
 
1393
 
 
1394
  case CURLOPT_WRITEHEADER:
 
1395
    /*
 
1396
     * Custom pointer to pass the header write callback function
 
1397
     */
 
1398
    data->set.writeheader = (void *)va_arg(param, void *);
 
1399
    break;
 
1400
  case CURLOPT_ERRORBUFFER:
 
1401
    /*
 
1402
     * Error buffer provided by the caller to get the human readable
 
1403
     * error string in.
 
1404
     */
 
1405
    data->set.errorbuffer = va_arg(param, char *);
 
1406
    break;
 
1407
  case CURLOPT_FILE:
 
1408
    /*
 
1409
     * FILE pointer to write to. Or possibly
 
1410
     * used as argument to the write callback.
 
1411
     */
 
1412
    data->set.out = va_arg(param, void *);
 
1413
    break;
 
1414
  case CURLOPT_FTPPORT:
 
1415
    /*
 
1416
     * Use FTP PORT, this also specifies which IP address to use
 
1417
     */
 
1418
    result = setstropt(&data->set.str[STRING_FTPPORT],
 
1419
                       va_arg(param, char *));
 
1420
    data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
 
1421
                             TRUE:FALSE;
 
1422
    break;
 
1423
 
 
1424
  case CURLOPT_FTP_USE_EPRT:
 
1425
    data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
 
1426
    break;
 
1427
 
 
1428
  case CURLOPT_FTP_USE_EPSV:
 
1429
    data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
 
1430
    break;
 
1431
 
 
1432
  case CURLOPT_FTP_USE_PRET:
 
1433
    data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
 
1434
    break;
 
1435
 
 
1436
  case CURLOPT_FTP_SSL_CCC:
 
1437
    data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
 
1438
    break;
 
1439
 
 
1440
  case CURLOPT_FTP_SKIP_PASV_IP:
 
1441
    /*
 
1442
     * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
 
1443
     * bypass of the IP address in PASV responses.
 
1444
     */
 
1445
    data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
 
1446
    break;
 
1447
 
 
1448
  case CURLOPT_INFILE:
 
1449
    /*
 
1450
     * FILE pointer to read the file to be uploaded from. Or possibly
 
1451
     * used as argument to the read callback.
 
1452
     */
 
1453
    data->set.in = va_arg(param, void *);
 
1454
    break;
 
1455
  case CURLOPT_INFILESIZE:
 
1456
    /*
 
1457
     * If known, this should inform curl about the file size of the
 
1458
     * to-be-uploaded file.
 
1459
     */
 
1460
    data->set.infilesize = va_arg(param, long);
 
1461
    break;
 
1462
  case CURLOPT_INFILESIZE_LARGE:
 
1463
    /*
 
1464
     * If known, this should inform curl about the file size of the
 
1465
     * to-be-uploaded file.
 
1466
     */
 
1467
    data->set.infilesize = va_arg(param, curl_off_t);
 
1468
    break;
 
1469
  case CURLOPT_LOW_SPEED_LIMIT:
 
1470
    /*
 
1471
     * The low speed limit that if transfers are below this for
 
1472
     * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
 
1473
     */
 
1474
    data->set.low_speed_limit=va_arg(param, long);
 
1475
    break;
 
1476
  case CURLOPT_MAX_SEND_SPEED_LARGE:
 
1477
    /*
 
1478
     * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
 
1479
     * bytes per second the transfer is throttled..
 
1480
     */
 
1481
    data->set.max_send_speed=va_arg(param, curl_off_t);
 
1482
    break;
 
1483
  case CURLOPT_MAX_RECV_SPEED_LARGE:
 
1484
    /*
 
1485
     * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
 
1486
     * second the transfer is throttled..
 
1487
     */
 
1488
    data->set.max_recv_speed=va_arg(param, curl_off_t);
 
1489
    break;
 
1490
  case CURLOPT_LOW_SPEED_TIME:
 
1491
    /*
 
1492
     * The low speed time that if transfers are below the set
 
1493
     * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
 
1494
     */
 
1495
    data->set.low_speed_time=va_arg(param, long);
 
1496
    break;
 
1497
  case CURLOPT_URL:
 
1498
    /*
 
1499
     * The URL to fetch.
 
1500
     */
 
1501
    if(data->change.url_alloc) {
 
1502
      /* the already set URL is allocated, free it first! */
 
1503
      Curl_safefree(data->change.url);
 
1504
      data->change.url_alloc = FALSE;
 
1505
    }
 
1506
    result = setstropt(&data->set.str[STRING_SET_URL],
 
1507
                       va_arg(param, char *));
 
1508
    data->change.url = data->set.str[STRING_SET_URL];
 
1509
    break;
 
1510
  case CURLOPT_PORT:
 
1511
    /*
 
1512
     * The port number to use when getting the URL
 
1513
     */
 
1514
    data->set.use_port = va_arg(param, long);
 
1515
    break;
 
1516
  case CURLOPT_TIMEOUT:
 
1517
    /*
 
1518
     * The maximum time you allow curl to use for a single transfer
 
1519
     * operation.
 
1520
     */
 
1521
    data->set.timeout = va_arg(param, long) * 1000L;
 
1522
    break;
 
1523
 
 
1524
  case CURLOPT_TIMEOUT_MS:
 
1525
    data->set.timeout = va_arg(param, long);
 
1526
    break;
 
1527
 
 
1528
  case CURLOPT_CONNECTTIMEOUT:
 
1529
    /*
 
1530
     * The maximum time you allow curl to use to connect.
 
1531
     */
 
1532
    data->set.connecttimeout = va_arg(param, long) * 1000L;
 
1533
    break;
 
1534
 
 
1535
  case CURLOPT_CONNECTTIMEOUT_MS:
 
1536
    data->set.connecttimeout = va_arg(param, long);
 
1537
    break;
 
1538
 
 
1539
  case CURLOPT_ACCEPTTIMEOUT_MS:
 
1540
    /*
 
1541
     * The maximum time you allow curl to wait for server connect
 
1542
     */
 
1543
    data->set.accepttimeout = va_arg(param, long);
 
1544
    break;
 
1545
 
 
1546
  case CURLOPT_USERPWD:
 
1547
    /*
 
1548
     * user:password to use in the operation
 
1549
     */
 
1550
    result = setstropt_userpwd(va_arg(param, char *),
 
1551
                               &data->set.str[STRING_USERNAME],
 
1552
                               &data->set.str[STRING_PASSWORD]);
 
1553
    break;
 
1554
 
 
1555
  case CURLOPT_USERNAME:
 
1556
    /*
 
1557
     * authentication user name to use in the operation
 
1558
     */
 
1559
    result = setstropt(&data->set.str[STRING_USERNAME],
 
1560
                       va_arg(param, char *));
 
1561
    break;
 
1562
 
 
1563
  case CURLOPT_PASSWORD:
 
1564
    /*
 
1565
     * authentication password to use in the operation
 
1566
     */
 
1567
    result = setstropt(&data->set.str[STRING_PASSWORD],
 
1568
                       va_arg(param, char *));
 
1569
    break;
 
1570
 
 
1571
  case CURLOPT_LOGIN_OPTIONS:
 
1572
    /*
 
1573
     * authentication options to use in the operation
 
1574
     */
 
1575
    result = setstropt(&data->set.str[STRING_OPTIONS],
 
1576
                       va_arg(param, char *));
 
1577
    break;
 
1578
 
 
1579
  case CURLOPT_XOAUTH2_BEARER:
 
1580
    /*
 
1581
     * XOAUTH2 bearer token to use in the operation
 
1582
     */
 
1583
    result = setstropt(&data->set.str[STRING_BEARER],
 
1584
                       va_arg(param, char *));
 
1585
    break;
 
1586
 
 
1587
  case CURLOPT_POSTQUOTE:
 
1588
    /*
 
1589
     * List of RAW FTP commands to use after a transfer
 
1590
     */
 
1591
    data->set.postquote = va_arg(param, struct curl_slist *);
 
1592
    break;
 
1593
  case CURLOPT_PREQUOTE:
 
1594
    /*
 
1595
     * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
 
1596
     */
 
1597
    data->set.prequote = va_arg(param, struct curl_slist *);
 
1598
    break;
 
1599
  case CURLOPT_QUOTE:
 
1600
    /*
 
1601
     * List of RAW FTP commands to use before a transfer
 
1602
     */
 
1603
    data->set.quote = va_arg(param, struct curl_slist *);
 
1604
    break;
 
1605
  case CURLOPT_RESOLVE:
 
1606
    /*
 
1607
     * List of NAME:[address] names to populate the DNS cache with
 
1608
     * Prefix the NAME with dash (-) to _remove_ the name from the cache.
 
1609
     *
 
1610
     * Names added with this API will remain in the cache until explicitly
 
1611
     * removed or the handle is cleaned up.
 
1612
     *
 
1613
     * This API can remove any name from the DNS cache, but only entries
 
1614
     * that aren't actually in use right now will be pruned immediately.
 
1615
     */
 
1616
    data->set.resolve = va_arg(param, struct curl_slist *);
 
1617
    data->change.resolve = data->set.resolve;
 
1618
    break;
 
1619
  case CURLOPT_PROGRESSFUNCTION:
 
1620
    /*
 
1621
     * Progress callback function
 
1622
     */
 
1623
    data->set.fprogress = va_arg(param, curl_progress_callback);
 
1624
    if(data->set.fprogress)
 
1625
      data->progress.callback = TRUE; /* no longer internal */
 
1626
    else
 
1627
      data->progress.callback = FALSE; /* NULL enforces internal */
 
1628
    break;
 
1629
 
 
1630
  case CURLOPT_XFERINFOFUNCTION:
 
1631
    /*
 
1632
     * Transfer info callback function
 
1633
     */
 
1634
    data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
 
1635
    if(data->set.fxferinfo)
 
1636
      data->progress.callback = TRUE; /* no longer internal */
 
1637
    else
 
1638
      data->progress.callback = FALSE; /* NULL enforces internal */
 
1639
 
 
1640
    break;
 
1641
 
 
1642
  case CURLOPT_PROGRESSDATA:
 
1643
    /*
 
1644
     * Custom client data to pass to the progress callback
 
1645
     */
 
1646
    data->set.progress_client = va_arg(param, void *);
 
1647
    break;
 
1648
 
 
1649
#ifndef CURL_DISABLE_PROXY
 
1650
  case CURLOPT_PROXYUSERPWD:
 
1651
    /*
 
1652
     * user:password needed to use the proxy
 
1653
     */
 
1654
    result = setstropt_userpwd(va_arg(param, char *),
 
1655
                               &data->set.str[STRING_PROXYUSERNAME],
 
1656
                               &data->set.str[STRING_PROXYPASSWORD]);
 
1657
    break;
 
1658
  case CURLOPT_PROXYUSERNAME:
 
1659
    /*
 
1660
     * authentication user name to use in the operation
 
1661
     */
 
1662
    result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
 
1663
                       va_arg(param, char *));
 
1664
    break;
 
1665
  case CURLOPT_PROXYPASSWORD:
 
1666
    /*
 
1667
     * authentication password to use in the operation
 
1668
     */
 
1669
    result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
 
1670
                       va_arg(param, char *));
 
1671
    break;
 
1672
  case CURLOPT_NOPROXY:
 
1673
    /*
 
1674
     * proxy exception list
 
1675
     */
 
1676
    result = setstropt(&data->set.str[STRING_NOPROXY],
 
1677
                       va_arg(param, char *));
 
1678
    break;
 
1679
#endif
 
1680
 
 
1681
  case CURLOPT_RANGE:
 
1682
    /*
 
1683
     * What range of the file you want to transfer
 
1684
     */
 
1685
    result = setstropt(&data->set.str[STRING_SET_RANGE],
 
1686
                       va_arg(param, char *));
 
1687
    break;
 
1688
  case CURLOPT_RESUME_FROM:
 
1689
    /*
 
1690
     * Resume transfer at the give file position
 
1691
     */
 
1692
    data->set.set_resume_from = va_arg(param, long);
 
1693
    break;
 
1694
  case CURLOPT_RESUME_FROM_LARGE:
 
1695
    /*
 
1696
     * Resume transfer at the give file position
 
1697
     */
 
1698
    data->set.set_resume_from = va_arg(param, curl_off_t);
 
1699
    break;
 
1700
  case CURLOPT_DEBUGFUNCTION:
 
1701
    /*
 
1702
     * stderr write callback.
 
1703
     */
 
1704
    data->set.fdebug = va_arg(param, curl_debug_callback);
 
1705
    /*
 
1706
     * if the callback provided is NULL, it'll use the default callback
 
1707
     */
 
1708
    break;
 
1709
  case CURLOPT_DEBUGDATA:
 
1710
    /*
 
1711
     * Set to a void * that should receive all error writes. This
 
1712
     * defaults to CURLOPT_STDERR for normal operations.
 
1713
     */
 
1714
    data->set.debugdata = va_arg(param, void *);
 
1715
    break;
 
1716
  case CURLOPT_STDERR:
 
1717
    /*
 
1718
     * Set to a FILE * that should receive all error writes. This
 
1719
     * defaults to stderr for normal operations.
 
1720
     */
 
1721
    data->set.err = va_arg(param, FILE *);
 
1722
    if(!data->set.err)
 
1723
      data->set.err = stderr;
 
1724
    break;
 
1725
  case CURLOPT_HEADERFUNCTION:
 
1726
    /*
 
1727
     * Set header write callback
 
1728
     */
 
1729
    data->set.fwrite_header = va_arg(param, curl_write_callback);
 
1730
    break;
 
1731
  case CURLOPT_WRITEFUNCTION:
 
1732
    /*
 
1733
     * Set data write callback
 
1734
     */
 
1735
    data->set.fwrite_func = va_arg(param, curl_write_callback);
 
1736
    if(!data->set.fwrite_func) {
 
1737
      data->set.is_fwrite_set = 0;
 
1738
      /* When set to NULL, reset to our internal default function */
 
1739
      data->set.fwrite_func = (curl_write_callback)fwrite;
 
1740
    }
 
1741
    else
 
1742
      data->set.is_fwrite_set = 1;
 
1743
    break;
 
1744
  case CURLOPT_READFUNCTION:
 
1745
    /*
 
1746
     * Read data callback
 
1747
     */
 
1748
    data->set.fread_func = va_arg(param, curl_read_callback);
 
1749
    if(!data->set.fread_func) {
 
1750
      data->set.is_fread_set = 0;
 
1751
      /* When set to NULL, reset to our internal default function */
 
1752
      data->set.fread_func = (curl_read_callback)fread;
 
1753
    }
 
1754
    else
 
1755
      data->set.is_fread_set = 1;
 
1756
    break;
 
1757
  case CURLOPT_SEEKFUNCTION:
 
1758
    /*
 
1759
     * Seek callback. Might be NULL.
 
1760
     */
 
1761
    data->set.seek_func = va_arg(param, curl_seek_callback);
 
1762
    break;
 
1763
  case CURLOPT_SEEKDATA:
 
1764
    /*
 
1765
     * Seek control callback. Might be NULL.
 
1766
     */
 
1767
    data->set.seek_client = va_arg(param, void *);
 
1768
    break;
 
1769
  case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
 
1770
    /*
 
1771
     * "Convert from network encoding" callback
 
1772
     */
 
1773
    data->set.convfromnetwork = va_arg(param, curl_conv_callback);
 
1774
    break;
 
1775
  case CURLOPT_CONV_TO_NETWORK_FUNCTION:
 
1776
    /*
 
1777
     * "Convert to network encoding" callback
 
1778
     */
 
1779
    data->set.convtonetwork = va_arg(param, curl_conv_callback);
 
1780
    break;
 
1781
  case CURLOPT_CONV_FROM_UTF8_FUNCTION:
 
1782
    /*
 
1783
     * "Convert from UTF-8 encoding" callback
 
1784
     */
 
1785
    data->set.convfromutf8 = va_arg(param, curl_conv_callback);
 
1786
    break;
 
1787
  case CURLOPT_IOCTLFUNCTION:
 
1788
    /*
 
1789
     * I/O control callback. Might be NULL.
 
1790
     */
 
1791
    data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
 
1792
    break;
 
1793
  case CURLOPT_IOCTLDATA:
 
1794
    /*
 
1795
     * I/O control data pointer. Might be NULL.
 
1796
     */
 
1797
    data->set.ioctl_client = va_arg(param, void *);
 
1798
    break;
 
1799
  case CURLOPT_SSLCERT:
 
1800
    /*
 
1801
     * String that holds file name of the SSL certificate to use
 
1802
     */
 
1803
    result = setstropt(&data->set.str[STRING_CERT],
 
1804
                       va_arg(param, char *));
 
1805
    break;
 
1806
  case CURLOPT_SSLCERTTYPE:
 
1807
    /*
 
1808
     * String that holds file type of the SSL certificate to use
 
1809
     */
 
1810
    result = setstropt(&data->set.str[STRING_CERT_TYPE],
 
1811
                       va_arg(param, char *));
 
1812
    break;
 
1813
  case CURLOPT_SSLKEY:
 
1814
    /*
 
1815
     * String that holds file name of the SSL key to use
 
1816
     */
 
1817
    result = setstropt(&data->set.str[STRING_KEY],
 
1818
                       va_arg(param, char *));
 
1819
    break;
 
1820
  case CURLOPT_SSLKEYTYPE:
 
1821
    /*
 
1822
     * String that holds file type of the SSL key to use
 
1823
     */
 
1824
    result = setstropt(&data->set.str[STRING_KEY_TYPE],
 
1825
                       va_arg(param, char *));
 
1826
    break;
 
1827
  case CURLOPT_KEYPASSWD:
 
1828
    /*
 
1829
     * String that holds the SSL or SSH private key password.
 
1830
     */
 
1831
    result = setstropt(&data->set.str[STRING_KEY_PASSWD],
 
1832
                       va_arg(param, char *));
 
1833
    break;
 
1834
  case CURLOPT_SSLENGINE:
 
1835
    /*
 
1836
     * String that holds the SSL crypto engine.
 
1837
     */
 
1838
    argptr = va_arg(param, char *);
 
1839
    if(argptr && argptr[0])
 
1840
      result = Curl_ssl_set_engine(data, argptr);
 
1841
    break;
 
1842
 
 
1843
  case CURLOPT_SSLENGINE_DEFAULT:
 
1844
    /*
 
1845
     * flag to set engine as default.
 
1846
     */
 
1847
    result = Curl_ssl_set_engine_default(data);
 
1848
    break;
 
1849
  case CURLOPT_CRLF:
 
1850
    /*
 
1851
     * Kludgy option to enable CRLF conversions. Subject for removal.
 
1852
     */
 
1853
    data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
 
1854
    break;
 
1855
 
 
1856
  case CURLOPT_INTERFACE:
 
1857
    /*
 
1858
     * Set what interface or address/hostname to bind the socket to when
 
1859
     * performing an operation and thus what from-IP your connection will use.
 
1860
     */
 
1861
    result = setstropt(&data->set.str[STRING_DEVICE],
 
1862
                       va_arg(param, char *));
 
1863
    break;
 
1864
  case CURLOPT_LOCALPORT:
 
1865
    /*
 
1866
     * Set what local port to bind the socket to when performing an operation.
 
1867
     */
 
1868
    data->set.localport = curlx_sltous(va_arg(param, long));
 
1869
    break;
 
1870
  case CURLOPT_LOCALPORTRANGE:
 
1871
    /*
 
1872
     * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
 
1873
     */
 
1874
    data->set.localportrange = curlx_sltosi(va_arg(param, long));
 
1875
    break;
 
1876
  case CURLOPT_KRBLEVEL:
 
1877
    /*
 
1878
     * A string that defines the kerberos security level.
 
1879
     */
 
1880
    result = setstropt(&data->set.str[STRING_KRB_LEVEL],
 
1881
                       va_arg(param, char *));
 
1882
    data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
 
1883
    break;
 
1884
  case CURLOPT_GSSAPI_DELEGATION:
 
1885
    /*
 
1886
     * GSSAPI credential delegation
 
1887
     */
 
1888
    data->set.gssapi_delegation = va_arg(param, long);
 
1889
    break;
 
1890
  case CURLOPT_SSL_VERIFYPEER:
 
1891
    /*
 
1892
     * Enable peer SSL verifying.
 
1893
     */
 
1894
    data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
 
1895
    break;
 
1896
  case CURLOPT_SSL_VERIFYHOST:
 
1897
    /*
 
1898
     * Enable verification of the host name in the peer certificate
 
1899
     */
 
1900
    arg = va_arg(param, long);
 
1901
 
 
1902
    /* Obviously people are not reading documentation and too many thought
 
1903
       this argument took a boolean when it wasn't and misused it. We thus ban
 
1904
       1 as a sensible input and we warn about its use. Then we only have the
 
1905
       2 action internally stored as TRUE. */
 
1906
 
 
1907
    if(1 == arg) {
 
1908
      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
 
1909
      return CURLE_BAD_FUNCTION_ARGUMENT;
 
1910
    }
 
1911
 
 
1912
    data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
 
1913
    break;
 
1914
#ifdef USE_SSLEAY
 
1915
    /* since these two options are only possible to use on an OpenSSL-
 
1916
       powered libcurl we #ifdef them on this condition so that libcurls
 
1917
       built against other SSL libs will return a proper error when trying
 
1918
       to set this option! */
 
1919
  case CURLOPT_SSL_CTX_FUNCTION:
 
1920
    /*
 
1921
     * Set a SSL_CTX callback
 
1922
     */
 
1923
    data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
 
1924
    break;
 
1925
  case CURLOPT_SSL_CTX_DATA:
 
1926
    /*
 
1927
     * Set a SSL_CTX callback parameter pointer
 
1928
     */
 
1929
    data->set.ssl.fsslctxp = va_arg(param, void *);
 
1930
    break;
 
1931
#endif
 
1932
#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT) || \
 
1933
    defined(USE_NSS)
 
1934
  case CURLOPT_CERTINFO:
 
1935
    data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
 
1936
    break;
 
1937
#endif
 
1938
  case CURLOPT_CAINFO:
 
1939
    /*
 
1940
     * Set CA info for SSL connection. Specify file name of the CA certificate
 
1941
     */
 
1942
    result = setstropt(&data->set.str[STRING_SSL_CAFILE],
 
1943
                       va_arg(param, char *));
 
1944
    break;
 
1945
  case CURLOPT_CAPATH:
 
1946
    /*
 
1947
     * Set CA path info for SSL connection. Specify directory name of the CA
 
1948
     * certificates which have been prepared using openssl c_rehash utility.
 
1949
     */
 
1950
    /* This does not work on windows. */
 
1951
    result = setstropt(&data->set.str[STRING_SSL_CAPATH],
 
1952
                       va_arg(param, char *));
 
1953
    break;
 
1954
  case CURLOPT_CRLFILE:
 
1955
    /*
 
1956
     * Set CRL file info for SSL connection. Specify file name of the CRL
 
1957
     * to check certificates revocation
 
1958
     */
 
1959
    result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
 
1960
                       va_arg(param, char *));
 
1961
    break;
 
1962
  case CURLOPT_ISSUERCERT:
 
1963
    /*
 
1964
     * Set Issuer certificate file
 
1965
     * to check certificates issuer
 
1966
     */
 
1967
    result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
 
1968
                       va_arg(param, char *));
 
1969
    break;
 
1970
  case CURLOPT_TELNETOPTIONS:
 
1971
    /*
 
1972
     * Set a linked list of telnet options
 
1973
     */
 
1974
    data->set.telnet_options = va_arg(param, struct curl_slist *);
 
1975
    break;
 
1976
 
 
1977
  case CURLOPT_BUFFERSIZE:
 
1978
    /*
 
1979
     * The application kindly asks for a differently sized receive buffer.
 
1980
     * If it seems reasonable, we'll use it.
 
1981
     */
 
1982
    data->set.buffer_size = va_arg(param, long);
 
1983
 
 
1984
    if((data->set.buffer_size> (BUFSIZE -1 )) ||
 
1985
       (data->set.buffer_size < 1))
 
1986
      data->set.buffer_size = 0; /* huge internal default */
 
1987
 
 
1988
    break;
 
1989
 
 
1990
  case CURLOPT_NOSIGNAL:
 
1991
    /*
 
1992
     * The application asks not to set any signal() or alarm() handlers,
 
1993
     * even when using a timeout.
 
1994
     */
 
1995
    data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
 
1996
    break;
 
1997
 
 
1998
  case CURLOPT_SHARE:
 
1999
  {
 
2000
    struct Curl_share *set;
 
2001
    set = va_arg(param, struct Curl_share *);
 
2002
 
 
2003
    /* disconnect from old share, if any */
 
2004
    if(data->share) {
 
2005
      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
 
2006
 
 
2007
      if(data->dns.hostcachetype == HCACHE_SHARED) {
 
2008
        data->dns.hostcache = NULL;
 
2009
        data->dns.hostcachetype = HCACHE_NONE;
 
2010
      }
 
2011
 
 
2012
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 
2013
      if(data->share->cookies == data->cookies)
 
2014
        data->cookies = NULL;
 
2015
#endif
 
2016
 
 
2017
      if(data->share->sslsession == data->state.session)
 
2018
        data->state.session = NULL;
 
2019
 
 
2020
      data->share->dirty--;
 
2021
 
 
2022
      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
 
2023
      data->share = NULL;
 
2024
    }
 
2025
 
 
2026
    /* use new share if it set */
 
2027
    data->share = set;
 
2028
    if(data->share) {
 
2029
 
 
2030
      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
 
2031
 
 
2032
      data->share->dirty++;
 
2033
 
 
2034
      if(data->share->hostcache) {
 
2035
        /* use shared host cache */
 
2036
        data->dns.hostcache = data->share->hostcache;
 
2037
        data->dns.hostcachetype = HCACHE_SHARED;
 
2038
      }
 
2039
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 
2040
      if(data->share->cookies) {
 
2041
        /* use shared cookie list, first free own one if any */
 
2042
        if(data->cookies)
 
2043
          Curl_cookie_cleanup(data->cookies);
 
2044
        /* enable cookies since we now use a share that uses cookies! */
 
2045
        data->cookies = data->share->cookies;
 
2046
      }
 
2047
#endif   /* CURL_DISABLE_HTTP */
 
2048
      if(data->share->sslsession) {
 
2049
        data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
 
2050
        data->state.session = data->share->sslsession;
 
2051
      }
 
2052
      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
 
2053
 
 
2054
    }
 
2055
    /* check for host cache not needed,
 
2056
     * it will be done by curl_easy_perform */
 
2057
  }
 
2058
  break;
 
2059
 
 
2060
  case CURLOPT_PRIVATE:
 
2061
    /*
 
2062
     * Set private data pointer.
 
2063
     */
 
2064
    data->set.private_data = va_arg(param, void *);
 
2065
    break;
 
2066
 
 
2067
  case CURLOPT_MAXFILESIZE:
 
2068
    /*
 
2069
     * Set the maximum size of a file to download.
 
2070
     */
 
2071
    data->set.max_filesize = va_arg(param, long);
 
2072
    break;
 
2073
 
 
2074
#ifdef USE_SSL
 
2075
  case CURLOPT_USE_SSL:
 
2076
    /*
 
2077
     * Make transfers attempt to use SSL/TLS.
 
2078
     */
 
2079
    data->set.use_ssl = (curl_usessl)va_arg(param, long);
 
2080
    break;
 
2081
 
 
2082
  case CURLOPT_SSL_OPTIONS:
 
2083
    arg = va_arg(param, long);
 
2084
    data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
 
2085
    break;
 
2086
 
 
2087
#endif
 
2088
  case CURLOPT_FTPSSLAUTH:
 
2089
    /*
 
2090
     * Set a specific auth for FTP-SSL transfers.
 
2091
     */
 
2092
    data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
 
2093
    break;
 
2094
 
 
2095
  case CURLOPT_IPRESOLVE:
 
2096
    data->set.ipver = va_arg(param, long);
 
2097
    break;
 
2098
 
 
2099
  case CURLOPT_MAXFILESIZE_LARGE:
 
2100
    /*
 
2101
     * Set the maximum size of a file to download.
 
2102
     */
 
2103
    data->set.max_filesize = va_arg(param, curl_off_t);
 
2104
    break;
 
2105
 
 
2106
  case CURLOPT_TCP_NODELAY:
 
2107
    /*
 
2108
     * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
 
2109
     * algorithm
 
2110
     */
 
2111
    data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
 
2112
    break;
 
2113
 
 
2114
  case CURLOPT_FTP_ACCOUNT:
 
2115
    result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
 
2116
                       va_arg(param, char *));
 
2117
    break;
 
2118
 
 
2119
  case CURLOPT_IGNORE_CONTENT_LENGTH:
 
2120
    data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
 
2121
    break;
 
2122
 
 
2123
  case CURLOPT_CONNECT_ONLY:
 
2124
    /*
 
2125
     * No data transfer, set up connection and let application use the socket
 
2126
     */
 
2127
    data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
 
2128
    break;
 
2129
 
 
2130
  case CURLOPT_FTP_ALTERNATIVE_TO_USER:
 
2131
    result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
 
2132
                       va_arg(param, char *));
 
2133
    break;
 
2134
 
 
2135
  case CURLOPT_SOCKOPTFUNCTION:
 
2136
    /*
 
2137
     * socket callback function: called after socket() but before connect()
 
2138
     */
 
2139
    data->set.fsockopt = va_arg(param, curl_sockopt_callback);
 
2140
    break;
 
2141
 
 
2142
  case CURLOPT_SOCKOPTDATA:
 
2143
    /*
 
2144
     * socket callback data pointer. Might be NULL.
 
2145
     */
 
2146
    data->set.sockopt_client = va_arg(param, void *);
 
2147
    break;
 
2148
 
 
2149
  case CURLOPT_OPENSOCKETFUNCTION:
 
2150
    /*
 
2151
     * open/create socket callback function: called instead of socket(),
 
2152
     * before connect()
 
2153
     */
 
2154
    data->set.fopensocket = va_arg(param, curl_opensocket_callback);
 
2155
    break;
 
2156
 
 
2157
  case CURLOPT_OPENSOCKETDATA:
 
2158
    /*
 
2159
     * socket callback data pointer. Might be NULL.
 
2160
     */
 
2161
    data->set.opensocket_client = va_arg(param, void *);
 
2162
    break;
 
2163
 
 
2164
  case CURLOPT_CLOSESOCKETFUNCTION:
 
2165
    /*
 
2166
     * close socket callback function: called instead of close()
 
2167
     * when shutting down a connection
 
2168
     */
 
2169
    data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
 
2170
    break;
 
2171
 
 
2172
  case CURLOPT_CLOSESOCKETDATA:
 
2173
    /*
 
2174
     * socket callback data pointer. Might be NULL.
 
2175
     */
 
2176
    data->set.closesocket_client = va_arg(param, void *);
 
2177
    break;
 
2178
 
 
2179
  case CURLOPT_SSL_SESSIONID_CACHE:
 
2180
    data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
 
2181
    break;
 
2182
 
 
2183
#ifdef USE_LIBSSH2
 
2184
    /* we only include SSH options if explicitly built to support SSH */
 
2185
  case CURLOPT_SSH_AUTH_TYPES:
 
2186
    data->set.ssh_auth_types = va_arg(param, long);
 
2187
    break;
 
2188
 
 
2189
  case CURLOPT_SSH_PUBLIC_KEYFILE:
 
2190
    /*
 
2191
     * Use this file instead of the $HOME/.ssh/id_dsa.pub file
 
2192
     */
 
2193
    result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
 
2194
                       va_arg(param, char *));
 
2195
    break;
 
2196
 
 
2197
  case CURLOPT_SSH_PRIVATE_KEYFILE:
 
2198
    /*
 
2199
     * Use this file instead of the $HOME/.ssh/id_dsa file
 
2200
     */
 
2201
    result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
 
2202
                       va_arg(param, char *));
 
2203
    break;
 
2204
  case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
 
2205
    /*
 
2206
     * Option to allow for the MD5 of the host public key to be checked
 
2207
     * for validation purposes.
 
2208
     */
 
2209
    result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
 
2210
                       va_arg(param, char *));
 
2211
    break;
 
2212
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
 
2213
  case CURLOPT_SSH_KNOWNHOSTS:
 
2214
    /*
 
2215
     * Store the file name to read known hosts from.
 
2216
     */
 
2217
    result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
 
2218
                       va_arg(param, char *));
 
2219
    break;
 
2220
 
 
2221
  case CURLOPT_SSH_KEYFUNCTION:
 
2222
    /* setting to NULL is fine since the ssh.c functions themselves will
 
2223
       then rever to use the internal default */
 
2224
    data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
 
2225
    break;
 
2226
 
 
2227
  case CURLOPT_SSH_KEYDATA:
 
2228
    /*
 
2229
     * Custom client data to pass to the SSH keyfunc callback
 
2230
     */
 
2231
    data->set.ssh_keyfunc_userp = va_arg(param, void *);
 
2232
    break;
 
2233
#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
 
2234
 
 
2235
#endif /* USE_LIBSSH2 */
 
2236
 
 
2237
  case CURLOPT_HTTP_TRANSFER_DECODING:
 
2238
    /*
 
2239
     * disable libcurl transfer encoding is used
 
2240
     */
 
2241
    data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
 
2242
    break;
 
2243
 
 
2244
  case CURLOPT_HTTP_CONTENT_DECODING:
 
2245
    /*
 
2246
     * raw data passed to the application when content encoding is used
 
2247
     */
 
2248
    data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
 
2249
    break;
 
2250
 
 
2251
  case CURLOPT_NEW_FILE_PERMS:
 
2252
    /*
 
2253
     * Uses these permissions instead of 0644
 
2254
     */
 
2255
    data->set.new_file_perms = va_arg(param, long);
 
2256
    break;
 
2257
 
 
2258
  case CURLOPT_NEW_DIRECTORY_PERMS:
 
2259
    /*
 
2260
     * Uses these permissions instead of 0755
 
2261
     */
 
2262
    data->set.new_directory_perms = va_arg(param, long);
 
2263
    break;
 
2264
 
 
2265
  case CURLOPT_ADDRESS_SCOPE:
 
2266
    /*
 
2267
     * We always get longs when passed plain numericals, but for this value we
 
2268
     * know that an unsigned int will always hold the value so we blindly
 
2269
     * typecast to this type
 
2270
     */
 
2271
    data->set.scope = curlx_sltoui(va_arg(param, long));
 
2272
    break;
 
2273
 
 
2274
  case CURLOPT_PROTOCOLS:
 
2275
    /* set the bitmask for the protocols that are allowed to be used for the
 
2276
       transfer, which thus helps the app which takes URLs from users or other
 
2277
       external inputs and want to restrict what protocol(s) to deal
 
2278
       with. Defaults to CURLPROTO_ALL. */
 
2279
    data->set.allowed_protocols = va_arg(param, long);
 
2280
    break;
 
2281
 
 
2282
  case CURLOPT_REDIR_PROTOCOLS:
 
2283
    /* set the bitmask for the protocols that libcurl is allowed to follow to,
 
2284
       as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
 
2285
       to be set in both bitmasks to be allowed to get redirected to. Defaults
 
2286
       to all protocols except FILE and SCP. */
 
2287
    data->set.redir_protocols = va_arg(param, long);
 
2288
    break;
 
2289
 
 
2290
  case CURLOPT_MAIL_FROM:
 
2291
    /* Set the SMTP mail originator */
 
2292
    result = setstropt(&data->set.str[STRING_MAIL_FROM],
 
2293
                       va_arg(param, char *));
 
2294
    break;
 
2295
 
 
2296
  case CURLOPT_MAIL_AUTH:
 
2297
    /* Set the SMTP auth originator */
 
2298
    result = setstropt(&data->set.str[STRING_MAIL_AUTH],
 
2299
                       va_arg(param, char *));
 
2300
    break;
 
2301
 
 
2302
  case CURLOPT_MAIL_RCPT:
 
2303
    /* Set the list of mail recipients */
 
2304
    data->set.mail_rcpt = va_arg(param, struct curl_slist *);
 
2305
    break;
 
2306
 
 
2307
  case CURLOPT_SASL_IR:
 
2308
    /* Enable/disable SASL initial response */
 
2309
    data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
 
2310
    break;
 
2311
 
 
2312
  case CURLOPT_RTSP_REQUEST:
 
2313
    {
 
2314
      /*
 
2315
       * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
 
2316
       * Would this be better if the RTSPREQ_* were just moved into here?
 
2317
       */
 
2318
      long curl_rtspreq = va_arg(param, long);
 
2319
      Curl_RtspReq rtspreq = RTSPREQ_NONE;
 
2320
      switch(curl_rtspreq) {
 
2321
        case CURL_RTSPREQ_OPTIONS:
 
2322
          rtspreq = RTSPREQ_OPTIONS;
 
2323
          break;
 
2324
 
 
2325
        case CURL_RTSPREQ_DESCRIBE:
 
2326
          rtspreq = RTSPREQ_DESCRIBE;
 
2327
          break;
 
2328
 
 
2329
        case CURL_RTSPREQ_ANNOUNCE:
 
2330
          rtspreq = RTSPREQ_ANNOUNCE;
 
2331
          break;
 
2332
 
 
2333
        case CURL_RTSPREQ_SETUP:
 
2334
          rtspreq = RTSPREQ_SETUP;
 
2335
          break;
 
2336
 
 
2337
        case CURL_RTSPREQ_PLAY:
 
2338
          rtspreq = RTSPREQ_PLAY;
 
2339
          break;
 
2340
 
 
2341
        case CURL_RTSPREQ_PAUSE:
 
2342
          rtspreq = RTSPREQ_PAUSE;
 
2343
          break;
 
2344
 
 
2345
        case CURL_RTSPREQ_TEARDOWN:
 
2346
          rtspreq = RTSPREQ_TEARDOWN;
 
2347
          break;
 
2348
 
 
2349
        case CURL_RTSPREQ_GET_PARAMETER:
 
2350
          rtspreq = RTSPREQ_GET_PARAMETER;
 
2351
          break;
 
2352
 
 
2353
        case CURL_RTSPREQ_SET_PARAMETER:
 
2354
          rtspreq = RTSPREQ_SET_PARAMETER;
 
2355
          break;
 
2356
 
 
2357
        case CURL_RTSPREQ_RECORD:
 
2358
          rtspreq = RTSPREQ_RECORD;
 
2359
          break;
 
2360
 
 
2361
        case CURL_RTSPREQ_RECEIVE:
 
2362
          rtspreq = RTSPREQ_RECEIVE;
 
2363
          break;
 
2364
        default:
 
2365
          rtspreq = RTSPREQ_NONE;
 
2366
      }
 
2367
 
 
2368
      data->set.rtspreq = rtspreq;
 
2369
    break;
 
2370
    }
 
2371
 
 
2372
 
 
2373
  case CURLOPT_RTSP_SESSION_ID:
 
2374
    /*
 
2375
     * Set the RTSP Session ID manually. Useful if the application is
 
2376
     * resuming a previously established RTSP session
 
2377
     */
 
2378
    result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
 
2379
                       va_arg(param, char *));
 
2380
    break;
 
2381
 
 
2382
  case CURLOPT_RTSP_STREAM_URI:
 
2383
    /*
 
2384
     * Set the Stream URI for the RTSP request. Unless the request is
 
2385
     * for generic server options, the application will need to set this.
 
2386
     */
 
2387
    result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
 
2388
                       va_arg(param, char *));
 
2389
    break;
 
2390
 
 
2391
  case CURLOPT_RTSP_TRANSPORT:
 
2392
    /*
 
2393
     * The content of the Transport: header for the RTSP request
 
2394
     */
 
2395
    result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
 
2396
                       va_arg(param, char *));
 
2397
    break;
 
2398
 
 
2399
  case CURLOPT_RTSP_CLIENT_CSEQ:
 
2400
    /*
 
2401
     * Set the CSEQ number to issue for the next RTSP request. Useful if the
 
2402
     * application is resuming a previously broken connection. The CSEQ
 
2403
     * will increment from this new number henceforth.
 
2404
     */
 
2405
    data->state.rtsp_next_client_CSeq = va_arg(param, long);
 
2406
    break;
 
2407
 
 
2408
  case CURLOPT_RTSP_SERVER_CSEQ:
 
2409
    /* Same as the above, but for server-initiated requests */
 
2410
    data->state.rtsp_next_client_CSeq = va_arg(param, long);
 
2411
    break;
 
2412
 
 
2413
  case CURLOPT_INTERLEAVEDATA:
 
2414
    data->set.rtp_out = va_arg(param, void *);
 
2415
    break;
 
2416
  case CURLOPT_INTERLEAVEFUNCTION:
 
2417
    /* Set the user defined RTP write function */
 
2418
    data->set.fwrite_rtp = va_arg(param, curl_write_callback);
 
2419
    break;
 
2420
 
 
2421
  case CURLOPT_WILDCARDMATCH:
 
2422
    data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
 
2423
    break;
 
2424
  case CURLOPT_CHUNK_BGN_FUNCTION:
 
2425
    data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
 
2426
    break;
 
2427
  case CURLOPT_CHUNK_END_FUNCTION:
 
2428
    data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
 
2429
    break;
 
2430
  case CURLOPT_FNMATCH_FUNCTION:
 
2431
    data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
 
2432
    break;
 
2433
  case CURLOPT_CHUNK_DATA:
 
2434
    data->wildcard.customptr = va_arg(param, void *);
 
2435
    break;
 
2436
  case CURLOPT_FNMATCH_DATA:
 
2437
    data->set.fnmatch_data = va_arg(param, void *);
 
2438
    break;
 
2439
#ifdef USE_TLS_SRP
 
2440
  case CURLOPT_TLSAUTH_USERNAME:
 
2441
    result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
 
2442
                       va_arg(param, char *));
 
2443
    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
 
2444
      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
 
2445
    break;
 
2446
  case CURLOPT_TLSAUTH_PASSWORD:
 
2447
    result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
 
2448
                       va_arg(param, char *));
 
2449
    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
 
2450
      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
 
2451
    break;
 
2452
  case CURLOPT_TLSAUTH_TYPE:
 
2453
    if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
 
2454
      data->set.ssl.authtype = CURL_TLSAUTH_SRP;
 
2455
    else
 
2456
      data->set.ssl.authtype = CURL_TLSAUTH_NONE;
 
2457
    break;
 
2458
#endif
 
2459
  case CURLOPT_DNS_SERVERS:
 
2460
    result = Curl_set_dns_servers(data, va_arg(param, char *));
 
2461
    break;
 
2462
  case CURLOPT_DNS_INTERFACE:
 
2463
    result = Curl_set_dns_interface(data, va_arg(param, char *));
 
2464
    break;
 
2465
  case CURLOPT_DNS_LOCAL_IP4:
 
2466
    result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
 
2467
    break;
 
2468
  case CURLOPT_DNS_LOCAL_IP6:
 
2469
    result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
 
2470
    break;
 
2471
 
 
2472
  case CURLOPT_TCP_KEEPALIVE:
 
2473
    data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
 
2474
    break;
 
2475
  case CURLOPT_TCP_KEEPIDLE:
 
2476
    data->set.tcp_keepidle = va_arg(param, long);
 
2477
    break;
 
2478
  case CURLOPT_TCP_KEEPINTVL:
 
2479
    data->set.tcp_keepintvl = va_arg(param, long);
 
2480
    break;
 
2481
 
 
2482
  default:
 
2483
    /* unknown tag and its companion, just ignore: */
 
2484
    result = CURLE_UNKNOWN_OPTION;
 
2485
    break;
 
2486
  }
 
2487
 
 
2488
  return result;
 
2489
}
 
2490
 
 
2491
static void conn_free(struct connectdata *conn)
 
2492
{
 
2493
  if(!conn)
 
2494
    return;
 
2495
 
 
2496
  /* possible left-overs from the async name resolvers */
 
2497
  Curl_resolver_cancel(conn);
 
2498
 
 
2499
  /* close the SSL stuff before we close any sockets since they will/may
 
2500
     write to the sockets */
 
2501
  Curl_ssl_close(conn, FIRSTSOCKET);
 
2502
  Curl_ssl_close(conn, SECONDARYSOCKET);
 
2503
 
 
2504
  /* close possibly still open sockets */
 
2505
  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
 
2506
    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
 
2507
  if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
 
2508
    Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
 
2509
  if(CURL_SOCKET_BAD != conn->tempsock[0])
 
2510
    Curl_closesocket(conn, conn->tempsock[0]);
 
2511
  if(CURL_SOCKET_BAD != conn->tempsock[1])
 
2512
    Curl_closesocket(conn, conn->tempsock[1]);
 
2513
 
 
2514
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
 
2515
  Curl_ntlm_wb_cleanup(conn);
 
2516
#endif
 
2517
 
 
2518
  Curl_safefree(conn->user);
 
2519
  Curl_safefree(conn->passwd);
 
2520
  Curl_safefree(conn->xoauth2_bearer);
 
2521
  Curl_safefree(conn->options);
 
2522
  Curl_safefree(conn->proxyuser);
 
2523
  Curl_safefree(conn->proxypasswd);
 
2524
  Curl_safefree(conn->allocptr.proxyuserpwd);
 
2525
  Curl_safefree(conn->allocptr.uagent);
 
2526
  Curl_safefree(conn->allocptr.userpwd);
 
2527
  Curl_safefree(conn->allocptr.accept_encoding);
 
2528
  Curl_safefree(conn->allocptr.te);
 
2529
  Curl_safefree(conn->allocptr.rangeline);
 
2530
  Curl_safefree(conn->allocptr.ref);
 
2531
  Curl_safefree(conn->allocptr.host);
 
2532
  Curl_safefree(conn->allocptr.cookiehost);
 
2533
  Curl_safefree(conn->allocptr.rtsp_transport);
 
2534
  Curl_safefree(conn->trailer);
 
2535
  Curl_safefree(conn->host.rawalloc); /* host name buffer */
 
2536
  Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
 
2537
  Curl_safefree(conn->master_buffer);
 
2538
 
 
2539
  Curl_llist_destroy(conn->send_pipe, NULL);
 
2540
  Curl_llist_destroy(conn->recv_pipe, NULL);
 
2541
 
 
2542
  conn->send_pipe = NULL;
 
2543
  conn->recv_pipe = NULL;
 
2544
 
 
2545
  Curl_safefree(conn->localdev);
 
2546
  Curl_free_ssl_config(&conn->ssl_config);
 
2547
 
 
2548
  free(conn); /* free all the connection oriented data */
 
2549
}
 
2550
 
 
2551
CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
 
2552
{
 
2553
  struct SessionHandle *data;
 
2554
  if(!conn)
 
2555
    return CURLE_OK; /* this is closed and fine already */
 
2556
  data = conn->data;
 
2557
 
 
2558
  if(!data) {
 
2559
    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
 
2560
    return CURLE_OK;
 
2561
  }
 
2562
 
 
2563
  if(conn->dns_entry != NULL) {
 
2564
    Curl_resolv_unlock(data, conn->dns_entry);
 
2565
    conn->dns_entry = NULL;
 
2566
  }
 
2567
 
 
2568
  Curl_hostcache_prune(data); /* kill old DNS cache entries */
 
2569
 
 
2570
  {
 
2571
    int has_host_ntlm = (conn->ntlm.state != NTLMSTATE_NONE);
 
2572
    int has_proxy_ntlm = (conn->proxyntlm.state != NTLMSTATE_NONE);
 
2573
 
 
2574
    /* Authentication data is a mix of connection-related and sessionhandle-
 
2575
       related stuff. NTLM is connection-related so when we close the shop
 
2576
       we shall forget. */
 
2577
 
 
2578
    if(has_host_ntlm) {
 
2579
      data->state.authhost.done = FALSE;
 
2580
      data->state.authhost.picked =
 
2581
        data->state.authhost.want;
 
2582
    }
 
2583
 
 
2584
    if(has_proxy_ntlm) {
 
2585
      data->state.authproxy.done = FALSE;
 
2586
      data->state.authproxy.picked =
 
2587
        data->state.authproxy.want;
 
2588
    }
 
2589
 
 
2590
    if(has_host_ntlm || has_proxy_ntlm)
 
2591
      data->state.authproblem = FALSE;
 
2592
  }
 
2593
 
 
2594
  /* Cleanup NTLM connection-related data */
 
2595
  Curl_http_ntlm_cleanup(conn);
 
2596
 
 
2597
  /* Cleanup possible redirect junk */
 
2598
  if(data->req.newurl) {
 
2599
    free(data->req.newurl);
 
2600
    data->req.newurl = NULL;
 
2601
  }
 
2602
 
 
2603
  if(conn->handler->disconnect)
 
2604
    /* This is set if protocol-specific cleanups should be made */
 
2605
    conn->handler->disconnect(conn, dead_connection);
 
2606
 
 
2607
    /* unlink ourselves! */
 
2608
  infof(data, "Closing connection %ld\n", conn->connection_id);
 
2609
  Curl_conncache_remove_conn(data->state.conn_cache, conn);
 
2610
 
 
2611
#if defined(USE_LIBIDN)
 
2612
  if(conn->host.encalloc)
 
2613
    idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
 
2614
                                      with idn_free() since this was allocated
 
2615
                                      by libidn */
 
2616
  if(conn->proxy.encalloc)
 
2617
    idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
 
2618
                                       freed with idn_free() since this was
 
2619
                                       allocated by libidn */
 
2620
#elif defined(USE_WIN32_IDN)
 
2621
  free(conn->host.encalloc); /* encoded host name buffer, must be freed with
 
2622
                                idn_free() since this was allocated by
 
2623
                                curl_win32_idn_to_ascii */
 
2624
  if(conn->proxy.encalloc)
 
2625
    free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
 
2626
                                   with idn_free() since this was allocated by
 
2627
                                   curl_win32_idn_to_ascii */
 
2628
#endif
 
2629
 
 
2630
  Curl_ssl_close(conn, FIRSTSOCKET);
 
2631
 
 
2632
  /* Indicate to all handles on the pipe that we're dead */
 
2633
  if(Curl_multi_pipeline_enabled(data->multi)) {
 
2634
    signalPipeClose(conn->send_pipe, TRUE);
 
2635
    signalPipeClose(conn->recv_pipe, TRUE);
 
2636
  }
 
2637
 
 
2638
  conn_free(conn);
 
2639
 
 
2640
  Curl_speedinit(data);
 
2641
 
 
2642
  return CURLE_OK;
 
2643
}
 
2644
 
 
2645
/*
 
2646
 * This function should return TRUE if the socket is to be assumed to
 
2647
 * be dead. Most commonly this happens when the server has closed the
 
2648
 * connection due to inactivity.
 
2649
 */
 
2650
static bool SocketIsDead(curl_socket_t sock)
 
2651
{
 
2652
  int sval;
 
2653
  bool ret_val = TRUE;
 
2654
 
 
2655
  sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
 
2656
  if(sval == 0)
 
2657
    /* timeout */
 
2658
    ret_val = FALSE;
 
2659
 
 
2660
  return ret_val;
 
2661
}
 
2662
 
 
2663
static bool IsPipeliningPossible(const struct SessionHandle *handle,
 
2664
                                 const struct connectdata *conn)
 
2665
{
 
2666
  if((conn->handler->protocol & CURLPROTO_HTTP) &&
 
2667
     Curl_multi_pipeline_enabled(handle->multi) &&
 
2668
     (handle->set.httpreq == HTTPREQ_GET ||
 
2669
      handle->set.httpreq == HTTPREQ_HEAD) &&
 
2670
     handle->set.httpversion != CURL_HTTP_VERSION_1_0)
 
2671
    return TRUE;
 
2672
 
 
2673
  return FALSE;
 
2674
}
 
2675
 
 
2676
bool Curl_isPipeliningEnabled(const struct SessionHandle *handle)
 
2677
{
 
2678
  return Curl_multi_pipeline_enabled(handle->multi);
 
2679
}
 
2680
 
 
2681
CURLcode Curl_addHandleToPipeline(struct SessionHandle *data,
 
2682
                                  struct curl_llist *pipeline)
 
2683
{
 
2684
  if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
 
2685
    return CURLE_OUT_OF_MEMORY;
 
2686
  return CURLE_OK;
 
2687
}
 
2688
 
 
2689
int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
 
2690
                                  struct curl_llist *pipeline)
 
2691
{
 
2692
  struct curl_llist_element *curr;
 
2693
 
 
2694
  curr = pipeline->head;
 
2695
  while(curr) {
 
2696
    if(curr->ptr == handle) {
 
2697
      Curl_llist_remove(pipeline, curr, NULL);
 
2698
      return 1; /* we removed a handle */
 
2699
    }
 
2700
    curr = curr->next;
 
2701
  }
 
2702
 
 
2703
  return 0;
 
2704
}
 
2705
 
 
2706
#if 0 /* this code is saved here as it is useful for debugging purposes */
 
2707
static void Curl_printPipeline(struct curl_llist *pipeline)
 
2708
{
 
2709
  struct curl_llist_element *curr;
 
2710
 
 
2711
  curr = pipeline->head;
 
2712
  while(curr) {
 
2713
    struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
 
2714
    infof(data, "Handle in pipeline: %s\n", data->state.path);
 
2715
    curr = curr->next;
 
2716
  }
 
2717
}
 
2718
#endif
 
2719
 
 
2720
static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
 
2721
{
 
2722
  struct curl_llist_element *curr = pipeline->head;
 
2723
  if(curr) {
 
2724
    return (struct SessionHandle *) curr->ptr;
 
2725
  }
 
2726
 
 
2727
  return NULL;
 
2728
}
 
2729
 
 
2730
/* remove the specified connection from all (possible) pipelines and related
 
2731
   queues */
 
2732
void Curl_getoff_all_pipelines(struct SessionHandle *data,
 
2733
                               struct connectdata *conn)
 
2734
{
 
2735
  bool recv_head = (conn->readchannel_inuse &&
 
2736
    (gethandleathead(conn->recv_pipe) == data)) ? TRUE : FALSE;
 
2737
 
 
2738
  bool send_head = (conn->writechannel_inuse &&
 
2739
    (gethandleathead(conn->send_pipe) == data)) ? TRUE : FALSE;
 
2740
 
 
2741
  if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
 
2742
    conn->readchannel_inuse = FALSE;
 
2743
  if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
 
2744
    conn->writechannel_inuse = FALSE;
 
2745
}
 
2746
 
 
2747
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
 
2748
{
 
2749
  struct curl_llist_element *curr;
 
2750
 
 
2751
  if(!pipeline)
 
2752
    return;
 
2753
 
 
2754
  curr = pipeline->head;
 
2755
  while(curr) {
 
2756
    struct curl_llist_element *next = curr->next;
 
2757
    struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
 
2758
 
 
2759
#ifdef DEBUGBUILD /* debug-only code */
 
2760
    if(data->magic != CURLEASY_MAGIC_NUMBER) {
 
2761
      /* MAJOR BADNESS */
 
2762
      infof(data, "signalPipeClose() found BAAD easy handle\n");
 
2763
    }
 
2764
#endif
 
2765
 
 
2766
    if(pipe_broke)
 
2767
      data->state.pipe_broke = TRUE;
 
2768
    Curl_multi_handlePipeBreak(data);
 
2769
    Curl_llist_remove(pipeline, curr, NULL);
 
2770
    curr = next;
 
2771
  }
 
2772
}
 
2773
 
 
2774
/*
 
2775
 * This function finds the connection in the connection
 
2776
 * cache that has been unused for the longest time.
 
2777
 *
 
2778
 * Returns the pointer to the oldest idle connection, or NULL if none was
 
2779
 * found.
 
2780
 */
 
2781
static struct connectdata *
 
2782
find_oldest_idle_connection(struct SessionHandle *data)
 
2783
{
 
2784
  struct conncache *bc = data->state.conn_cache;
 
2785
  struct curl_hash_iterator iter;
 
2786
  struct curl_llist_element *curr;
 
2787
  struct curl_hash_element *he;
 
2788
  long highscore=-1;
 
2789
  long score;
 
2790
  struct timeval now;
 
2791
  struct connectdata *conn_candidate = NULL;
 
2792
  struct connectbundle *bundle;
 
2793
 
 
2794
  now = Curl_tvnow();
 
2795
 
 
2796
  Curl_hash_start_iterate(bc->hash, &iter);
 
2797
 
 
2798
  he = Curl_hash_next_element(&iter);
 
2799
  while(he) {
 
2800
    struct connectdata *conn;
 
2801
 
 
2802
    bundle = he->ptr;
 
2803
 
 
2804
    curr = bundle->conn_list->head;
 
2805
    while(curr) {
 
2806
      conn = curr->ptr;
 
2807
 
 
2808
      if(!conn->inuse) {
 
2809
        /* Set higher score for the age passed since the connection was used */
 
2810
        score = Curl_tvdiff(now, conn->now);
 
2811
 
 
2812
        if(score > highscore) {
 
2813
          highscore = score;
 
2814
          conn_candidate = conn;
 
2815
        }
 
2816
      }
 
2817
      curr = curr->next;
 
2818
    }
 
2819
 
 
2820
    he = Curl_hash_next_element(&iter);
 
2821
  }
 
2822
 
 
2823
  return conn_candidate;
 
2824
}
 
2825
 
 
2826
/*
 
2827
 * This function finds the connection in the connection
 
2828
 * bundle that has been unused for the longest time.
 
2829
 *
 
2830
 * Returns the pointer to the oldest idle connection, or NULL if none was
 
2831
 * found.
 
2832
 */
 
2833
static struct connectdata *
 
2834
find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
 
2835
                                      struct connectbundle *bundle)
 
2836
{
 
2837
  struct curl_llist_element *curr;
 
2838
  long highscore=-1;
 
2839
  long score;
 
2840
  struct timeval now;
 
2841
  struct connectdata *conn_candidate = NULL;
 
2842
  struct connectdata *conn;
 
2843
 
 
2844
  (void)data;
 
2845
 
 
2846
  now = Curl_tvnow();
 
2847
 
 
2848
  curr = bundle->conn_list->head;
 
2849
  while(curr) {
 
2850
    conn = curr->ptr;
 
2851
 
 
2852
    if(!conn->inuse) {
 
2853
      /* Set higher score for the age passed since the connection was used */
 
2854
      score = Curl_tvdiff(now, conn->now);
 
2855
 
 
2856
      if(score > highscore) {
 
2857
        highscore = score;
 
2858
        conn_candidate = conn;
 
2859
      }
 
2860
    }
 
2861
    curr = curr->next;
 
2862
  }
 
2863
 
 
2864
  return conn_candidate;
 
2865
}
 
2866
 
 
2867
/*
 
2868
 * Given one filled in connection struct (named needle), this function should
 
2869
 * detect if there already is one that has all the significant details
 
2870
 * exactly the same and thus should be used instead.
 
2871
 *
 
2872
 * If there is a match, this function returns TRUE - and has marked the
 
2873
 * connection as 'in-use'. It must later be called with ConnectionDone() to
 
2874
 * return back to 'idle' (unused) state.
 
2875
 *
 
2876
 * The force_reuse flag is set if the connection must be used, even if
 
2877
 * the pipelining strategy wants to open a new connection instead of reusing.
 
2878
 */
 
2879
static bool
 
2880
ConnectionExists(struct SessionHandle *data,
 
2881
                 struct connectdata *needle,
 
2882
                 struct connectdata **usethis,
 
2883
                 bool *force_reuse)
 
2884
{
 
2885
  struct connectdata *check;
 
2886
  struct connectdata *chosen = 0;
 
2887
  bool canPipeline = IsPipeliningPossible(data, needle);
 
2888
  bool wantNTLM = (data->state.authhost.want & CURLAUTH_NTLM) ||
 
2889
    (data->state.authhost.want & CURLAUTH_NTLM_WB) ? TRUE : FALSE;
 
2890
  struct connectbundle *bundle;
 
2891
 
 
2892
  *force_reuse = FALSE;
 
2893
 
 
2894
  /* We can't pipe if the site is blacklisted */
 
2895
  if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
 
2896
    canPipeline = FALSE;
 
2897
  }
 
2898
 
 
2899
  /* Look up the bundle with all the connections to this
 
2900
     particular host */
 
2901
  bundle = Curl_conncache_find_bundle(data->state.conn_cache,
 
2902
                                      needle->host.name);
 
2903
  if(bundle) {
 
2904
    size_t max_pipe_len = Curl_multi_max_pipeline_length(data->multi);
 
2905
    size_t best_pipe_len = max_pipe_len;
 
2906
    struct curl_llist_element *curr;
 
2907
 
 
2908
    infof(data, "Found bundle for host %s: %p\n",
 
2909
          needle->host.name, (void *)bundle);
 
2910
 
 
2911
    /* We can't pipe if we don't know anything about the server */
 
2912
    if(canPipeline && !bundle->server_supports_pipelining) {
 
2913
      infof(data, "Server doesn't support pipelining\n");
 
2914
      canPipeline = FALSE;
 
2915
    }
 
2916
 
 
2917
    curr = bundle->conn_list->head;
 
2918
    while(curr) {
 
2919
      bool match = FALSE;
 
2920
      bool credentialsMatch = FALSE;
 
2921
      size_t pipeLen;
 
2922
 
 
2923
      /*
 
2924
       * Note that if we use a HTTP proxy, we check connections to that
 
2925
       * proxy and not to the actual remote server.
 
2926
       */
 
2927
      check = curr->ptr;
 
2928
      curr = curr->next;
 
2929
 
 
2930
      pipeLen = check->send_pipe->size + check->recv_pipe->size;
 
2931
 
 
2932
      if(!pipeLen && !check->inuse) {
 
2933
        /* The check for a dead socket makes sense only if there are no
 
2934
           handles in pipeline and the connection isn't already marked in
 
2935
           use */
 
2936
        bool dead;
 
2937
        if(check->handler->protocol & CURLPROTO_RTSP)
 
2938
          /* RTSP is a special case due to RTP interleaving */
 
2939
          dead = Curl_rtsp_connisdead(check);
 
2940
        else
 
2941
          dead = SocketIsDead(check->sock[FIRSTSOCKET]);
 
2942
 
 
2943
        if(dead) {
 
2944
          check->data = data;
 
2945
          infof(data, "Connection %ld seems to be dead!\n",
 
2946
                check->connection_id);
 
2947
 
 
2948
          /* disconnect resources */
 
2949
          Curl_disconnect(check, /* dead_connection */ TRUE);
 
2950
          continue;
 
2951
        }
 
2952
      }
 
2953
 
 
2954
      if(canPipeline) {
 
2955
        /* Make sure the pipe has only GET requests */
 
2956
        struct SessionHandle* sh = gethandleathead(check->send_pipe);
 
2957
        struct SessionHandle* rh = gethandleathead(check->recv_pipe);
 
2958
        if(sh) {
 
2959
          if(!IsPipeliningPossible(sh, check))
 
2960
            continue;
 
2961
        }
 
2962
        else if(rh) {
 
2963
          if(!IsPipeliningPossible(rh, check))
 
2964
            continue;
 
2965
        }
 
2966
      }
 
2967
      else {
 
2968
        if(pipeLen > 0) {
 
2969
          /* can only happen within multi handles, and means that another easy
 
2970
             handle is using this connection */
 
2971
          continue;
 
2972
        }
 
2973
 
 
2974
        if(Curl_resolver_asynch()) {
 
2975
          /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
 
2976
             completed yet and until then we don't re-use this connection */
 
2977
          if(!check->ip_addr_str[0]) {
 
2978
            infof(data,
 
2979
                  "Connection #%ld is still name resolving, can't reuse\n",
 
2980
                  check->connection_id);
 
2981
            continue;
 
2982
          }
 
2983
        }
 
2984
 
 
2985
        if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
 
2986
           check->bits.close) {
 
2987
          /* Don't pick a connection that hasn't connected yet or that is going
 
2988
             to get closed. */
 
2989
          infof(data, "Connection #%ld isn't open enough, can't reuse\n",
 
2990
                check->connection_id);
 
2991
#ifdef DEBUGBUILD
 
2992
          if(check->recv_pipe->size > 0) {
 
2993
            infof(data,
 
2994
                  "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
 
2995
                  check->connection_id);
 
2996
          }
 
2997
#endif
 
2998
          continue;
 
2999
        }
 
3000
      }
 
3001
 
 
3002
      if((needle->handler->flags&PROTOPT_SSL) !=
 
3003
         (check->handler->flags&PROTOPT_SSL))
 
3004
        /* don't do mixed SSL and non-SSL connections */
 
3005
        if(!(needle->handler->protocol & check->handler->protocol))
 
3006
          /* except protocols that have been upgraded via TLS */
 
3007
          continue;
 
3008
 
 
3009
      if(needle->handler->flags&PROTOPT_SSL) {
 
3010
        if((data->set.ssl.verifypeer != check->verifypeer) ||
 
3011
           (data->set.ssl.verifyhost != check->verifyhost))
 
3012
          continue;
 
3013
      }
 
3014
 
 
3015
      if(needle->bits.proxy != check->bits.proxy)
 
3016
        /* don't do mixed proxy and non-proxy connections */
 
3017
        continue;
 
3018
 
 
3019
      if(!canPipeline && check->inuse)
 
3020
        /* this request can't be pipelined but the checked connection is
 
3021
           already in use so we skip it */
 
3022
        continue;
 
3023
 
 
3024
      if(needle->localdev || needle->localport) {
 
3025
        /* If we are bound to a specific local end (IP+port), we must not
 
3026
           re-use a random other one, although if we didn't ask for a
 
3027
           particular one we can reuse one that was bound.
 
3028
 
 
3029
           This comparison is a bit rough and too strict. Since the input
 
3030
           parameters can be specified in numerous ways and still end up the
 
3031
           same it would take a lot of processing to make it really accurate.
 
3032
           Instead, this matching will assume that re-uses of bound connections
 
3033
           will most likely also re-use the exact same binding parameters and
 
3034
           missing out a few edge cases shouldn't hurt anyone very much.
 
3035
        */
 
3036
        if((check->localport != needle->localport) ||
 
3037
           (check->localportrange != needle->localportrange) ||
 
3038
           !check->localdev ||
 
3039
           !needle->localdev ||
 
3040
           strcmp(check->localdev, needle->localdev))
 
3041
          continue;
 
3042
      }
 
3043
 
 
3044
      if((needle->handler->protocol & CURLPROTO_FTP) ||
 
3045
         ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
 
3046
         /* This is FTP or HTTP+NTLM, verify that we're using the same name
 
3047
            and password as well */
 
3048
         if(!strequal(needle->user, check->user) ||
 
3049
            !strequal(needle->passwd, check->passwd)) {
 
3050
            /* one of them was different */
 
3051
            continue;
 
3052
         }
 
3053
         credentialsMatch = TRUE;
 
3054
      }
 
3055
 
 
3056
      if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
 
3057
         (needle->bits.httpproxy && check->bits.httpproxy &&
 
3058
          needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
 
3059
          Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
 
3060
          (needle->port == check->port))) {
 
3061
        /* The requested connection does not use a HTTP proxy or it uses SSL or
 
3062
           it is a non-SSL protocol tunneled over the same http proxy name and
 
3063
           port number or it is a non-SSL protocol which is allowed to be
 
3064
           upgraded via TLS */
 
3065
 
 
3066
        if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
 
3067
            needle->handler->protocol & check->handler->protocol) &&
 
3068
           Curl_raw_equal(needle->host.name, check->host.name) &&
 
3069
           needle->remote_port == check->remote_port) {
 
3070
          if(needle->handler->flags & PROTOPT_SSL) {
 
3071
            /* This is a SSL connection so verify that we're using the same
 
3072
               SSL options as well */
 
3073
            if(!Curl_ssl_config_matches(&needle->ssl_config,
 
3074
                                        &check->ssl_config)) {
 
3075
              DEBUGF(infof(data,
 
3076
                           "Connection #%ld has different SSL parameters, "
 
3077
                           "can't reuse\n",
 
3078
                           check->connection_id));
 
3079
              continue;
 
3080
            }
 
3081
            else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
 
3082
              DEBUGF(infof(data,
 
3083
                           "Connection #%ld has not started SSL connect, "
 
3084
                           "can't reuse\n",
 
3085
                           check->connection_id));
 
3086
              continue;
 
3087
            }
 
3088
          }
 
3089
          match = TRUE;
 
3090
        }
 
3091
      }
 
3092
      else { /* The requested needle connection is using a proxy,
 
3093
                is the checked one using the same host, port and type? */
 
3094
        if(check->bits.proxy &&
 
3095
           (needle->proxytype == check->proxytype) &&
 
3096
           (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
 
3097
           Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
 
3098
           needle->port == check->port) {
 
3099
          /* This is the same proxy connection, use it! */
 
3100
          match = TRUE;
 
3101
        }
 
3102
      }
 
3103
 
 
3104
      if(match) {
 
3105
        /* If we are looking for an NTLM connection, check if this is already
 
3106
           authenticating with the right credentials. If not, keep looking so
 
3107
           that we can reuse NTLM connections if possible. (Especially we
 
3108
           must not reuse the same connection if partway through
 
3109
           a handshake!) */
 
3110
        if(wantNTLM) {
 
3111
          if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
 
3112
            chosen = check;
 
3113
 
 
3114
            /* We must use this connection, no other */
 
3115
            *force_reuse = TRUE;
 
3116
            break;
 
3117
          }
 
3118
          else
 
3119
            continue;
 
3120
        }
 
3121
 
 
3122
        if(canPipeline) {
 
3123
          /* We can pipeline if we want to. Let's continue looking for
 
3124
             the optimal connection to use, i.e the shortest pipe that is not
 
3125
             blacklisted. */
 
3126
 
 
3127
          if(pipeLen == 0) {
 
3128
            /* We have the optimal connection. Let's stop looking. */
 
3129
            chosen = check;
 
3130
            break;
 
3131
          }
 
3132
 
 
3133
          /* We can't use the connection if the pipe is full */
 
3134
          if(pipeLen >= max_pipe_len)
 
3135
            continue;
 
3136
 
 
3137
          /* We can't use the connection if the pipe is penalized */
 
3138
          if(Curl_pipeline_penalized(data, check))
 
3139
            continue;
 
3140
 
 
3141
          if(pipeLen < best_pipe_len) {
 
3142
            /* This connection has a shorter pipe so far. We'll pick this
 
3143
               and continue searching */
 
3144
            chosen = check;
 
3145
            best_pipe_len = pipeLen;
 
3146
            continue;
 
3147
          }
 
3148
        }
 
3149
        else {
 
3150
          /* We have found a connection. Let's stop searching. */
 
3151
          chosen = check;
 
3152
          break;
 
3153
        }
 
3154
      }
 
3155
    }
 
3156
  }
 
3157
 
 
3158
  if(chosen) {
 
3159
    *usethis = chosen;
 
3160
    return TRUE; /* yes, we found one to use! */
 
3161
  }
 
3162
 
 
3163
  return FALSE; /* no matching connecting exists */
 
3164
}
 
3165
 
 
3166
/* Mark the connection as 'idle', or close it if the cache is full.
 
3167
   Returns TRUE if the connection is kept, or FALSE if it was closed. */
 
3168
static bool
 
3169
ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
 
3170
{
 
3171
  /* data->multi->maxconnects can be negative, deal with it. */
 
3172
  size_t maxconnects =
 
3173
    (data->multi->maxconnects < 0) ? 0 : data->multi->maxconnects;
 
3174
  struct connectdata *conn_candidate = NULL;
 
3175
 
 
3176
  /* Mark the current connection as 'unused' */
 
3177
  conn->inuse = FALSE;
 
3178
 
 
3179
  if(maxconnects > 0 &&
 
3180
     data->state.conn_cache->num_connections > maxconnects) {
 
3181
    infof(data, "Connection cache is full, closing the oldest one.\n");
 
3182
 
 
3183
    conn_candidate = find_oldest_idle_connection(data);
 
3184
 
 
3185
    if(conn_candidate) {
 
3186
      /* Set the connection's owner correctly */
 
3187
      conn_candidate->data = data;
 
3188
 
 
3189
      /* the winner gets the honour of being disconnected */
 
3190
      (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
 
3191
    }
 
3192
  }
 
3193
 
 
3194
  return (conn_candidate == conn) ? FALSE : TRUE;
 
3195
}
 
3196
 
 
3197
/*
 
3198
 * The given input connection struct pointer is to be stored in the connection
 
3199
 * cache. If the cache is already full, least interesting existing connection
 
3200
 * (if any) gets closed.
 
3201
 *
 
3202
 * The given connection should be unique. That must've been checked prior to
 
3203
 * this call.
 
3204
 */
 
3205
static CURLcode ConnectionStore(struct SessionHandle *data,
 
3206
                                struct connectdata *conn)
 
3207
{
 
3208
  static int connection_id_counter = 0;
 
3209
 
 
3210
  CURLcode result;
 
3211
 
 
3212
  /* Assign a number to the connection for easier tracking in the log
 
3213
     output */
 
3214
  conn->connection_id = connection_id_counter++;
 
3215
 
 
3216
  result = Curl_conncache_add_conn(data->state.conn_cache, conn);
 
3217
  if(result != CURLE_OK)
 
3218
    conn->connection_id = -1;
 
3219
 
 
3220
  return result;
 
3221
}
 
3222
 
 
3223
/* after a TCP connection to the proxy has been verified, this function does
 
3224
   the next magic step.
 
3225
 
 
3226
   Note: this function's sub-functions call failf()
 
3227
 
 
3228
*/
 
3229
CURLcode Curl_connected_proxy(struct connectdata *conn,
 
3230
                              int sockindex)
 
3231
{
 
3232
  if(!conn->bits.proxy || sockindex)
 
3233
    /* this magic only works for the primary socket as the secondary is used
 
3234
       for FTP only and it has FTP specific magic in ftp.c */
 
3235
    return CURLE_OK;
 
3236
 
 
3237
  switch(conn->proxytype) {
 
3238
#ifndef CURL_DISABLE_PROXY
 
3239
  case CURLPROXY_SOCKS5:
 
3240
  case CURLPROXY_SOCKS5_HOSTNAME:
 
3241
    return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
 
3242
                       conn->host.name, conn->remote_port,
 
3243
                       FIRSTSOCKET, conn);
 
3244
 
 
3245
  case CURLPROXY_SOCKS4:
 
3246
    return Curl_SOCKS4(conn->proxyuser, conn->host.name,
 
3247
                       conn->remote_port, FIRSTSOCKET, conn, FALSE);
 
3248
 
 
3249
  case CURLPROXY_SOCKS4A:
 
3250
    return Curl_SOCKS4(conn->proxyuser, conn->host.name,
 
3251
                       conn->remote_port, FIRSTSOCKET, conn, TRUE);
 
3252
 
 
3253
#endif /* CURL_DISABLE_PROXY */
 
3254
  case CURLPROXY_HTTP:
 
3255
  case CURLPROXY_HTTP_1_0:
 
3256
    /* do nothing here. handled later. */
 
3257
    break;
 
3258
  default:
 
3259
    break;
 
3260
  } /* switch proxytype */
 
3261
 
 
3262
  return CURLE_OK;
 
3263
}
 
3264
 
 
3265
/*
 
3266
 * verboseconnect() displays verbose information after a connect
 
3267
 */
 
3268
#ifndef CURL_DISABLE_VERBOSE_STRINGS
 
3269
void Curl_verboseconnect(struct connectdata *conn)
 
3270
{
 
3271
  if(conn->data->set.verbose)
 
3272
    infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
 
3273
          conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
 
3274
          conn->ip_addr_str, conn->port, conn->connection_id);
 
3275
}
 
3276
#endif
 
3277
 
 
3278
int Curl_protocol_getsock(struct connectdata *conn,
 
3279
                          curl_socket_t *socks,
 
3280
                          int numsocks)
 
3281
{
 
3282
  if(conn->handler->proto_getsock)
 
3283
    return conn->handler->proto_getsock(conn, socks, numsocks);
 
3284
  return GETSOCK_BLANK;
 
3285
}
 
3286
 
 
3287
int Curl_doing_getsock(struct connectdata *conn,
 
3288
                       curl_socket_t *socks,
 
3289
                       int numsocks)
 
3290
{
 
3291
  if(conn && conn->handler->doing_getsock)
 
3292
    return conn->handler->doing_getsock(conn, socks, numsocks);
 
3293
  return GETSOCK_BLANK;
 
3294
}
 
3295
 
 
3296
/*
 
3297
 * We are doing protocol-specific connecting and this is being called over and
 
3298
 * over from the multi interface until the connection phase is done on
 
3299
 * protocol layer.
 
3300
 */
 
3301
 
 
3302
CURLcode Curl_protocol_connecting(struct connectdata *conn,
 
3303
                                  bool *done)
 
3304
{
 
3305
  CURLcode result=CURLE_OK;
 
3306
 
 
3307
  if(conn && conn->handler->connecting) {
 
3308
    *done = FALSE;
 
3309
    result = conn->handler->connecting(conn, done);
 
3310
  }
 
3311
  else
 
3312
    *done = TRUE;
 
3313
 
 
3314
  return result;
 
3315
}
 
3316
 
 
3317
/*
 
3318
 * We are DOING this is being called over and over from the multi interface
 
3319
 * until the DOING phase is done on protocol layer.
 
3320
 */
 
3321
 
 
3322
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
 
3323
{
 
3324
  CURLcode result=CURLE_OK;
 
3325
 
 
3326
  if(conn && conn->handler->doing) {
 
3327
    *done = FALSE;
 
3328
    result = conn->handler->doing(conn, done);
 
3329
  }
 
3330
  else
 
3331
    *done = TRUE;
 
3332
 
 
3333
  return result;
 
3334
}
 
3335
 
 
3336
/*
 
3337
 * We have discovered that the TCP connection has been successful, we can now
 
3338
 * proceed with some action.
 
3339
 *
 
3340
 */
 
3341
CURLcode Curl_protocol_connect(struct connectdata *conn,
 
3342
                               bool *protocol_done)
 
3343
{
 
3344
  CURLcode result=CURLE_OK;
 
3345
 
 
3346
  *protocol_done = FALSE;
 
3347
 
 
3348
  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
 
3349
    /* We already are connected, get back. This may happen when the connect
 
3350
       worked fine in the first call, like when we connect to a local server
 
3351
       or proxy. Note that we don't know if the protocol is actually done.
 
3352
 
 
3353
       Unless this protocol doesn't have any protocol-connect callback, as
 
3354
       then we know we're done. */
 
3355
    if(!conn->handler->connecting)
 
3356
      *protocol_done = TRUE;
 
3357
 
 
3358
    return CURLE_OK;
 
3359
  }
 
3360
 
 
3361
  if(!conn->bits.protoconnstart) {
 
3362
 
 
3363
    result = Curl_proxy_connect(conn);
 
3364
    if(result)
 
3365
      return result;
 
3366
 
 
3367
    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
 
3368
       (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
 
3369
      /* when using an HTTP tunnel proxy, await complete tunnel establishment
 
3370
         before proceeding further. Return CURLE_OK so we'll be called again */
 
3371
      return CURLE_OK;
 
3372
 
 
3373
    if(conn->handler->connect_it) {
 
3374
      /* is there a protocol-specific connect() procedure? */
 
3375
 
 
3376
      /* Call the protocol-specific connect function */
 
3377
      result = conn->handler->connect_it(conn, protocol_done);
 
3378
    }
 
3379
    else
 
3380
      *protocol_done = TRUE;
 
3381
 
 
3382
    /* it has started, possibly even completed but that knowledge isn't stored
 
3383
       in this bit! */
 
3384
    if(!result)
 
3385
      conn->bits.protoconnstart = TRUE;
 
3386
  }
 
3387
 
 
3388
  return result; /* pass back status */
 
3389
}
 
3390
 
 
3391
/*
 
3392
 * Helpers for IDNA convertions.
 
3393
 */
 
3394
static bool is_ASCII_name(const char *hostname)
 
3395
{
 
3396
  const unsigned char *ch = (const unsigned char*)hostname;
 
3397
 
 
3398
  while(*ch) {
 
3399
    if(*ch++ & 0x80)
 
3400
      return FALSE;
 
3401
  }
 
3402
  return TRUE;
 
3403
}
 
3404
 
 
3405
#ifdef USE_LIBIDN
 
3406
/*
 
3407
 * Check if characters in hostname is allowed in Top Level Domain.
 
3408
 */
 
3409
static bool tld_check_name(struct SessionHandle *data,
 
3410
                           const char *ace_hostname)
 
3411
{
 
3412
  size_t err_pos;
 
3413
  char *uc_name = NULL;
 
3414
  int rc;
 
3415
#ifndef CURL_DISABLE_VERBOSE_STRINGS
 
3416
  const char *tld_errmsg = "<no msg>";
 
3417
#else
 
3418
  (void)data;
 
3419
#endif
 
3420
 
 
3421
  /* Convert (and downcase) ACE-name back into locale's character set */
 
3422
  rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
 
3423
  if(rc != IDNA_SUCCESS)
 
3424
    return FALSE;
 
3425
 
 
3426
  rc = tld_check_lz(uc_name, &err_pos, NULL);
 
3427
#ifndef CURL_DISABLE_VERBOSE_STRINGS
 
3428
#ifdef HAVE_TLD_STRERROR
 
3429
  if(rc != TLD_SUCCESS)
 
3430
    tld_errmsg = tld_strerror((Tld_rc)rc);
 
3431
#endif
 
3432
  if(rc == TLD_INVALID)
 
3433
    infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
 
3434
          tld_errmsg, err_pos, uc_name[err_pos],
 
3435
          uc_name[err_pos] & 255);
 
3436
  else if(rc != TLD_SUCCESS)
 
3437
    infof(data, "WARNING: TLD check for %s failed; %s\n",
 
3438
          uc_name, tld_errmsg);
 
3439
#endif /* CURL_DISABLE_VERBOSE_STRINGS */
 
3440
  if(uc_name)
 
3441
     idn_free(uc_name);
 
3442
  if(rc != TLD_SUCCESS)
 
3443
    return FALSE;
 
3444
 
 
3445
  return TRUE;
 
3446
}
 
3447
#endif
 
3448
 
 
3449
/*
 
3450
 * Perform any necessary IDN conversion of hostname
 
3451
 */
 
3452
static void fix_hostname(struct SessionHandle *data,
 
3453
                         struct connectdata *conn, struct hostname *host)
 
3454
{
 
3455
#ifndef USE_LIBIDN
 
3456
  (void)data;
 
3457
  (void)conn;
 
3458
#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
 
3459
  (void)conn;
 
3460
#endif
 
3461
 
 
3462
  /* set the name we use to display the host name */
 
3463
  host->dispname = host->name;
 
3464
  if(!is_ASCII_name(host->name)) {
 
3465
#ifdef USE_LIBIDN
 
3466
  /*************************************************************
 
3467
   * Check name for non-ASCII and convert hostname to ACE form.
 
3468
   *************************************************************/
 
3469
  if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
 
3470
    char *ace_hostname = NULL;
 
3471
    int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
 
3472
    infof (data, "Input domain encoded as `%s'\n",
 
3473
           stringprep_locale_charset ());
 
3474
    if(rc != IDNA_SUCCESS)
 
3475
      infof(data, "Failed to convert %s to ACE; %s\n",
 
3476
            host->name, Curl_idn_strerror(conn,rc));
 
3477
    else {
 
3478
      /* tld_check_name() displays a warning if the host name contains
 
3479
         "illegal" characters for this TLD */
 
3480
      (void)tld_check_name(data, ace_hostname);
 
3481
 
 
3482
      host->encalloc = ace_hostname;
 
3483
      /* change the name pointer to point to the encoded hostname */
 
3484
      host->name = host->encalloc;
 
3485
    }
 
3486
  }
 
3487
#elif defined(USE_WIN32_IDN)
 
3488
  /*************************************************************
 
3489
   * Check name for non-ASCII and convert hostname to ACE form.
 
3490
   *************************************************************/
 
3491
    char *ace_hostname = NULL;
 
3492
    int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
 
3493
    if(rc == 0)
 
3494
      infof(data, "Failed to convert %s to ACE;\n",
 
3495
            host->name);
 
3496
    else {
 
3497
      host->encalloc = ace_hostname;
 
3498
      /* change the name pointer to point to the encoded hostname */
 
3499
      host->name = host->encalloc;
 
3500
    }
 
3501
#else
 
3502
    infof(data, "IDN support not present, can't parse Unicode domains\n");
 
3503
#endif
 
3504
  }
 
3505
}
 
3506
 
 
3507
static void llist_dtor(void *user, void *element)
 
3508
{
 
3509
  (void)user;
 
3510
  (void)element;
 
3511
  /* Do nothing */
 
3512
}
 
3513
 
 
3514
/*
 
3515
 * Allocate and initialize a new connectdata object.
 
3516
 */
 
3517
static struct connectdata *allocate_conn(struct SessionHandle *data)
 
3518
{
 
3519
  struct connectdata *conn = calloc(1, sizeof(struct connectdata));
 
3520
  if(!conn)
 
3521
    return NULL;
 
3522
 
 
3523
  conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
 
3524
                                           already from start to avoid NULL
 
3525
                                           situations and checks */
 
3526
 
 
3527
  /* and we setup a few fields in case we end up actually using this struct */
 
3528
 
 
3529
  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
 
3530
  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
 
3531
  conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
 
3532
  conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
 
3533
  conn->connection_id = -1;    /* no ID */
 
3534
  conn->port = -1; /* unknown at this point */
 
3535
 
 
3536
  /* Default protocol-independent behavior doesn't support persistent
 
3537
     connections, so we set this to force-close. Protocols that support
 
3538
     this need to set this to FALSE in their "curl_do" functions. */
 
3539
  conn->bits.close = TRUE;
 
3540
 
 
3541
  /* Store creation time to help future close decision making */
 
3542
  conn->created = Curl_tvnow();
 
3543
 
 
3544
  conn->data = data; /* Setup the association between this connection
 
3545
                        and the SessionHandle */
 
3546
 
 
3547
  conn->proxytype = data->set.proxytype; /* type */
 
3548
 
 
3549
#ifdef CURL_DISABLE_PROXY
 
3550
 
 
3551
  conn->bits.proxy = FALSE;
 
3552
  conn->bits.httpproxy = FALSE;
 
3553
  conn->bits.proxy_user_passwd = FALSE;
 
3554
  conn->bits.tunnel_proxy = FALSE;
 
3555
 
 
3556
#else /* CURL_DISABLE_PROXY */
 
3557
 
 
3558
  /* note that these two proxy bits are now just on what looks to be
 
3559
     requested, they may be altered down the road */
 
3560
  conn->bits.proxy = (data->set.str[STRING_PROXY] &&
 
3561
                      *data->set.str[STRING_PROXY])?TRUE:FALSE;
 
3562
  conn->bits.httpproxy = (conn->bits.proxy &&
 
3563
                          (conn->proxytype == CURLPROXY_HTTP ||
 
3564
                           conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
 
3565
  conn->bits.proxy_user_passwd =
 
3566
    (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
 
3567
  conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
 
3568
 
 
3569
#endif /* CURL_DISABLE_PROXY */
 
3570
 
 
3571
  conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
 
3572
  conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
 
3573
  conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
 
3574
 
 
3575
  conn->verifypeer = data->set.ssl.verifypeer;
 
3576
  conn->verifyhost = data->set.ssl.verifyhost;
 
3577
 
 
3578
  conn->ip_version = data->set.ipver;
 
3579
 
 
3580
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
 
3581
  conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
 
3582
  conn->ntlm_auth_hlpr_pid = 0;
 
3583
  conn->challenge_header = NULL;
 
3584
  conn->response_header = NULL;
 
3585
#endif
 
3586
 
 
3587
  if(Curl_multi_pipeline_enabled(data->multi) &&
 
3588
      !conn->master_buffer) {
 
3589
    /* Allocate master_buffer to be used for pipelining */
 
3590
    conn->master_buffer = calloc(BUFSIZE, sizeof (char));
 
3591
    if(!conn->master_buffer)
 
3592
      goto error;
 
3593
  }
 
3594
 
 
3595
  /* Initialize the pipeline lists */
 
3596
  conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
 
3597
  conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
 
3598
  if(!conn->send_pipe || !conn->recv_pipe)
 
3599
    goto error;
 
3600
 
 
3601
#ifdef HAVE_GSSAPI
 
3602
  conn->data_prot = PROT_CLEAR;
 
3603
#endif
 
3604
 
 
3605
  /* Store the local bind parameters that will be used for this connection */
 
3606
  if(data->set.str[STRING_DEVICE]) {
 
3607
    conn->localdev = strdup(data->set.str[STRING_DEVICE]);
 
3608
    if(!conn->localdev)
 
3609
      goto error;
 
3610
  }
 
3611
  conn->localportrange = data->set.localportrange;
 
3612
  conn->localport = data->set.localport;
 
3613
 
 
3614
  /* the close socket stuff needs to be copied to the connection struct as
 
3615
     it may live on without (this specific) SessionHandle */
 
3616
  conn->fclosesocket = data->set.fclosesocket;
 
3617
  conn->closesocket_client = data->set.closesocket_client;
 
3618
 
 
3619
  return conn;
 
3620
  error:
 
3621
 
 
3622
  Curl_llist_destroy(conn->send_pipe, NULL);
 
3623
  Curl_llist_destroy(conn->recv_pipe, NULL);
 
3624
 
 
3625
  conn->send_pipe = NULL;
 
3626
  conn->recv_pipe = NULL;
 
3627
 
 
3628
  Curl_safefree(conn->master_buffer);
 
3629
  Curl_safefree(conn->localdev);
 
3630
  Curl_safefree(conn);
 
3631
  return NULL;
 
3632
}
 
3633
 
 
3634
static CURLcode findprotocol(struct SessionHandle *data,
 
3635
                             struct connectdata *conn,
 
3636
                             const char *protostr)
 
3637
{
 
3638
  const struct Curl_handler * const *pp;
 
3639
  const struct Curl_handler *p;
 
3640
 
 
3641
  /* Scan protocol handler table and match against 'protostr' to set a few
 
3642
     variables based on the URL. Now that the handler may be changed later
 
3643
     when the protocol specific setup function is called. */
 
3644
  for(pp = protocols; (p = *pp) != NULL; pp++) {
 
3645
    if(Curl_raw_equal(p->scheme, protostr)) {
 
3646
      /* Protocol found in table. Check if allowed */
 
3647
      if(!(data->set.allowed_protocols & p->protocol))
 
3648
        /* nope, get out */
 
3649
        break;
 
3650
 
 
3651
      /* it is allowed for "normal" request, now do an extra check if this is
 
3652
         the result of a redirect */
 
3653
      if(data->state.this_is_a_follow &&
 
3654
         !(data->set.redir_protocols & p->protocol))
 
3655
        /* nope, get out */
 
3656
        break;
 
3657
 
 
3658
      /* Perform setup complement if some. */
 
3659
      conn->handler = conn->given = p;
 
3660
 
 
3661
      /* 'port' and 'remote_port' are set in setup_connection_internals() */
 
3662
      return CURLE_OK;
 
3663
    }
 
3664
  }
 
3665
 
 
3666
 
 
3667
  /* The protocol was not found in the table, but we don't have to assign it
 
3668
     to anything since it is already assigned to a dummy-struct in the
 
3669
     create_conn() function when the connectdata struct is allocated. */
 
3670
  failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
 
3671
        protostr);
 
3672
 
 
3673
  return CURLE_UNSUPPORTED_PROTOCOL;
 
3674
}
 
3675
 
 
3676
/*
 
3677
 * Parse URL and fill in the relevant members of the connection struct.
 
3678
 */
 
3679
static CURLcode parseurlandfillconn(struct SessionHandle *data,
 
3680
                                    struct connectdata *conn,
 
3681
                                    bool *prot_missing,
 
3682
                                    char **userp, char **passwdp,
 
3683
                                    char **optionsp)
 
3684
{
 
3685
  char *at;
 
3686
  char *fragment;
 
3687
  char *path = data->state.path;
 
3688
  char *query;
 
3689
  int rc;
 
3690
  char protobuf[16];
 
3691
  const char *protop;
 
3692
  CURLcode result;
 
3693
  bool rebuild_url = FALSE;
 
3694
 
 
3695
  *prot_missing = FALSE;
 
3696
 
 
3697
  /*************************************************************
 
3698
   * Parse the URL.
 
3699
   *
 
3700
   * We need to parse the url even when using the proxy, because we will need
 
3701
   * the hostname and port in case we are trying to SSL connect through the
 
3702
   * proxy -- and we don't know if we will need to use SSL until we parse the
 
3703
   * url ...
 
3704
   ************************************************************/
 
3705
  if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
 
3706
                  protobuf, path)) &&
 
3707
     Curl_raw_equal(protobuf, "file")) {
 
3708
    if(path[0] == '/' && path[1] == '/') {
 
3709
      /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
 
3710
       * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
 
3711
       * file://localhost/<path> is similar to how other schemes treat missing
 
3712
       * hostnames.  See RFC 1808. */
 
3713
 
 
3714
      /* This cannot be done with strcpy() in a portable manner, since the
 
3715
         memory areas overlap! */
 
3716
      memmove(path, path + 2, strlen(path + 2)+1);
 
3717
    }
 
3718
    /*
 
3719
     * we deal with file://<host>/<path> differently since it supports no
 
3720
     * hostname other than "localhost" and "127.0.0.1", which is unique among
 
3721
     * the URL protocols specified in RFC 1738
 
3722
     */
 
3723
    if(path[0] != '/') {
 
3724
      /* the URL included a host name, we ignore host names in file:// URLs
 
3725
         as the standards don't define what to do with them */
 
3726
      char *ptr=strchr(path, '/');
 
3727
      if(ptr) {
 
3728
        /* there was a slash present
 
3729
 
 
3730
           RFC1738 (section 3.1, page 5) says:
 
3731
 
 
3732
           The rest of the locator consists of data specific to the scheme,
 
3733
           and is known as the "url-path". It supplies the details of how the
 
3734
           specified resource can be accessed. Note that the "/" between the
 
3735
           host (or port) and the url-path is NOT part of the url-path.
 
3736
 
 
3737
           As most agents use file://localhost/foo to get '/foo' although the
 
3738
           slash preceding foo is a separator and not a slash for the path,
 
3739
           a URL as file://localhost//foo must be valid as well, to refer to
 
3740
           the same file with an absolute path.
 
3741
        */
 
3742
 
 
3743
        if(ptr[1] && ('/' == ptr[1]))
 
3744
          /* if there was two slashes, we skip the first one as that is then
 
3745
             used truly as a separator */
 
3746
          ptr++;
 
3747
 
 
3748
        /* This cannot be made with strcpy, as the memory chunks overlap! */
 
3749
        memmove(path, ptr, strlen(ptr)+1);
 
3750
      }
 
3751
    }
 
3752
 
 
3753
    protop = "file"; /* protocol string */
 
3754
  }
 
3755
  else {
 
3756
    /* clear path */
 
3757
    path[0]=0;
 
3758
 
 
3759
    if(2 > sscanf(data->change.url,
 
3760
                   "%15[^\n:]://%[^\n/?]%[^\n]",
 
3761
                   protobuf,
 
3762
                   conn->host.name, path)) {
 
3763
 
 
3764
      /*
 
3765
       * The URL was badly formatted, let's try the browser-style _without_
 
3766
       * protocol specified like 'http://'.
 
3767
       */
 
3768
      rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
 
3769
      if(1 > rc) {
 
3770
        /*
 
3771
         * We couldn't even get this format.
 
3772
         * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
 
3773
         * assigned, but the return value is EOF!
 
3774
         */
 
3775
#if defined(__DJGPP__) && (DJGPP_MINOR == 4)
 
3776
        if(!(rc == -1 && *conn->host.name))
 
3777
#endif
 
3778
        {
 
3779
          failf(data, "<url> malformed");
 
3780
          return CURLE_URL_MALFORMAT;
 
3781
        }
 
3782
      }
 
3783
 
 
3784
      /*
 
3785
       * Since there was no protocol part specified, we guess what protocol it
 
3786
       * is based on the first letters of the server name.
 
3787
       */
 
3788
 
 
3789
      /* Note: if you add a new protocol, please update the list in
 
3790
       * lib/version.c too! */
 
3791
 
 
3792
      if(checkprefix("FTP.", conn->host.name))
 
3793
        protop = "ftp";
 
3794
      else if(checkprefix("DICT.", conn->host.name))
 
3795
        protop = "DICT";
 
3796
      else if(checkprefix("LDAP.", conn->host.name))
 
3797
        protop = "LDAP";
 
3798
      else if(checkprefix("IMAP.", conn->host.name))
 
3799
        protop = "IMAP";
 
3800
      else if(checkprefix("SMTP.", conn->host.name))
 
3801
        protop = "smtp";
 
3802
      else if(checkprefix("POP3.", conn->host.name))
 
3803
        protop = "pop3";
 
3804
      else {
 
3805
        protop = "http";
 
3806
      }
 
3807
 
 
3808
      *prot_missing = TRUE; /* not given in URL */
 
3809
    }
 
3810
    else
 
3811
      protop = protobuf;
 
3812
  }
 
3813
 
 
3814
  /* We search for '?' in the host name (but only on the right side of a
 
3815
   * @-letter to allow ?-letters in username and password) to handle things
 
3816
   * like http://example.com?param= (notice the missing '/').
 
3817
   */
 
3818
  at = strchr(conn->host.name, '@');
 
3819
  if(at)
 
3820
    query = strchr(at+1, '?');
 
3821
  else
 
3822
    query = strchr(conn->host.name, '?');
 
3823
 
 
3824
  if(query) {
 
3825
    /* We must insert a slash before the '?'-letter in the URL. If the URL had
 
3826
       a slash after the '?', that is where the path currently begins and the
 
3827
       '?string' is still part of the host name.
 
3828
 
 
3829
       We must move the trailing part from the host name and put it first in
 
3830
       the path. And have it all prefixed with a slash.
 
3831
    */
 
3832
 
 
3833
    size_t hostlen = strlen(query);
 
3834
    size_t pathlen = strlen(path);
 
3835
 
 
3836
    /* move the existing path plus the zero byte forward, to make room for
 
3837
       the host-name part */
 
3838
    memmove(path+hostlen+1, path, pathlen+1);
 
3839
 
 
3840
     /* now copy the trailing host part in front of the existing path */
 
3841
    memcpy(path+1, query, hostlen);
 
3842
 
 
3843
    path[0]='/'; /* prepend the missing slash */
 
3844
    rebuild_url = TRUE;
 
3845
 
 
3846
    *query=0; /* now cut off the hostname at the ? */
 
3847
  }
 
3848
  else if(!path[0]) {
 
3849
    /* if there's no path set, use a single slash */
 
3850
    strcpy(path, "/");
 
3851
    rebuild_url = TRUE;
 
3852
  }
 
3853
 
 
3854
  /* If the URL is malformatted (missing a '/' after hostname before path) we
 
3855
   * insert a slash here. The only letter except '/' we accept to start a path
 
3856
   * is '?'.
 
3857
   */
 
3858
  if(path[0] == '?') {
 
3859
    /* We need this function to deal with overlapping memory areas. We know
 
3860
       that the memory area 'path' points to is 'urllen' bytes big and that
 
3861
       is bigger than the path. Use +1 to move the zero byte too. */
 
3862
    memmove(&path[1], path, strlen(path)+1);
 
3863
    path[0] = '/';
 
3864
    rebuild_url = TRUE;
 
3865
  }
 
3866
  else {
 
3867
    /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
 
3868
    char *newp = Curl_dedotdotify(path);
 
3869
    if(!newp)
 
3870
      return CURLE_OUT_OF_MEMORY;
 
3871
 
 
3872
    if(strcmp(newp, path)) {
 
3873
      rebuild_url = TRUE;
 
3874
      free(data->state.pathbuffer);
 
3875
      data->state.pathbuffer = newp;
 
3876
      data->state.path = newp;
 
3877
      path = newp;
 
3878
    }
 
3879
    else
 
3880
      free(newp);
 
3881
  }
 
3882
 
 
3883
  /*
 
3884
   * "rebuild_url" means that one or more URL components have been modified so
 
3885
   * we need to generate an updated full version.  We need the corrected URL
 
3886
   * when communicating over HTTP proxy and we don't know at this point if
 
3887
   * we're using a proxy or not.
 
3888
   */
 
3889
  if(rebuild_url) {
 
3890
    char *reurl;
 
3891
 
 
3892
    size_t plen = strlen(path); /* new path, should be 1 byte longer than
 
3893
                                   the original */
 
3894
    size_t urllen = strlen(data->change.url); /* original URL length */
 
3895
 
 
3896
    size_t prefixlen = strlen(conn->host.name);
 
3897
 
 
3898
    if(!*prot_missing)
 
3899
      prefixlen += strlen(protop) + strlen("://");
 
3900
 
 
3901
    reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
 
3902
    if(!reurl)
 
3903
      return CURLE_OUT_OF_MEMORY;
 
3904
 
 
3905
    /* copy the prefix */
 
3906
    memcpy(reurl, data->change.url, prefixlen);
 
3907
 
 
3908
    /* append the trailing piece + zerobyte */
 
3909
    memcpy(&reurl[prefixlen], path, plen + 1);
 
3910
 
 
3911
    /* possible free the old one */
 
3912
    if(data->change.url_alloc) {
 
3913
      Curl_safefree(data->change.url);
 
3914
      data->change.url_alloc = FALSE;
 
3915
    }
 
3916
 
 
3917
    infof(data, "Rebuilt URL to: %s\n", reurl);
 
3918
 
 
3919
    data->change.url = reurl;
 
3920
    data->change.url_alloc = TRUE; /* free this later */
 
3921
  }
 
3922
 
 
3923
  /*
 
3924
   * Parse the login details from the URL and strip them out of
 
3925
   * the host name
 
3926
   */
 
3927
  result = parse_url_login(data, conn, userp, passwdp, optionsp);
 
3928
  if(result != CURLE_OK)
 
3929
    return result;
 
3930
 
 
3931
  if(conn->host.name[0] == '[') {
 
3932
    /* This looks like an IPv6 address literal.  See if there is an address
 
3933
       scope.  */
 
3934
    char *percent = strstr (conn->host.name, "%25");
 
3935
    if(percent) {
 
3936
      char *endp;
 
3937
      unsigned long scope = strtoul (percent + 3, &endp, 10);
 
3938
      if(*endp == ']') {
 
3939
        /* The address scope was well formed.  Knock it out of the
 
3940
           hostname. */
 
3941
        memmove(percent, endp, strlen(endp)+1);
 
3942
        if(!data->state.this_is_a_follow)
 
3943
          /* Don't honour a scope given in a Location: header */
 
3944
          conn->scope = (unsigned int)scope;
 
3945
      }
 
3946
      else
 
3947
        infof(data, "Invalid IPv6 address format\n");
 
3948
    }
 
3949
  }
 
3950
 
 
3951
  if(data->set.scope)
 
3952
    /* Override any scope that was set above.  */
 
3953
    conn->scope = data->set.scope;
 
3954
 
 
3955
  /* Remove the fragment part of the path. Per RFC 2396, this is always the
 
3956
     last part of the URI. We are looking for the first '#' so that we deal
 
3957
     gracefully with non conformant URI such as http://example.com#foo#bar. */
 
3958
  fragment = strchr(path, '#');
 
3959
  if(fragment) {
 
3960
    *fragment = 0;
 
3961
 
 
3962
    /* we know the path part ended with a fragment, so we know the full URL
 
3963
       string does too and we need to cut it off from there so it isn't used
 
3964
       over proxy */
 
3965
    fragment = strchr(data->change.url, '#');
 
3966
    if(fragment)
 
3967
      *fragment = 0;
 
3968
  }
 
3969
 
 
3970
  /*
 
3971
   * So if the URL was A://B/C#D,
 
3972
   *   protop is A
 
3973
   *   conn->host.name is B
 
3974
   *   data->state.path is /C
 
3975
   */
 
3976
 
 
3977
  return findprotocol(data, conn, protop);
 
3978
}
 
3979
 
 
3980
/*
 
3981
 * If we're doing a resumed transfer, we need to setup our stuff
 
3982
 * properly.
 
3983
 */
 
3984
static CURLcode setup_range(struct SessionHandle *data)
 
3985
{
 
3986
  struct UrlState *s = &data->state;
 
3987
  s->resume_from = data->set.set_resume_from;
 
3988
  if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
 
3989
    if(s->rangestringalloc)
 
3990
      free(s->range);
 
3991
 
 
3992
    if(s->resume_from)
 
3993
      s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
 
3994
    else
 
3995
      s->range = strdup(data->set.str[STRING_SET_RANGE]);
 
3996
 
 
3997
    s->rangestringalloc = (s->range)?TRUE:FALSE;
 
3998
 
 
3999
    if(!s->range)
 
4000
      return CURLE_OUT_OF_MEMORY;
 
4001
 
 
4002
    /* tell ourselves to fetch this range */
 
4003
    s->use_range = TRUE;        /* enable range download */
 
4004
  }
 
4005
  else
 
4006
    s->use_range = FALSE; /* disable range download */
 
4007
 
 
4008
  return CURLE_OK;
 
4009
}
 
4010
 
 
4011
 
 
4012
/*
 
4013
 * setup_connection_internals() -
 
4014
 *
 
4015
 * Setup connection internals specific to the requested protocol in the
 
4016
 * SessionHandle. This is inited and setup before the connection is made but
 
4017
 * is about the particular protocol that is to be used.
 
4018
 *
 
4019
 * This MUST get called after proxy magic has been figured out.
 
4020
 */
 
4021
static CURLcode setup_connection_internals(struct connectdata *conn)
 
4022
{
 
4023
  const struct Curl_handler * p;
 
4024
  CURLcode result;
 
4025
 
 
4026
  /* in some case in the multi state-machine, we go back to the CONNECT state
 
4027
     and then a second (or third or...) call to this function will be made
 
4028
     without doing a DISCONNECT or DONE in between (since the connection is
 
4029
     yet in place) and therefore this function needs to first make sure
 
4030
     there's no lingering previous data allocated. */
 
4031
  Curl_free_request_state(conn->data);
 
4032
 
 
4033
  memset(&conn->data->req, 0, sizeof(struct SingleRequest));
 
4034
  conn->data->req.maxdownload = -1;
 
4035
 
 
4036
  conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
 
4037
 
 
4038
  /* Perform setup complement if some. */
 
4039
  p = conn->handler;
 
4040
 
 
4041
  if(p->setup_connection) {
 
4042
    result = (*p->setup_connection)(conn);
 
4043
 
 
4044
    if(result != CURLE_OK)
 
4045
      return result;
 
4046
 
 
4047
    p = conn->handler;              /* May have changed. */
 
4048
  }
 
4049
 
 
4050
  if(conn->port < 0)
 
4051
    /* we check for -1 here since if proxy was detected already, this
 
4052
       was very likely already set to the proxy port */
 
4053
    conn->port = p->defport;
 
4054
 
 
4055
  /* only if remote_port was not already parsed off the URL we use the
 
4056
     default port number */
 
4057
  if(!conn->remote_port)
 
4058
    conn->remote_port = (unsigned short)conn->given->defport;
 
4059
 
 
4060
  return CURLE_OK;
 
4061
}
 
4062
 
 
4063
/*
 
4064
 * Curl_free_request_state() should free temp data that was allocated in the
 
4065
 * SessionHandle for this single request.
 
4066
 */
 
4067
 
 
4068
void Curl_free_request_state(struct SessionHandle *data)
 
4069
{
 
4070
  Curl_safefree(data->req.protop);
 
4071
}
 
4072
 
 
4073
 
 
4074
#ifndef CURL_DISABLE_PROXY
 
4075
/****************************************************************
 
4076
* Checks if the host is in the noproxy list. returns true if it matches
 
4077
* and therefore the proxy should NOT be used.
 
4078
****************************************************************/
 
4079
static bool check_noproxy(const char* name, const char* no_proxy)
 
4080
{
 
4081
  /* no_proxy=domain1.dom,host.domain2.dom
 
4082
   *   (a comma-separated list of hosts which should
 
4083
   *   not be proxied, or an asterisk to override
 
4084
   *   all proxy variables)
 
4085
   */
 
4086
  size_t tok_start;
 
4087
  size_t tok_end;
 
4088
  const char* separator = ", ";
 
4089
  size_t no_proxy_len;
 
4090
  size_t namelen;
 
4091
  char *endptr;
 
4092
 
 
4093
  if(no_proxy && no_proxy[0]) {
 
4094
    if(Curl_raw_equal("*", no_proxy)) {
 
4095
      return TRUE;
 
4096
    }
 
4097
 
 
4098
    /* NO_PROXY was specified and it wasn't just an asterisk */
 
4099
 
 
4100
    no_proxy_len = strlen(no_proxy);
 
4101
    endptr = strchr(name, ':');
 
4102
    if(endptr)
 
4103
      namelen = endptr - name;
 
4104
    else
 
4105
      namelen = strlen(name);
 
4106
 
 
4107
    for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
 
4108
      while(tok_start < no_proxy_len &&
 
4109
            strchr(separator, no_proxy[tok_start]) != NULL) {
 
4110
        /* Look for the beginning of the token. */
 
4111
        ++tok_start;
 
4112
      }
 
4113
 
 
4114
      if(tok_start == no_proxy_len)
 
4115
        break; /* It was all trailing separator chars, no more tokens. */
 
4116
 
 
4117
      for(tok_end = tok_start; tok_end < no_proxy_len &&
 
4118
            strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
 
4119
        /* Look for the end of the token. */
 
4120
        ;
 
4121
 
 
4122
      /* To match previous behaviour, where it was necessary to specify
 
4123
       * ".local.com" to prevent matching "notlocal.com", we will leave
 
4124
       * the '.' off.
 
4125
       */
 
4126
      if(no_proxy[tok_start] == '.')
 
4127
        ++tok_start;
 
4128
 
 
4129
      if((tok_end - tok_start) <= namelen) {
 
4130
        /* Match the last part of the name to the domain we are checking. */
 
4131
        const char *checkn = name + namelen - (tok_end - tok_start);
 
4132
        if(Curl_raw_nequal(no_proxy + tok_start, checkn,
 
4133
                           tok_end - tok_start)) {
 
4134
          if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
 
4135
            /* We either have an exact match, or the previous character is a .
 
4136
             * so it is within the same domain, so no proxy for this host.
 
4137
             */
 
4138
            return TRUE;
 
4139
          }
 
4140
        }
 
4141
      } /* if((tok_end - tok_start) <= namelen) */
 
4142
    } /* for(tok_start = 0; tok_start < no_proxy_len;
 
4143
         tok_start = tok_end + 1) */
 
4144
  } /* NO_PROXY was specified and it wasn't just an asterisk */
 
4145
 
 
4146
  return FALSE;
 
4147
}
 
4148
 
 
4149
/****************************************************************
 
4150
* Detect what (if any) proxy to use. Remember that this selects a host
 
4151
* name and is not limited to HTTP proxies only.
 
4152
* The returned pointer must be freed by the caller (unless NULL)
 
4153
****************************************************************/
 
4154
static char *detect_proxy(struct connectdata *conn)
 
4155
{
 
4156
  char *proxy = NULL;
 
4157
 
 
4158
#ifndef CURL_DISABLE_HTTP
 
4159
  /* If proxy was not specified, we check for default proxy environment
 
4160
   * variables, to enable i.e Lynx compliance:
 
4161
   *
 
4162
   * http_proxy=http://some.server.dom:port/
 
4163
   * https_proxy=http://some.server.dom:port/
 
4164
   * ftp_proxy=http://some.server.dom:port/
 
4165
   * no_proxy=domain1.dom,host.domain2.dom
 
4166
   *   (a comma-separated list of hosts which should
 
4167
   *   not be proxied, or an asterisk to override
 
4168
   *   all proxy variables)
 
4169
   * all_proxy=http://some.server.dom:port/
 
4170
   *   (seems to exist for the CERN www lib. Probably
 
4171
   *   the first to check for.)
 
4172
   *
 
4173
   * For compatibility, the all-uppercase versions of these variables are
 
4174
   * checked if the lowercase versions don't exist.
 
4175
   */
 
4176
  char *no_proxy=NULL;
 
4177
  char proxy_env[128];
 
4178
 
 
4179
  no_proxy=curl_getenv("no_proxy");
 
4180
  if(!no_proxy)
 
4181
    no_proxy=curl_getenv("NO_PROXY");
 
4182
 
 
4183
  if(!check_noproxy(conn->host.name, no_proxy)) {
 
4184
    /* It was not listed as without proxy */
 
4185
    const char *protop = conn->handler->scheme;
 
4186
    char *envp = proxy_env;
 
4187
    char *prox;
 
4188
 
 
4189
    /* Now, build <protocol>_proxy and check for such a one to use */
 
4190
    while(*protop)
 
4191
      *envp++ = (char)tolower((int)*protop++);
 
4192
 
 
4193
    /* append _proxy */
 
4194
    strcpy(envp, "_proxy");
 
4195
 
 
4196
    /* read the protocol proxy: */
 
4197
    prox=curl_getenv(proxy_env);
 
4198
 
 
4199
    /*
 
4200
     * We don't try the uppercase version of HTTP_PROXY because of
 
4201
     * security reasons:
 
4202
     *
 
4203
     * When curl is used in a webserver application
 
4204
     * environment (cgi or php), this environment variable can
 
4205
     * be controlled by the web server user by setting the
 
4206
     * http header 'Proxy:' to some value.
 
4207
     *
 
4208
     * This can cause 'internal' http/ftp requests to be
 
4209
     * arbitrarily redirected by any external attacker.
 
4210
     */
 
4211
    if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
 
4212
      /* There was no lowercase variable, try the uppercase version: */
 
4213
      Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
 
4214
      prox=curl_getenv(proxy_env);
 
4215
    }
 
4216
 
 
4217
    if(prox && *prox) { /* don't count "" strings */
 
4218
      proxy = prox; /* use this */
 
4219
    }
 
4220
    else {
 
4221
      proxy = curl_getenv("all_proxy"); /* default proxy to use */
 
4222
      if(!proxy)
 
4223
        proxy=curl_getenv("ALL_PROXY");
 
4224
    }
 
4225
  } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
 
4226
       non-proxy */
 
4227
  if(no_proxy)
 
4228
    free(no_proxy);
 
4229
 
 
4230
#else /* !CURL_DISABLE_HTTP */
 
4231
 
 
4232
  (void)conn;
 
4233
#endif /* CURL_DISABLE_HTTP */
 
4234
 
 
4235
  return proxy;
 
4236
}
 
4237
 
 
4238
/*
 
4239
 * If this is supposed to use a proxy, we need to figure out the proxy
 
4240
 * host name, so that we can re-use an existing connection
 
4241
 * that may exist registered to the same proxy host.
 
4242
 * proxy will be freed before this function returns.
 
4243
 */
 
4244
static CURLcode parse_proxy(struct SessionHandle *data,
 
4245
                            struct connectdata *conn, char *proxy)
 
4246
{
 
4247
  char *prox_portno;
 
4248
  char *endofprot;
 
4249
 
 
4250
  /* We use 'proxyptr' to point to the proxy name from now on... */
 
4251
  char *proxyptr;
 
4252
  char *portptr;
 
4253
  char *atsign;
 
4254
 
 
4255
  /* We do the proxy host string parsing here. We want the host name and the
 
4256
   * port name. Accept a protocol:// prefix
 
4257
   */
 
4258
 
 
4259
  /* Parse the protocol part if present */
 
4260
  endofprot = strstr(proxy, "://");
 
4261
  if(endofprot) {
 
4262
    proxyptr = endofprot+3;
 
4263
    if(checkprefix("socks5h", proxy))
 
4264
      conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
 
4265
    else if(checkprefix("socks5", proxy))
 
4266
      conn->proxytype = CURLPROXY_SOCKS5;
 
4267
    else if(checkprefix("socks4a", proxy))
 
4268
      conn->proxytype = CURLPROXY_SOCKS4A;
 
4269
    else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
 
4270
      conn->proxytype = CURLPROXY_SOCKS4;
 
4271
    /* Any other xxx:// : change to http proxy */
 
4272
  }
 
4273
  else
 
4274
    proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
 
4275
 
 
4276
  /* Is there a username and password given in this proxy url? */
 
4277
  atsign = strchr(proxyptr, '@');
 
4278
  if(atsign) {
 
4279
    CURLcode res = CURLE_OK;
 
4280
    char *proxyuser = NULL;
 
4281
    char *proxypasswd = NULL;
 
4282
 
 
4283
    res = parse_login_details(proxyptr, atsign - proxyptr,
 
4284
                              &proxyuser, &proxypasswd, NULL);
 
4285
    if(!res) {
 
4286
      /* found user and password, rip them out.  note that we are
 
4287
         unescaping them, as there is otherwise no way to have a
 
4288
         username or password with reserved characters like ':' in
 
4289
         them. */
 
4290
      Curl_safefree(conn->proxyuser);
 
4291
      if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
 
4292
        conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
 
4293
      else
 
4294
        conn->proxyuser = strdup("");
 
4295
 
 
4296
      if(!conn->proxyuser)
 
4297
        res = CURLE_OUT_OF_MEMORY;
 
4298
      else {
 
4299
        Curl_safefree(conn->proxypasswd);
 
4300
        if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
 
4301
          conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
 
4302
        else
 
4303
          conn->proxypasswd = strdup("");
 
4304
 
 
4305
        if(!conn->proxypasswd)
 
4306
          res = CURLE_OUT_OF_MEMORY;
 
4307
      }
 
4308
 
 
4309
      if(!res) {
 
4310
        conn->bits.proxy_user_passwd = TRUE; /* enable it */
 
4311
        atsign++; /* the right side of the @-letter */
 
4312
 
 
4313
        if(atsign)
 
4314
          proxyptr = atsign; /* now use this instead */
 
4315
        else
 
4316
          res = CURLE_OUT_OF_MEMORY;
 
4317
      }
 
4318
    }
 
4319
 
 
4320
    Curl_safefree(proxyuser);
 
4321
    Curl_safefree(proxypasswd);
 
4322
 
 
4323
    if(res)
 
4324
      return res;
 
4325
  }
 
4326
 
 
4327
  /* start scanning for port number at this point */
 
4328
  portptr = proxyptr;
 
4329
 
 
4330
  /* detect and extract RFC2732-style IPv6-addresses */
 
4331
  if(*proxyptr == '[') {
 
4332
    char *ptr = ++proxyptr; /* advance beyond the initial bracket */
 
4333
    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') ||
 
4334
                   (*ptr == '.')))
 
4335
      ptr++;
 
4336
    if(*ptr == ']')
 
4337
      /* yeps, it ended nicely with a bracket as well */
 
4338
      *ptr++ = 0;
 
4339
    else
 
4340
      infof(data, "Invalid IPv6 address format\n");
 
4341
    portptr = ptr;
 
4342
    /* Note that if this didn't end with a bracket, we still advanced the
 
4343
     * proxyptr first, but I can't see anything wrong with that as no host
 
4344
     * name nor a numeric can legally start with a bracket.
 
4345
     */
 
4346
  }
 
4347
 
 
4348
  /* Get port number off proxy.server.com:1080 */
 
4349
  prox_portno = strchr(portptr, ':');
 
4350
  if(prox_portno) {
 
4351
    *prox_portno = 0x0; /* cut off number from host name */
 
4352
    prox_portno ++;
 
4353
    /* now set the local port number */
 
4354
    conn->port = strtol(prox_portno, NULL, 10);
 
4355
  }
 
4356
  else {
 
4357
    if(proxyptr[0]=='/')
 
4358
      /* If the first character in the proxy string is a slash, fail
 
4359
         immediately. The following code will otherwise clear the string which
 
4360
         will lead to code running as if no proxy was set! */
 
4361
      return CURLE_COULDNT_RESOLVE_PROXY;
 
4362
 
 
4363
    /* without a port number after the host name, some people seem to use
 
4364
       a slash so we strip everything from the first slash */
 
4365
    atsign = strchr(proxyptr, '/');
 
4366
    if(atsign)
 
4367
      *atsign = 0x0; /* cut off path part from host name */
 
4368
 
 
4369
    if(data->set.proxyport)
 
4370
      /* None given in the proxy string, then get the default one if it is
 
4371
         given */
 
4372
      conn->port = data->set.proxyport;
 
4373
  }
 
4374
 
 
4375
  /* now, clone the cleaned proxy host name */
 
4376
  conn->proxy.rawalloc = strdup(proxyptr);
 
4377
  conn->proxy.name = conn->proxy.rawalloc;
 
4378
 
 
4379
  if(!conn->proxy.rawalloc)
 
4380
    return CURLE_OUT_OF_MEMORY;
 
4381
 
 
4382
  return CURLE_OK;
 
4383
}
 
4384
 
 
4385
/*
 
4386
 * Extract the user and password from the authentication string
 
4387
 */
 
4388
static CURLcode parse_proxy_auth(struct SessionHandle *data,
 
4389
                                 struct connectdata *conn)
 
4390
{
 
4391
  char proxyuser[MAX_CURL_USER_LENGTH]="";
 
4392
  char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
 
4393
 
 
4394
  if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
 
4395
    strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
 
4396
            MAX_CURL_USER_LENGTH);
 
4397
    proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
 
4398
  }
 
4399
  if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
 
4400
    strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
 
4401
            MAX_CURL_PASSWORD_LENGTH);
 
4402
    proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
 
4403
  }
 
4404
 
 
4405
  conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
 
4406
  if(!conn->proxyuser)
 
4407
    return CURLE_OUT_OF_MEMORY;
 
4408
 
 
4409
  conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
 
4410
  if(!conn->proxypasswd)
 
4411
    return CURLE_OUT_OF_MEMORY;
 
4412
 
 
4413
  return CURLE_OK;
 
4414
}
 
4415
#endif /* CURL_DISABLE_PROXY */
 
4416
 
 
4417
/*
 
4418
 * parse_url_login()
 
4419
 *
 
4420
 * Parse the login details (user name, password and options) from the URL and
 
4421
 * strip them out of the host name
 
4422
 *
 
4423
 * Inputs: data->set.use_netrc (CURLOPT_NETRC)
 
4424
 *         conn->host.name
 
4425
 *
 
4426
 * Outputs: (almost :- all currently undefined)
 
4427
 *          conn->bits.user_passwd  - non-zero if non-default passwords exist
 
4428
 *          user                    - non-zero length if defined
 
4429
 *          passwd                  - non-zero length if defined
 
4430
 *          options                 - non-zero length if defined
 
4431
 *          conn->host.name         - remove user name and password
 
4432
 */
 
4433
static CURLcode parse_url_login(struct SessionHandle *data,
 
4434
                                struct connectdata *conn,
 
4435
                                char **user, char **passwd, char **options)
 
4436
{
 
4437
  CURLcode result = CURLE_OK;
 
4438
  char *userp = NULL;
 
4439
  char *passwdp = NULL;
 
4440
  char *optionsp = NULL;
 
4441
 
 
4442
  /* At this point, we're hoping all the other special cases have
 
4443
   * been taken care of, so conn->host.name is at most
 
4444
   *    [user[:password][;options]]@]hostname
 
4445
   *
 
4446
   * We need somewhere to put the embedded details, so do that first.
 
4447
   */
 
4448
 
 
4449
  char *ptr = strchr(conn->host.name, '@');
 
4450
  char *login = conn->host.name;
 
4451
 
 
4452
  DEBUGASSERT(!**user);
 
4453
  DEBUGASSERT(!**passwd);
 
4454
  DEBUGASSERT(!**options);
 
4455
 
 
4456
  if(!ptr)
 
4457
    goto out;
 
4458
 
 
4459
  /* We will now try to extract the
 
4460
   * possible login information in a string like:
 
4461
   * ftp://user:password@ftp.my.site:8021/README */
 
4462
  conn->host.name = ++ptr;
 
4463
 
 
4464
  /* So the hostname is sane.  Only bother interpreting the
 
4465
   * results if we could care.  It could still be wasted
 
4466
   * work because it might be overtaken by the programmatically
 
4467
   * set user/passwd, but doing that first adds more cases here :-(
 
4468
   */
 
4469
 
 
4470
  if(data->set.use_netrc == CURL_NETRC_REQUIRED)
 
4471
    goto out;
 
4472
 
 
4473
  /* We could use the login information in the URL so extract it */
 
4474
  result = parse_login_details(login, ptr - login - 1,
 
4475
                               &userp, &passwdp, &optionsp);
 
4476
  if(result != CURLE_OK)
 
4477
    goto out;
 
4478
 
 
4479
  if(userp) {
 
4480
    char *newname;
 
4481
 
 
4482
    /* We have a user in the URL */
 
4483
    conn->bits.userpwd_in_url = TRUE;
 
4484
    conn->bits.user_passwd = TRUE; /* enable user+password */
 
4485
 
 
4486
    /* Decode the user */
 
4487
    newname = curl_easy_unescape(data, userp, 0, NULL);
 
4488
    if(!newname) {
 
4489
      result = CURLE_OUT_OF_MEMORY;
 
4490
      goto out;
 
4491
    }
 
4492
 
 
4493
    free(*user);
 
4494
    *user = newname;
 
4495
  }
 
4496
 
 
4497
  if(passwdp) {
 
4498
    /* We have a password in the URL so decode it */
 
4499
    char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
 
4500
    if(!newpasswd) {
 
4501
      result = CURLE_OUT_OF_MEMORY;
 
4502
      goto out;
 
4503
    }
 
4504
 
 
4505
    free(*passwd);
 
4506
    *passwd = newpasswd;
 
4507
  }
 
4508
 
 
4509
  if(optionsp) {
 
4510
    /* We have an options list in the URL so decode it */
 
4511
    char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
 
4512
    if(!newoptions) {
 
4513
      result = CURLE_OUT_OF_MEMORY;
 
4514
      goto out;
 
4515
    }
 
4516
 
 
4517
    free(*options);
 
4518
    *options = newoptions;
 
4519
  }
 
4520
 
 
4521
 
 
4522
  out:
 
4523
 
 
4524
  Curl_safefree(userp);
 
4525
  Curl_safefree(passwdp);
 
4526
  Curl_safefree(optionsp);
 
4527
 
 
4528
  return result;
 
4529
}
 
4530
 
 
4531
/*
 
4532
 * parse_login_details()
 
4533
 *
 
4534
 * This is used to parse a login string for user name, password and options in
 
4535
 * the following formats:
 
4536
 *
 
4537
 *   user
 
4538
 *   user:password
 
4539
 *   user:password;options
 
4540
 *   user;options
 
4541
 *   user;options:password
 
4542
 *   :password
 
4543
 *   :password;options
 
4544
 *   ;options
 
4545
 *   ;options:password
 
4546
 *
 
4547
 * Parameters:
 
4548
 *
 
4549
 * login    [in]     - The login string.
 
4550
 * len      [in]     - The length of the login string.
 
4551
 * userp    [in/out] - The address where a pointer to newly allocated memory
 
4552
 *                     holding the user will be stored upon completion.
 
4553
 * passdwp  [in/out] - The address where a pointer to newly allocated memory
 
4554
 *                     holding the password will be stored upon completion.
 
4555
 * optionsp [in/out] - The address where a pointer to newly allocated memory
 
4556
 *                     holding the options will be stored upon completion.
 
4557
 *
 
4558
 * Returns CURLE_OK on success.
 
4559
 */
 
4560
static CURLcode parse_login_details(const char *login, const size_t len,
 
4561
                                    char **userp, char **passwdp,
 
4562
                                    char **optionsp)
 
4563
{
 
4564
  CURLcode result = CURLE_OK;
 
4565
  char *ubuf = NULL;
 
4566
  char *pbuf = NULL;
 
4567
  char *obuf = NULL;
 
4568
  const char *psep = NULL;
 
4569
  const char *osep = NULL;
 
4570
  size_t ulen;
 
4571
  size_t plen;
 
4572
  size_t olen;
 
4573
 
 
4574
  /* Attempt to find the password separator */
 
4575
  if(passwdp) {
 
4576
    psep = strchr(login, ':');
 
4577
 
 
4578
    /* Within the constraint of the login string */
 
4579
    if(psep >= login + len)
 
4580
      psep = NULL;
 
4581
  }
 
4582
 
 
4583
  /* Attempt to find the options separator */
 
4584
  if(optionsp) {
 
4585
    osep = strchr(login, ';');
 
4586
 
 
4587
    /* Within the constraint of the login string */
 
4588
    if(osep >= login + len)
 
4589
      osep = NULL;
 
4590
  }
 
4591
 
 
4592
  /* Calculate the portion lengths */
 
4593
  ulen = (psep ?
 
4594
          (size_t)(osep && psep > osep ? osep - login : psep - login) :
 
4595
          (osep ? (size_t)(osep - login) : len));
 
4596
  plen = (psep ?
 
4597
          (osep && osep > psep ? (size_t)(osep - psep) :
 
4598
                                 (size_t)(login + len - psep)) - 1 : 0);
 
4599
  olen = (osep ?
 
4600
          (psep && psep > osep ? (size_t)(psep - osep) :
 
4601
                                 (size_t)(login + len - osep)) - 1 : 0);
 
4602
 
 
4603
  /* Allocate the user portion buffer */
 
4604
  if(userp && ulen) {
 
4605
    ubuf = malloc(ulen + 1);
 
4606
    if(!ubuf)
 
4607
      result = CURLE_OUT_OF_MEMORY;
 
4608
  }
 
4609
 
 
4610
  /* Allocate the password portion buffer */
 
4611
  if(!result && passwdp && plen) {
 
4612
    pbuf = malloc(plen + 1);
 
4613
    if(!pbuf) {
 
4614
      Curl_safefree(ubuf);
 
4615
      result = CURLE_OUT_OF_MEMORY;
 
4616
    }
 
4617
  }
 
4618
 
 
4619
  /* Allocate the options portion buffer */
 
4620
  if(!result && optionsp && olen) {
 
4621
    obuf = malloc(olen + 1);
 
4622
    if(!obuf) {
 
4623
      Curl_safefree(pbuf);
 
4624
      Curl_safefree(ubuf);
 
4625
      result = CURLE_OUT_OF_MEMORY;
 
4626
    }
 
4627
  }
 
4628
 
 
4629
  if(!result) {
 
4630
    /* Store the user portion if necessary */
 
4631
    if(ubuf) {
 
4632
      memcpy(ubuf, login, ulen);
 
4633
      ubuf[ulen] = '\0';
 
4634
      Curl_safefree(*userp);
 
4635
      *userp = ubuf;
 
4636
    }
 
4637
 
 
4638
    /* Store the password portion if necessary */
 
4639
    if(pbuf) {
 
4640
      memcpy(pbuf, psep + 1, plen);
 
4641
      pbuf[plen] = '\0';
 
4642
      Curl_safefree(*passwdp);
 
4643
      *passwdp = pbuf;
 
4644
    }
 
4645
 
 
4646
    /* Store the options portion if necessary */
 
4647
    if(obuf) {
 
4648
      memcpy(obuf, osep + 1, olen);
 
4649
      obuf[olen] = '\0';
 
4650
      Curl_safefree(*optionsp);
 
4651
      *optionsp = obuf;
 
4652
    }
 
4653
  }
 
4654
 
 
4655
  return result;
 
4656
}
 
4657
 
 
4658
/*************************************************************
 
4659
 * Figure out the remote port number and fix it in the URL
 
4660
 *
 
4661
 * No matter if we use a proxy or not, we have to figure out the remote
 
4662
 * port number of various reasons.
 
4663
 *
 
4664
 * To be able to detect port number flawlessly, we must not confuse them
 
4665
 * IPv6-specified addresses in the [0::1] style. (RFC2732)
 
4666
 *
 
4667
 * The conn->host.name is currently [user:passwd@]host[:port] where host
 
4668
 * could be a hostname, IPv4 address or IPv6 address.
 
4669
 *
 
4670
 * The port number embedded in the URL is replaced, if necessary.
 
4671
 *************************************************************/
 
4672
static CURLcode parse_remote_port(struct SessionHandle *data,
 
4673
                                  struct connectdata *conn)
 
4674
{
 
4675
  char *portptr;
 
4676
  char endbracket;
 
4677
 
 
4678
  /* Note that at this point, the IPv6 address cannot contain any scope
 
4679
     suffix as that has already been removed in the parseurlandfillconn()
 
4680
     function */
 
4681
  if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
 
4682
                  &endbracket)) &&
 
4683
     (']' == endbracket)) {
 
4684
    /* this is a RFC2732-style specified IP-address */
 
4685
    conn->bits.ipv6_ip = TRUE;
 
4686
 
 
4687
    conn->host.name++; /* skip over the starting bracket */
 
4688
    portptr = strchr(conn->host.name, ']');
 
4689
    if(portptr) {
 
4690
      *portptr++ = '\0'; /* zero terminate, killing the bracket */
 
4691
      if(':' != *portptr)
 
4692
        portptr = NULL; /* no port number available */
 
4693
    }
 
4694
  }
 
4695
  else {
 
4696
#ifdef ENABLE_IPV6
 
4697
    struct in6_addr in6;
 
4698
    if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
 
4699
      /* This is a numerical IPv6 address, meaning this is a wrongly formatted
 
4700
         URL */
 
4701
      failf(data, "IPv6 numerical address used in URL without brackets");
 
4702
      return CURLE_URL_MALFORMAT;
 
4703
    }
 
4704
#endif
 
4705
 
 
4706
    portptr = strrchr(conn->host.name, ':');
 
4707
  }
 
4708
 
 
4709
  if(data->set.use_port && data->state.allow_port) {
 
4710
    /* if set, we use this and ignore the port possibly given in the URL */
 
4711
    conn->remote_port = (unsigned short)data->set.use_port;
 
4712
    if(portptr)
 
4713
      *portptr = '\0'; /* cut off the name there anyway - if there was a port
 
4714
                      number - since the port number is to be ignored! */
 
4715
    if(conn->bits.httpproxy) {
 
4716
      /* we need to create new URL with the new port number */
 
4717
      char *url;
 
4718
      char type[12]="";
 
4719
 
 
4720
      if(conn->bits.type_set)
 
4721
        snprintf(type, sizeof(type), ";type=%c",
 
4722
                 data->set.prefer_ascii?'A':
 
4723
                 (data->set.ftp_list_only?'D':'I'));
 
4724
 
 
4725
      /*
 
4726
       * This synthesized URL isn't always right--suffixes like ;type=A are
 
4727
       * stripped off. It would be better to work directly from the original
 
4728
       * URL and simply replace the port part of it.
 
4729
       */
 
4730
      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
 
4731
                    conn->bits.ipv6_ip?"[":"", conn->host.name,
 
4732
                    conn->bits.ipv6_ip?"]":"", conn->remote_port,
 
4733
                    data->state.slash_removed?"/":"", data->state.path,
 
4734
                    type);
 
4735
      if(!url)
 
4736
        return CURLE_OUT_OF_MEMORY;
 
4737
 
 
4738
      if(data->change.url_alloc) {
 
4739
        Curl_safefree(data->change.url);
 
4740
        data->change.url_alloc = FALSE;
 
4741
      }
 
4742
 
 
4743
      data->change.url = url;
 
4744
      data->change.url_alloc = TRUE;
 
4745
    }
 
4746
  }
 
4747
  else if(portptr) {
 
4748
    /* no CURLOPT_PORT given, extract the one from the URL */
 
4749
 
 
4750
    char *rest;
 
4751
    unsigned long port;
 
4752
 
 
4753
    port=strtoul(portptr+1, &rest, 10);  /* Port number must be decimal */
 
4754
 
 
4755
    if(rest != (portptr+1) && *rest == '\0') {
 
4756
      /* The colon really did have only digits after it,
 
4757
       * so it is either a port number or a mistake */
 
4758
 
 
4759
      if(port > 0xffff) {   /* Single unix standard says port numbers are
 
4760
                              * 16 bits long */
 
4761
        failf(data, "Port number too large: %lu", port);
 
4762
        return CURLE_URL_MALFORMAT;
 
4763
      }
 
4764
 
 
4765
      *portptr = '\0'; /* cut off the name there */
 
4766
      conn->remote_port = curlx_ultous(port);
 
4767
    }
 
4768
    else if(!port)
 
4769
      /* Browser behavior adaptation. If there's a colon with no digits after,
 
4770
         just cut off the name there which makes us ignore the colon and just
 
4771
         use the default port. Firefox and Chrome both do that. */
 
4772
      *portptr = '\0';
 
4773
  }
 
4774
  return CURLE_OK;
 
4775
}
 
4776
 
 
4777
/*
 
4778
 * Override the login details from the URL with that in the CURLOPT_USERPWD
 
4779
 * option or a .netrc file, if applicable.
 
4780
 */
 
4781
static CURLcode override_login(struct SessionHandle *data,
 
4782
                               struct connectdata *conn,
 
4783
                               char **userp, char **passwdp, char **optionsp)
 
4784
{
 
4785
  if(data->set.str[STRING_USERNAME]) {
 
4786
    free(*userp);
 
4787
    *userp = strdup(data->set.str[STRING_USERNAME]);
 
4788
    if(!*userp)
 
4789
      return CURLE_OUT_OF_MEMORY;
 
4790
  }
 
4791
 
 
4792
  if(data->set.str[STRING_PASSWORD]) {
 
4793
    free(*passwdp);
 
4794
    *passwdp = strdup(data->set.str[STRING_PASSWORD]);
 
4795
    if(!*passwdp)
 
4796
      return CURLE_OUT_OF_MEMORY;
 
4797
  }
 
4798
 
 
4799
  if(data->set.str[STRING_OPTIONS]) {
 
4800
    free(*optionsp);
 
4801
    *optionsp = strdup(data->set.str[STRING_OPTIONS]);
 
4802
    if(!*optionsp)
 
4803
      return CURLE_OUT_OF_MEMORY;
 
4804
  }
 
4805
 
 
4806
  conn->bits.netrc = FALSE;
 
4807
  if(data->set.use_netrc != CURL_NETRC_IGNORED) {
 
4808
    if(Curl_parsenetrc(conn->host.name,
 
4809
                       userp, passwdp,
 
4810
                       data->set.str[STRING_NETRC_FILE])) {
 
4811
      infof(data, "Couldn't find host %s in the "
 
4812
            DOT_CHAR "netrc file; using defaults\n",
 
4813
            conn->host.name);
 
4814
    }
 
4815
    else {
 
4816
      /* set bits.netrc TRUE to remember that we got the name from a .netrc
 
4817
         file, so that it is safe to use even if we followed a Location: to a
 
4818
         different host or similar. */
 
4819
      conn->bits.netrc = TRUE;
 
4820
 
 
4821
      conn->bits.user_passwd = TRUE; /* enable user+password */
 
4822
    }
 
4823
  }
 
4824
 
 
4825
  return CURLE_OK;
 
4826
}
 
4827
 
 
4828
/*
 
4829
 * Set the login details so they're available in the connection
 
4830
 */
 
4831
static CURLcode set_login(struct connectdata *conn,
 
4832
                          const char *user, const char *passwd,
 
4833
                          const char *options)
 
4834
{
 
4835
  CURLcode result = CURLE_OK;
 
4836
 
 
4837
  /* If our protocol needs a password and we have none, use the defaults */
 
4838
  if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
 
4839
    /* Store the default user */
 
4840
    conn->user = strdup(CURL_DEFAULT_USER);
 
4841
 
 
4842
    /* Store the default password */
 
4843
    if(conn->user)
 
4844
      conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
 
4845
    else
 
4846
      conn->passwd = NULL;
 
4847
 
 
4848
    /* This is the default password, so DON'T set conn->bits.user_passwd */
 
4849
  }
 
4850
  else {
 
4851
    /* Store the user, zero-length if not set */
 
4852
    conn->user = strdup(user);
 
4853
 
 
4854
    /* Store the password (only if user is present), zero-length if not set */
 
4855
    if(conn->user)
 
4856
      conn->passwd = strdup(passwd);
 
4857
    else
 
4858
      conn->passwd = NULL;
 
4859
  }
 
4860
 
 
4861
  if(!conn->user || !conn->passwd)
 
4862
    result = CURLE_OUT_OF_MEMORY;
 
4863
 
 
4864
  /* Store the options, null if not set */
 
4865
  if(!result && options[0]) {
 
4866
    conn->options = strdup(options);
 
4867
 
 
4868
    if(!conn->options)
 
4869
      result = CURLE_OUT_OF_MEMORY;
 
4870
  }
 
4871
 
 
4872
  return result;
 
4873
}
 
4874
 
 
4875
/*************************************************************
 
4876
 * Resolve the address of the server or proxy
 
4877
 *************************************************************/
 
4878
static CURLcode resolve_server(struct SessionHandle *data,
 
4879
                               struct connectdata *conn,
 
4880
                               bool *async)
 
4881
{
 
4882
  CURLcode result=CURLE_OK;
 
4883
  long timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
4884
 
 
4885
  /*************************************************************
 
4886
   * Resolve the name of the server or proxy
 
4887
   *************************************************************/
 
4888
  if(conn->bits.reuse)
 
4889
    /* We're reusing the connection - no need to resolve anything, and
 
4890
       fix_hostname() was called already in create_conn() for the re-use
 
4891
       case. */
 
4892
    *async = FALSE;
 
4893
 
 
4894
  else {
 
4895
    /* this is a fresh connect */
 
4896
    int rc;
 
4897
    struct Curl_dns_entry *hostaddr;
 
4898
 
 
4899
    /* set a pointer to the hostname we display */
 
4900
    fix_hostname(data, conn, &conn->host);
 
4901
 
 
4902
    if(!conn->proxy.name || !*conn->proxy.name) {
 
4903
      /* If not connecting via a proxy, extract the port from the URL, if it is
 
4904
       * there, thus overriding any defaults that might have been set above. */
 
4905
      conn->port =  conn->remote_port; /* it is the same port */
 
4906
 
 
4907
      /* Resolve target host right on */
 
4908
      rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
 
4909
                               &hostaddr, timeout_ms);
 
4910
      if(rc == CURLRESOLV_PENDING)
 
4911
        *async = TRUE;
 
4912
 
 
4913
      else if(rc == CURLRESOLV_TIMEDOUT)
 
4914
        result = CURLE_OPERATION_TIMEDOUT;
 
4915
 
 
4916
      else if(!hostaddr) {
 
4917
        failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
 
4918
        result =  CURLE_COULDNT_RESOLVE_HOST;
 
4919
        /* don't return yet, we need to clean up the timeout first */
 
4920
      }
 
4921
    }
 
4922
    else {
 
4923
      /* This is a proxy that hasn't been resolved yet. */
 
4924
 
 
4925
      /* IDN-fix the proxy name */
 
4926
      fix_hostname(data, conn, &conn->proxy);
 
4927
 
 
4928
      /* resolve proxy */
 
4929
      rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
 
4930
                               &hostaddr, timeout_ms);
 
4931
 
 
4932
      if(rc == CURLRESOLV_PENDING)
 
4933
        *async = TRUE;
 
4934
 
 
4935
      else if(rc == CURLRESOLV_TIMEDOUT)
 
4936
        result = CURLE_OPERATION_TIMEDOUT;
 
4937
 
 
4938
      else if(!hostaddr) {
 
4939
        failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
 
4940
        result = CURLE_COULDNT_RESOLVE_PROXY;
 
4941
        /* don't return yet, we need to clean up the timeout first */
 
4942
      }
 
4943
    }
 
4944
    DEBUGASSERT(conn->dns_entry == NULL);
 
4945
    conn->dns_entry = hostaddr;
 
4946
  }
 
4947
 
 
4948
  return result;
 
4949
}
 
4950
 
 
4951
/*
 
4952
 * Cleanup the connection just allocated before we can move along and use the
 
4953
 * previously existing one.  All relevant data is copied over and old_conn is
 
4954
 * ready for freeing once this function returns.
 
4955
 */
 
4956
static void reuse_conn(struct connectdata *old_conn,
 
4957
                       struct connectdata *conn)
 
4958
{
 
4959
  if(old_conn->proxy.rawalloc)
 
4960
    free(old_conn->proxy.rawalloc);
 
4961
 
 
4962
  /* free the SSL config struct from this connection struct as this was
 
4963
     allocated in vain and is targeted for destruction */
 
4964
  Curl_free_ssl_config(&old_conn->ssl_config);
 
4965
 
 
4966
  conn->data = old_conn->data;
 
4967
 
 
4968
  /* get the user+password information from the old_conn struct since it may
 
4969
   * be new for this request even when we re-use an existing connection */
 
4970
  conn->bits.user_passwd = old_conn->bits.user_passwd;
 
4971
  if(conn->bits.user_passwd) {
 
4972
    /* use the new user name and password though */
 
4973
    Curl_safefree(conn->user);
 
4974
    Curl_safefree(conn->passwd);
 
4975
    conn->user = old_conn->user;
 
4976
    conn->passwd = old_conn->passwd;
 
4977
    old_conn->user = NULL;
 
4978
    old_conn->passwd = NULL;
 
4979
  }
 
4980
 
 
4981
  conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
 
4982
  if(conn->bits.proxy_user_passwd) {
 
4983
    /* use the new proxy user name and proxy password though */
 
4984
    Curl_safefree(conn->proxyuser);
 
4985
    Curl_safefree(conn->proxypasswd);
 
4986
    conn->proxyuser = old_conn->proxyuser;
 
4987
    conn->proxypasswd = old_conn->proxypasswd;
 
4988
    old_conn->proxyuser = NULL;
 
4989
    old_conn->proxypasswd = NULL;
 
4990
  }
 
4991
 
 
4992
  /* host can change, when doing keepalive with a proxy or if the case is
 
4993
     different this time etc */
 
4994
  Curl_safefree(conn->host.rawalloc);
 
4995
  conn->host=old_conn->host;
 
4996
 
 
4997
  /* persist connection info in session handle */
 
4998
  Curl_persistconninfo(conn);
 
4999
 
 
5000
  /* re-use init */
 
5001
  conn->bits.reuse = TRUE; /* yes, we're re-using here */
 
5002
 
 
5003
  Curl_safefree(old_conn->user);
 
5004
  Curl_safefree(old_conn->passwd);
 
5005
  Curl_safefree(old_conn->proxyuser);
 
5006
  Curl_safefree(old_conn->proxypasswd);
 
5007
  Curl_safefree(old_conn->localdev);
 
5008
 
 
5009
  Curl_llist_destroy(old_conn->send_pipe, NULL);
 
5010
  Curl_llist_destroy(old_conn->recv_pipe, NULL);
 
5011
 
 
5012
  old_conn->send_pipe = NULL;
 
5013
  old_conn->recv_pipe = NULL;
 
5014
 
 
5015
  Curl_safefree(old_conn->master_buffer);
 
5016
}
 
5017
 
 
5018
/**
 
5019
 * create_conn() sets up a new connectdata struct, or re-uses an already
 
5020
 * existing one, and resolves host name.
 
5021
 *
 
5022
 * if this function returns CURLE_OK and *async is set to TRUE, the resolve
 
5023
 * response will be coming asynchronously. If *async is FALSE, the name is
 
5024
 * already resolved.
 
5025
 *
 
5026
 * @param data The sessionhandle pointer
 
5027
 * @param in_connect is set to the next connection data pointer
 
5028
 * @param async is set TRUE when an async DNS resolution is pending
 
5029
 * @see Curl_setup_conn()
 
5030
 *
 
5031
 * *NOTE* this function assigns the conn->data pointer!
 
5032
 */
 
5033
 
 
5034
static CURLcode create_conn(struct SessionHandle *data,
 
5035
                            struct connectdata **in_connect,
 
5036
                            bool *async)
 
5037
{
 
5038
  CURLcode result = CURLE_OK;
 
5039
  struct connectdata *conn;
 
5040
  struct connectdata *conn_temp = NULL;
 
5041
  size_t urllen;
 
5042
  char *user = NULL;
 
5043
  char *passwd = NULL;
 
5044
  char *options = NULL;
 
5045
  bool reuse;
 
5046
  char *proxy = NULL;
 
5047
  bool prot_missing = FALSE;
 
5048
  bool no_connections_available = FALSE;
 
5049
  bool force_reuse;
 
5050
  size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
 
5051
  size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
 
5052
 
 
5053
  *async = FALSE;
 
5054
 
 
5055
  /*************************************************************
 
5056
   * Check input data
 
5057
   *************************************************************/
 
5058
 
 
5059
  if(!data->change.url) {
 
5060
    result = CURLE_URL_MALFORMAT;
 
5061
    goto out;
 
5062
  }
 
5063
 
 
5064
  /* First, split up the current URL in parts so that we can use the
 
5065
     parts for checking against the already present connections. In order
 
5066
     to not have to modify everything at once, we allocate a temporary
 
5067
     connection data struct and fill in for comparison purposes. */
 
5068
  conn = allocate_conn(data);
 
5069
 
 
5070
  if(!conn) {
 
5071
    result = CURLE_OUT_OF_MEMORY;
 
5072
    goto out;
 
5073
  }
 
5074
 
 
5075
  /* We must set the return variable as soon as possible, so that our
 
5076
     parent can cleanup any possible allocs we may have done before
 
5077
     any failure */
 
5078
  *in_connect = conn;
 
5079
 
 
5080
  /* This initing continues below, see the comment "Continue connectdata
 
5081
   * initialization here" */
 
5082
 
 
5083
  /***********************************************************
 
5084
   * We need to allocate memory to store the path in. We get the size of the
 
5085
   * full URL to be sure, and we need to make it at least 256 bytes since
 
5086
   * other parts of the code will rely on this fact
 
5087
   ***********************************************************/
 
5088
#define LEAST_PATH_ALLOC 256
 
5089
  urllen=strlen(data->change.url);
 
5090
  if(urllen < LEAST_PATH_ALLOC)
 
5091
    urllen=LEAST_PATH_ALLOC;
 
5092
 
 
5093
  /*
 
5094
   * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
 
5095
   * 1 - an extra terminating zero
 
5096
   * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
 
5097
   */
 
5098
 
 
5099
  Curl_safefree(data->state.pathbuffer);
 
5100
  data->state.path = NULL;
 
5101
 
 
5102
  data->state.pathbuffer = malloc(urllen+2);
 
5103
  if(NULL == data->state.pathbuffer) {
 
5104
    result = CURLE_OUT_OF_MEMORY; /* really bad error */
 
5105
    goto out;
 
5106
  }
 
5107
  data->state.path = data->state.pathbuffer;
 
5108
 
 
5109
  conn->host.rawalloc = malloc(urllen+2);
 
5110
  if(NULL == conn->host.rawalloc) {
 
5111
    Curl_safefree(data->state.pathbuffer);
 
5112
    data->state.path = NULL;
 
5113
    result = CURLE_OUT_OF_MEMORY;
 
5114
    goto out;
 
5115
  }
 
5116
 
 
5117
  conn->host.name = conn->host.rawalloc;
 
5118
  conn->host.name[0] = 0;
 
5119
 
 
5120
  user = strdup("");
 
5121
  passwd = strdup("");
 
5122
  options = strdup("");
 
5123
  if(!user || !passwd || !options) {
 
5124
    result = CURLE_OUT_OF_MEMORY;
 
5125
    goto out;
 
5126
  }
 
5127
 
 
5128
  result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
 
5129
                               &options);
 
5130
  if(result != CURLE_OK)
 
5131
    goto out;
 
5132
 
 
5133
  /*************************************************************
 
5134
   * No protocol part in URL was used, add it!
 
5135
   *************************************************************/
 
5136
  if(prot_missing) {
 
5137
    /* We're guessing prefixes here and if we're told to use a proxy or if
 
5138
       we're gonna follow a Location: later or... then we need the protocol
 
5139
       part added so that we have a valid URL. */
 
5140
    char *reurl;
 
5141
 
 
5142
    reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
 
5143
 
 
5144
    if(!reurl) {
 
5145
      result = CURLE_OUT_OF_MEMORY;
 
5146
      goto out;
 
5147
    }
 
5148
 
 
5149
    if(data->change.url_alloc) {
 
5150
      Curl_safefree(data->change.url);
 
5151
      data->change.url_alloc = FALSE;
 
5152
    }
 
5153
 
 
5154
    data->change.url = reurl;
 
5155
    data->change.url_alloc = TRUE; /* free this later */
 
5156
  }
 
5157
 
 
5158
  /*************************************************************
 
5159
   * If the protocol can't handle url query strings, then cut
 
5160
   * of the unhandable part
 
5161
   *************************************************************/
 
5162
  if((conn->given->flags&PROTOPT_NOURLQUERY)) {
 
5163
    char *path_q_sep = strchr(conn->data->state.path, '?');
 
5164
    if(path_q_sep) {
 
5165
      /* according to rfc3986, allow the query (?foo=bar)
 
5166
         also on protocols that can't handle it.
 
5167
 
 
5168
         cut the string-part after '?'
 
5169
      */
 
5170
 
 
5171
      /* terminate the string */
 
5172
      path_q_sep[0] = 0;
 
5173
    }
 
5174
  }
 
5175
 
 
5176
  if(data->set.str[STRING_BEARER]) {
 
5177
    conn->xoauth2_bearer = strdup(data->set.str[STRING_BEARER]);
 
5178
    if(!conn->xoauth2_bearer) {
 
5179
      result = CURLE_OUT_OF_MEMORY;
 
5180
      goto out;
 
5181
    }
 
5182
  }
 
5183
 
 
5184
#ifndef CURL_DISABLE_PROXY
 
5185
  /*************************************************************
 
5186
   * Extract the user and password from the authentication string
 
5187
   *************************************************************/
 
5188
  if(conn->bits.proxy_user_passwd) {
 
5189
    result = parse_proxy_auth(data, conn);
 
5190
    if(result != CURLE_OK)
 
5191
      goto out;
 
5192
  }
 
5193
 
 
5194
  /*************************************************************
 
5195
   * Detect what (if any) proxy to use
 
5196
   *************************************************************/
 
5197
  if(data->set.str[STRING_PROXY]) {
 
5198
    proxy = strdup(data->set.str[STRING_PROXY]);
 
5199
    /* if global proxy is set, this is it */
 
5200
    if(NULL == proxy) {
 
5201
      failf(data, "memory shortage");
 
5202
      result = CURLE_OUT_OF_MEMORY;
 
5203
      goto out;
 
5204
    }
 
5205
  }
 
5206
 
 
5207
  if(data->set.str[STRING_NOPROXY] &&
 
5208
     check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
 
5209
    if(proxy) {
 
5210
      free(proxy);  /* proxy is in exception list */
 
5211
      proxy = NULL;
 
5212
    }
 
5213
  }
 
5214
  else if(!proxy)
 
5215
    proxy = detect_proxy(conn);
 
5216
 
 
5217
  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
 
5218
    free(proxy);  /* Don't bother with an empty proxy string or if the
 
5219
                     protocol doesn't work with network */
 
5220
    proxy = NULL;
 
5221
  }
 
5222
 
 
5223
  /***********************************************************************
 
5224
   * If this is supposed to use a proxy, we need to figure out the proxy host
 
5225
   * name, proxy type and port number, so that we can re-use an existing
 
5226
   * connection that may exist registered to the same proxy host.
 
5227
   ***********************************************************************/
 
5228
  if(proxy) {
 
5229
    result = parse_proxy(data, conn, proxy);
 
5230
 
 
5231
    Curl_safefree(proxy); /* parse_proxy copies the proxy string */
 
5232
 
 
5233
    if(result)
 
5234
      goto out;
 
5235
 
 
5236
    if((conn->proxytype == CURLPROXY_HTTP) ||
 
5237
       (conn->proxytype == CURLPROXY_HTTP_1_0)) {
 
5238
#ifdef CURL_DISABLE_HTTP
 
5239
      /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
 
5240
      result = CURLE_UNSUPPORTED_PROTOCOL;
 
5241
      goto out;
 
5242
#else
 
5243
      /* force this connection's protocol to become HTTP if not already
 
5244
         compatible - if it isn't tunneling through */
 
5245
      if(!(conn->handler->protocol & CURLPROTO_HTTP) &&
 
5246
         !conn->bits.tunnel_proxy)
 
5247
        conn->handler = &Curl_handler_http;
 
5248
 
 
5249
      conn->bits.httpproxy = TRUE;
 
5250
#endif
 
5251
    }
 
5252
    else
 
5253
      conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
 
5254
    conn->bits.proxy = TRUE;
 
5255
  }
 
5256
  else {
 
5257
    /* we aren't using the proxy after all... */
 
5258
    conn->bits.proxy = FALSE;
 
5259
    conn->bits.httpproxy = FALSE;
 
5260
    conn->bits.proxy_user_passwd = FALSE;
 
5261
    conn->bits.tunnel_proxy = FALSE;
 
5262
  }
 
5263
 
 
5264
#endif /* CURL_DISABLE_PROXY */
 
5265
 
 
5266
  /*************************************************************
 
5267
   * If the protocol is using SSL and HTTP proxy is used, we set
 
5268
   * the tunnel_proxy bit.
 
5269
   *************************************************************/
 
5270
  if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
 
5271
    conn->bits.tunnel_proxy = TRUE;
 
5272
 
 
5273
  /*************************************************************
 
5274
   * Figure out the remote port number and fix it in the URL
 
5275
   *************************************************************/
 
5276
  result = parse_remote_port(data, conn);
 
5277
  if(result != CURLE_OK)
 
5278
    goto out;
 
5279
 
 
5280
  /* Check for overridden login details and set them accordingly so they
 
5281
     they are known when protocol->setup_connection is called! */
 
5282
  result = override_login(data, conn, &user, &passwd, &options);
 
5283
  if(result != CURLE_OK)
 
5284
    goto out;
 
5285
  result = set_login(conn, user, passwd, options);
 
5286
  if(result != CURLE_OK)
 
5287
    goto out;
 
5288
 
 
5289
  /*************************************************************
 
5290
   * Setup internals depending on protocol. Needs to be done after
 
5291
   * we figured out what/if proxy to use.
 
5292
   *************************************************************/
 
5293
  result = setup_connection_internals(conn);
 
5294
  if(result != CURLE_OK)
 
5295
    goto out;
 
5296
 
 
5297
  conn->recv[FIRSTSOCKET] = Curl_recv_plain;
 
5298
  conn->send[FIRSTSOCKET] = Curl_send_plain;
 
5299
  conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
 
5300
  conn->send[SECONDARYSOCKET] = Curl_send_plain;
 
5301
 
 
5302
  /***********************************************************************
 
5303
   * file: is a special case in that it doesn't need a network connection
 
5304
   ***********************************************************************/
 
5305
#ifndef CURL_DISABLE_FILE
 
5306
  if(conn->handler->flags & PROTOPT_NONETWORK) {
 
5307
    bool done;
 
5308
    /* this is supposed to be the connect function so we better at least check
 
5309
       that the file is present here! */
 
5310
    DEBUGASSERT(conn->handler->connect_it);
 
5311
    result = conn->handler->connect_it(conn, &done);
 
5312
 
 
5313
    /* Setup a "faked" transfer that'll do nothing */
 
5314
    if(CURLE_OK == result) {
 
5315
      conn->data = data;
 
5316
      conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
 
5317
 
 
5318
      ConnectionStore(data, conn);
 
5319
 
 
5320
      /*
 
5321
       * Setup whatever necessary for a resumed transfer
 
5322
       */
 
5323
      result = setup_range(data);
 
5324
      if(result) {
 
5325
        DEBUGASSERT(conn->handler->done);
 
5326
        /* we ignore the return code for the protocol-specific DONE */
 
5327
        (void)conn->handler->done(conn, result, FALSE);
 
5328
        goto out;
 
5329
      }
 
5330
 
 
5331
      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
 
5332
                          -1, NULL); /* no upload */
 
5333
    }
 
5334
 
 
5335
    /* since we skip do_init() */
 
5336
    do_init(conn);
 
5337
 
 
5338
    goto out;
 
5339
  }
 
5340
#endif
 
5341
 
 
5342
  /* Get a cloned copy of the SSL config situation stored in the
 
5343
     connection struct. But to get this going nicely, we must first make
 
5344
     sure that the strings in the master copy are pointing to the correct
 
5345
     strings in the session handle strings array!
 
5346
 
 
5347
     Keep in mind that the pointers in the master copy are pointing to strings
 
5348
     that will be freed as part of the SessionHandle struct, but all cloned
 
5349
     copies will be separately allocated.
 
5350
  */
 
5351
  data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
 
5352
  data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
 
5353
  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
 
5354
  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
 
5355
  data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
 
5356
  data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
 
5357
  data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
 
5358
#ifdef USE_TLS_SRP
 
5359
  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
 
5360
  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
 
5361
#endif
 
5362
 
 
5363
  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
 
5364
    result = CURLE_OUT_OF_MEMORY;
 
5365
    goto out;
 
5366
  }
 
5367
 
 
5368
  /*************************************************************
 
5369
   * Check the current list of connections to see if we can
 
5370
   * re-use an already existing one or if we have to create a
 
5371
   * new one.
 
5372
   *************************************************************/
 
5373
 
 
5374
  /* reuse_fresh is TRUE if we are told to use a new connection by force, but
 
5375
     we only acknowledge this option if this is not a re-used connection
 
5376
     already (which happens due to follow-location or during a HTTP
 
5377
     authentication phase). */
 
5378
  if(data->set.reuse_fresh && !data->state.this_is_a_follow)
 
5379
    reuse = FALSE;
 
5380
  else
 
5381
    reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse);
 
5382
 
 
5383
  /* If we found a reusable connection, we may still want to
 
5384
     open a new connection if we are pipelining. */
 
5385
  if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
 
5386
    size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
 
5387
    if(pipelen > 0) {
 
5388
      infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
 
5389
            conn_temp->connection_id, pipelen);
 
5390
 
 
5391
      if(conn_temp->bundle->num_connections < max_host_connections &&
 
5392
         data->state.conn_cache->num_connections < max_total_connections) {
 
5393
        /* We want a new connection anyway */
 
5394
        reuse = FALSE;
 
5395
 
 
5396
        infof(data, "We can reuse, but we want a new connection anyway\n");
 
5397
      }
 
5398
    }
 
5399
  }
 
5400
 
 
5401
  if(reuse) {
 
5402
    /*
 
5403
     * We already have a connection for this, we got the former connection
 
5404
     * in the conn_temp variable and thus we need to cleanup the one we
 
5405
     * just allocated before we can move along and use the previously
 
5406
     * existing one.
 
5407
     */
 
5408
    conn_temp->inuse = TRUE; /* mark this as being in use so that no other
 
5409
                                handle in a multi stack may nick it */
 
5410
    reuse_conn(conn, conn_temp);
 
5411
    free(conn);          /* we don't need this anymore */
 
5412
    conn = conn_temp;
 
5413
    *in_connect = conn;
 
5414
 
 
5415
    /* set a pointer to the hostname we display */
 
5416
    fix_hostname(data, conn, &conn->host);
 
5417
 
 
5418
    infof(data, "Re-using existing connection! (#%ld) with host %s\n",
 
5419
          conn->connection_id,
 
5420
          conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
 
5421
  }
 
5422
  else {
 
5423
    /* We have decided that we want a new connection. However, we may not
 
5424
       be able to do that if we have reached the limit of how many
 
5425
       connections we are allowed to open. */
 
5426
    struct connectbundle *bundle;
 
5427
 
 
5428
    bundle = Curl_conncache_find_bundle(data->state.conn_cache,
 
5429
                                        conn->host.name);
 
5430
    if(max_host_connections > 0 && bundle &&
 
5431
       (bundle->num_connections >= max_host_connections)) {
 
5432
      struct connectdata *conn_candidate;
 
5433
 
 
5434
      /* The bundle is full. Let's see if we can kill a connection. */
 
5435
      conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
 
5436
 
 
5437
      if(conn_candidate) {
 
5438
        /* Set the connection's owner correctly, then kill it */
 
5439
        conn_candidate->data = data;
 
5440
        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
 
5441
      }
 
5442
      else
 
5443
        no_connections_available = TRUE;
 
5444
    }
 
5445
 
 
5446
    if(max_total_connections > 0 &&
 
5447
       (data->state.conn_cache->num_connections >= max_total_connections)) {
 
5448
      struct connectdata *conn_candidate;
 
5449
 
 
5450
      /* The cache is full. Let's see if we can kill a connection. */
 
5451
      conn_candidate = find_oldest_idle_connection(data);
 
5452
 
 
5453
      if(conn_candidate) {
 
5454
        /* Set the connection's owner correctly, then kill it */
 
5455
        conn_candidate->data = data;
 
5456
        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
 
5457
      }
 
5458
      else
 
5459
        no_connections_available = TRUE;
 
5460
    }
 
5461
 
 
5462
 
 
5463
    if(no_connections_available) {
 
5464
      infof(data, "No connections available.\n");
 
5465
 
 
5466
      conn_free(conn);
 
5467
      *in_connect = NULL;
 
5468
 
 
5469
      result = CURLE_NO_CONNECTION_AVAILABLE;
 
5470
      goto out;
 
5471
    }
 
5472
    else {
 
5473
      /*
 
5474
       * This is a brand new connection, so let's store it in the connection
 
5475
       * cache of ours!
 
5476
       */
 
5477
      ConnectionStore(data, conn);
 
5478
    }
 
5479
  }
 
5480
 
 
5481
  /* Mark the connection as used */
 
5482
  conn->inuse = TRUE;
 
5483
 
 
5484
  /* Setup and init stuff before DO starts, in preparing for the transfer. */
 
5485
  do_init(conn);
 
5486
 
 
5487
  /*
 
5488
   * Setup whatever necessary for a resumed transfer
 
5489
   */
 
5490
  result = setup_range(data);
 
5491
  if(result)
 
5492
    goto out;
 
5493
 
 
5494
  /* Continue connectdata initialization here. */
 
5495
 
 
5496
  /*
 
5497
   * Inherit the proper values from the urldata struct AFTER we have arranged
 
5498
   * the persistent connection stuff
 
5499
   */
 
5500
  conn->fread_func = data->set.fread_func;
 
5501
  conn->fread_in = data->set.in;
 
5502
  conn->seek_func = data->set.seek_func;
 
5503
  conn->seek_client = data->set.seek_client;
 
5504
 
 
5505
  /*************************************************************
 
5506
   * Resolve the address of the server or proxy
 
5507
   *************************************************************/
 
5508
  result = resolve_server(data, conn, async);
 
5509
 
 
5510
  out:
 
5511
 
 
5512
  Curl_safefree(options);
 
5513
  Curl_safefree(passwd);
 
5514
  Curl_safefree(user);
 
5515
  Curl_safefree(proxy);
 
5516
  return result;
 
5517
}
 
5518
 
 
5519
/* Curl_setup_conn() is called after the name resolve initiated in
 
5520
 * create_conn() is all done.
 
5521
 *
 
5522
 * Curl_setup_conn() also handles reused connections
 
5523
 *
 
5524
 * conn->data MUST already have been setup fine (in create_conn)
 
5525
 */
 
5526
 
 
5527
CURLcode Curl_setup_conn(struct connectdata *conn,
 
5528
                         bool *protocol_done)
 
5529
{
 
5530
  CURLcode result = CURLE_OK;
 
5531
  struct SessionHandle *data = conn->data;
 
5532
 
 
5533
  Curl_pgrsTime(data, TIMER_NAMELOOKUP);
 
5534
 
 
5535
  if(conn->handler->flags & PROTOPT_NONETWORK) {
 
5536
    /* nothing to setup when not using a network */
 
5537
    *protocol_done = TRUE;
 
5538
    return result;
 
5539
  }
 
5540
  *protocol_done = FALSE; /* default to not done */
 
5541
 
 
5542
  /* set proxy_connect_closed to false unconditionally already here since it
 
5543
     is used strictly to provide extra information to a parent function in the
 
5544
     case of proxy CONNECT failures and we must make sure we don't have it
 
5545
     lingering set from a previous invoke */
 
5546
  conn->bits.proxy_connect_closed = FALSE;
 
5547
 
 
5548
  /*
 
5549
   * Set user-agent. Used for HTTP, but since we can attempt to tunnel
 
5550
   * basically anything through a http proxy we can't limit this based on
 
5551
   * protocol.
 
5552
   */
 
5553
  if(data->set.str[STRING_USERAGENT]) {
 
5554
    Curl_safefree(conn->allocptr.uagent);
 
5555
    conn->allocptr.uagent =
 
5556
      aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
 
5557
    if(!conn->allocptr.uagent)
 
5558
      return CURLE_OUT_OF_MEMORY;
 
5559
  }
 
5560
 
 
5561
  data->req.headerbytecount = 0;
 
5562
 
 
5563
#ifdef CURL_DO_LINEEND_CONV
 
5564
  data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
 
5565
#endif /* CURL_DO_LINEEND_CONV */
 
5566
 
 
5567
  /* set start time here for timeout purposes in the connect procedure, it
 
5568
     is later set again for the progress meter purpose */
 
5569
  conn->now = Curl_tvnow();
 
5570
 
 
5571
  if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
 
5572
    conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
 
5573
    result = Curl_connecthost(conn, conn->dns_entry);
 
5574
    if(result)
 
5575
      return result;
 
5576
  }
 
5577
  else {
 
5578
    Curl_pgrsTime(data, TIMER_CONNECT);    /* we're connected already */
 
5579
    Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
 
5580
    conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
 
5581
    *protocol_done = TRUE;
 
5582
    Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
 
5583
    Curl_verboseconnect(conn);
 
5584
  }
 
5585
 
 
5586
  conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
 
5587
                               set this here perhaps a second time */
 
5588
 
 
5589
#ifdef __EMX__
 
5590
  /*
 
5591
   * This check is quite a hack. We're calling _fsetmode to fix the problem
 
5592
   * with fwrite converting newline characters (you get mangled text files,
 
5593
   * and corrupted binary files when you download to stdout and redirect it to
 
5594
   * a file).
 
5595
   */
 
5596
 
 
5597
  if((data->set.out)->_handle == NULL) {
 
5598
    _fsetmode(stdout, "b");
 
5599
  }
 
5600
#endif
 
5601
 
 
5602
  return result;
 
5603
}
 
5604
 
 
5605
CURLcode Curl_connect(struct SessionHandle *data,
 
5606
                      struct connectdata **in_connect,
 
5607
                      bool *asyncp,
 
5608
                      bool *protocol_done)
 
5609
{
 
5610
  CURLcode code;
 
5611
 
 
5612
  *asyncp = FALSE; /* assume synchronous resolves by default */
 
5613
 
 
5614
  /* call the stuff that needs to be called */
 
5615
  code = create_conn(data, in_connect, asyncp);
 
5616
 
 
5617
  if(CURLE_OK == code) {
 
5618
    /* no error */
 
5619
    if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
 
5620
      /* pipelining */
 
5621
      *protocol_done = TRUE;
 
5622
    else if(!*asyncp) {
 
5623
      /* DNS resolution is done: that's either because this is a reused
 
5624
         connection, in which case DNS was unnecessary, or because DNS
 
5625
         really did finish already (synch resolver/fast async resolve) */
 
5626
      code = Curl_setup_conn(*in_connect, protocol_done);
 
5627
    }
 
5628
  }
 
5629
 
 
5630
  if(code == CURLE_NO_CONNECTION_AVAILABLE) {
 
5631
    *in_connect = NULL;
 
5632
    return code;
 
5633
  }
 
5634
 
 
5635
  if(code && *in_connect) {
 
5636
    /* We're not allowed to return failure with memory left allocated
 
5637
       in the connectdata struct, free those here */
 
5638
    Curl_disconnect(*in_connect, FALSE); /* close the connection */
 
5639
    *in_connect = NULL;           /* return a NULL */
 
5640
  }
 
5641
 
 
5642
  return code;
 
5643
}
 
5644
 
 
5645
CURLcode Curl_done(struct connectdata **connp,
 
5646
                   CURLcode status,  /* an error if this is called after an
 
5647
                                        error was detected */
 
5648
                   bool premature)
 
5649
{
 
5650
  CURLcode result;
 
5651
  struct connectdata *conn;
 
5652
  struct SessionHandle *data;
 
5653
 
 
5654
  DEBUGASSERT(*connp);
 
5655
 
 
5656
  conn = *connp;
 
5657
  data = conn->data;
 
5658
 
 
5659
  if(conn->bits.done)
 
5660
    /* Stop if Curl_done() has already been called */
 
5661
    return CURLE_OK;
 
5662
 
 
5663
  Curl_getoff_all_pipelines(data, conn);
 
5664
 
 
5665
  if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
 
5666
      !data->set.reuse_forbid &&
 
5667
      !conn->bits.close))
 
5668
    /* Stop if pipeline is not empty and we do not have to close
 
5669
       connection. */
 
5670
    return CURLE_OK;
 
5671
 
 
5672
  conn->bits.done = TRUE; /* called just now! */
 
5673
 
 
5674
  /* Cleanup possible redirect junk */
 
5675
  if(data->req.newurl) {
 
5676
    free(data->req.newurl);
 
5677
    data->req.newurl = NULL;
 
5678
  }
 
5679
  if(data->req.location) {
 
5680
    free(data->req.location);
 
5681
    data->req.location = NULL;
 
5682
  }
 
5683
 
 
5684
  Curl_resolver_cancel(conn);
 
5685
 
 
5686
  if(conn->dns_entry) {
 
5687
    Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
 
5688
    conn->dns_entry = NULL;
 
5689
  }
 
5690
 
 
5691
  switch(status) {
 
5692
  case CURLE_ABORTED_BY_CALLBACK:
 
5693
  case CURLE_READ_ERROR:
 
5694
  case CURLE_WRITE_ERROR:
 
5695
    /* When we're aborted due to a callback return code it basically have to
 
5696
       be counted as premature as there is trouble ahead if we don't. We have
 
5697
       many callbacks and protocols work differently, we could potentially do
 
5698
       this more fine-grained in the future. */
 
5699
    premature = TRUE;
 
5700
  default:
 
5701
    break;
 
5702
  }
 
5703
 
 
5704
  /* this calls the protocol-specific function pointer previously set */
 
5705
  if(conn->handler->done)
 
5706
    result = conn->handler->done(conn, status, premature);
 
5707
  else
 
5708
    result = CURLE_OK;
 
5709
 
 
5710
  if(Curl_pgrsDone(conn) && !result)
 
5711
    result = CURLE_ABORTED_BY_CALLBACK;
 
5712
 
 
5713
  /* if the transfer was completed in a paused state there can be buffered
 
5714
     data left to write and then kill */
 
5715
  if(data->state.tempwrite) {
 
5716
    free(data->state.tempwrite);
 
5717
    data->state.tempwrite = NULL;
 
5718
  }
 
5719
 
 
5720
  /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
 
5721
     forced us to close this no matter what we think.
 
5722
 
 
5723
     if conn->bits.close is TRUE, it means that the connection should be
 
5724
     closed in spite of all our efforts to be nice, due to protocol
 
5725
     restrictions in our or the server's end
 
5726
 
 
5727
     if premature is TRUE, it means this connection was said to be DONE before
 
5728
     the entire request operation is complete and thus we can't know in what
 
5729
     state it is for re-using, so we're forced to close it. In a perfect world
 
5730
     we can add code that keep track of if we really must close it here or not,
 
5731
     but currently we have no such detail knowledge.
 
5732
  */
 
5733
  if(data->set.reuse_forbid || conn->bits.close || premature) {
 
5734
    CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
 
5735
 
 
5736
    /* If we had an error already, make sure we return that one. But
 
5737
       if we got a new error, return that. */
 
5738
    if(!result && res2)
 
5739
      result = res2;
 
5740
  }
 
5741
  else {
 
5742
    /* the connection is no longer in use */
 
5743
    if(ConnectionDone(data, conn)) {
 
5744
      /* remember the most recently used connection */
 
5745
      data->state.lastconnect = conn;
 
5746
 
 
5747
      infof(data, "Connection #%ld to host %s left intact\n",
 
5748
            conn->connection_id,
 
5749
            conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
 
5750
    }
 
5751
    else
 
5752
      data->state.lastconnect = NULL;
 
5753
  }
 
5754
 
 
5755
  *connp = NULL; /* to make the caller of this function better detect that
 
5756
                    this was either closed or handed over to the connection
 
5757
                    cache here, and therefore cannot be used from this point on
 
5758
                 */
 
5759
  Curl_free_request_state(data);
 
5760
 
 
5761
  return result;
 
5762
}
 
5763
 
 
5764
/*
 
5765
 * do_init() inits the readwrite session. This is inited each time (in the DO
 
5766
 * function before the protocol-specific DO functions are invoked) for a
 
5767
 * transfer, sometimes multiple times on the same SessionHandle. Make sure
 
5768
 * nothing in here depends on stuff that are setup dynamically for the
 
5769
 * transfer.
 
5770
 */
 
5771
 
 
5772
static CURLcode do_init(struct connectdata *conn)
 
5773
{
 
5774
  struct SessionHandle *data = conn->data;
 
5775
  struct SingleRequest *k = &data->req;
 
5776
 
 
5777
  conn->bits.done = FALSE; /* Curl_done() is not called yet */
 
5778
  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
 
5779
  data->state.expect100header = FALSE;
 
5780
 
 
5781
  if(data->set.opt_no_body)
 
5782
    /* in HTTP lingo, no body means using the HEAD request... */
 
5783
    data->set.httpreq = HTTPREQ_HEAD;
 
5784
  else if(HTTPREQ_HEAD == data->set.httpreq)
 
5785
    /* ... but if unset there really is no perfect method that is the
 
5786
       "opposite" of HEAD but in reality most people probably think GET
 
5787
       then. The important thing is that we can't let it remain HEAD if the
 
5788
       opt_no_body is set FALSE since then we'll behave wrong when getting
 
5789
       HTTP. */
 
5790
    data->set.httpreq = HTTPREQ_GET;
 
5791
 
 
5792
  k->start = Curl_tvnow(); /* start time */
 
5793
  k->now = k->start;   /* current time is now */
 
5794
  k->header = TRUE; /* assume header */
 
5795
 
 
5796
  k->bytecount = 0;
 
5797
 
 
5798
  k->buf = data->state.buffer;
 
5799
  k->uploadbuf = data->state.uploadbuffer;
 
5800
  k->hbufp = data->state.headerbuff;
 
5801
  k->ignorebody=FALSE;
 
5802
 
 
5803
  Curl_speedinit(data);
 
5804
 
 
5805
  Curl_pgrsSetUploadCounter(data, 0);
 
5806
  Curl_pgrsSetDownloadCounter(data, 0);
 
5807
 
 
5808
  return CURLE_OK;
 
5809
}
 
5810
 
 
5811
/*
 
5812
 * do_complete is called when the DO actions are complete.
 
5813
 *
 
5814
 * We init chunking and trailer bits to their default values here immediately
 
5815
 * before receiving any header data for the current request in the pipeline.
 
5816
 */
 
5817
static void do_complete(struct connectdata *conn)
 
5818
{
 
5819
  conn->data->req.chunk=FALSE;
 
5820
  conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
 
5821
                           conn->sockfd:conn->writesockfd)+1;
 
5822
  Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
 
5823
}
 
5824
 
 
5825
CURLcode Curl_do(struct connectdata **connp, bool *done)
 
5826
{
 
5827
  CURLcode result=CURLE_OK;
 
5828
  struct connectdata *conn = *connp;
 
5829
  struct SessionHandle *data = conn->data;
 
5830
 
 
5831
  if(conn->handler->do_it) {
 
5832
    /* generic protocol-specific function pointer set in curl_connect() */
 
5833
    result = conn->handler->do_it(conn, done);
 
5834
 
 
5835
    /* This was formerly done in transfer.c, but we better do it here */
 
5836
    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
 
5837
      /*
 
5838
       * If the connection is using an easy handle, call reconnect
 
5839
       * to re-establish the connection.  Otherwise, let the multi logic
 
5840
       * figure out how to re-establish the connection.
 
5841
       */
 
5842
      if(!data->multi) {
 
5843
        result = Curl_reconnect_request(connp);
 
5844
 
 
5845
        if(result == CURLE_OK) {
 
5846
          /* ... finally back to actually retry the DO phase */
 
5847
          conn = *connp; /* re-assign conn since Curl_reconnect_request
 
5848
                            creates a new connection */
 
5849
          result = conn->handler->do_it(conn, done);
 
5850
        }
 
5851
      }
 
5852
      else
 
5853
        return result;
 
5854
    }
 
5855
 
 
5856
    if((result == CURLE_OK) && *done)
 
5857
      /* do_complete must be called after the protocol-specific DO function */
 
5858
      do_complete(conn);
 
5859
  }
 
5860
  return result;
 
5861
}
 
5862
 
 
5863
/*
 
5864
 * Curl_do_more() is called during the DO_MORE multi state. It is basically a
 
5865
 * second stage DO state which (wrongly) was introduced to support FTP's
 
5866
 * second connection.
 
5867
 *
 
5868
 * TODO: A future libcurl should be able to work away this state.
 
5869
 *
 
5870
 * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
 
5871
 * DOING state there's more work to do!
 
5872
 */
 
5873
 
 
5874
CURLcode Curl_do_more(struct connectdata *conn, int *complete)
 
5875
{
 
5876
  CURLcode result=CURLE_OK;
 
5877
 
 
5878
  *complete = 0;
 
5879
 
 
5880
  if(conn->handler->do_more)
 
5881
    result = conn->handler->do_more(conn, complete);
 
5882
 
 
5883
  if(!result && (*complete == 1))
 
5884
    /* do_complete must be called after the protocol-specific DO function */
 
5885
    do_complete(conn);
 
5886
 
 
5887
  return result;
 
5888
}
 
5889