~ubuntu-branches/ubuntu/wily/curl/wily

« back to all changes in this revision

Viewing changes to .pc/CVE-2015-3144.patch/lib/url.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-05-05 14:17:51 UTC
  • Revision ID: package-import@ubuntu.com-20150505141751-g5v1qb9ivse33jqs
Tags: 7.38.0-3ubuntu3
* SECURITY UPDATE: NTLM connection reuse when unauthenticated
  - debian/patches/CVE-2015-3143.patch: require credentials to match in
    lib/url.c.
  - CVE-2015-3143
* SECURITY UPDATE: host name out of boundary memory access
  - debian/patches/CVE-2015-3144.patch: check for valid length in
    lib/url.c.
  - CVE-2015-3144
* SECURITY UPDATE: cookie parser out of boundary memory access
  - debian/patches/CVE-2015-3145.patch: properly handle a single double
    quote in lib/cookie.c.
  - CVE-2015-3145
* SECURITY UPDATE: negotiate not treated as connection-oriented
  - debian/patches/CVE-2015-3148.patch: close Negotiate connections when
    done in lib/http.c.
  - CVE-2015-3148
* SECURITY UPDATE: sensitive HTTP server headers disclosure to proxies
  - debian/patches/CVE-2015-3153.patch: make HTTP headers separated in
    docs/libcurl/opts/CURLOPT_HEADEROPT.3, lib/url.c,
    tests/data/test1527, tests/data/test287, tests/libtest/lib1527.c.
  - CVE-2015-3153

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