Apply DLP feature
[platform/upstream/curl.git] / lib / easy.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2018, 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 https://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 /*
26  * See comment in curl_memory.h for the explanation of this sanity check.
27  */
28
29 #ifdef CURLX_NO_MEMORY_CALLBACKS
30 #error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
31 #endif
32
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
35 #endif
36 #ifdef HAVE_NETDB_H
37 #include <netdb.h>
38 #endif
39 #ifdef HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
41 #endif
42 #ifdef HAVE_NET_IF_H
43 #include <net/if.h>
44 #endif
45 #ifdef HAVE_SYS_IOCTL_H
46 #include <sys/ioctl.h>
47 #endif
48
49 #ifdef HAVE_SYS_PARAM_H
50 #include <sys/param.h>
51 #endif
52
53 #include "urldata.h"
54 #include <curl/curl.h>
55 #include "transfer.h"
56 #include "vtls/vtls.h"
57 #include "url.h"
58 #include "getinfo.h"
59 #include "hostip.h"
60 #include "share.h"
61 #include "strdup.h"
62 #include "progress.h"
63 #include "easyif.h"
64 #include "multiif.h"
65 #include "select.h"
66 #include "sendf.h" /* for failf function prototype */
67 #include "connect.h" /* for Curl_getconnectinfo */
68 #include "slist.h"
69 #include "mime.h"
70 #include "amigaos.h"
71 #include "non-ascii.h"
72 #include "warnless.h"
73 #include "multiif.h"
74 #include "sigpipe.h"
75 #include "ssh.h"
76 #include "setopt.h"
77 #include "http_digest.h"
78
79 /* The last 3 #include files should be in this order */
80 #include "curl_printf.h"
81 #include "curl_memory.h"
82 #include "memdebug.h"
83 #ifdef USE_TIZEN_FEATURE_DLP
84 #include "extensions/curl_extensions.h"
85 #endif
86
87 void Curl_version_init(void);
88
89 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
90    of win32_init() */
91 static void win32_cleanup(void)
92 {
93 #ifdef USE_WINSOCK
94   WSACleanup();
95 #endif
96 #ifdef USE_WINDOWS_SSPI
97   Curl_sspi_global_cleanup();
98 #endif
99 }
100
101 /* win32_init() performs win32 socket initialization to properly setup the
102    stack to allow networking */
103 static CURLcode win32_init(void)
104 {
105 #ifdef USE_WINSOCK
106   WORD wVersionRequested;
107   WSADATA wsaData;
108   int res;
109
110 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
111   Error IPV6_requires_winsock2
112 #endif
113
114   wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
115
116   res = WSAStartup(wVersionRequested, &wsaData);
117
118   if(res != 0)
119     /* Tell the user that we couldn't find a useable */
120     /* winsock.dll.     */
121     return CURLE_FAILED_INIT;
122
123   /* Confirm that the Windows Sockets DLL supports what we need.*/
124   /* Note that if the DLL supports versions greater */
125   /* than wVersionRequested, it will still return */
126   /* wVersionRequested in wVersion. wHighVersion contains the */
127   /* highest supported version. */
128
129   if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
130      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
131     /* Tell the user that we couldn't find a useable */
132
133     /* winsock.dll. */
134     WSACleanup();
135     return CURLE_FAILED_INIT;
136   }
137   /* The Windows Sockets DLL is acceptable. Proceed. */
138 #elif defined(USE_LWIPSOCK)
139   lwip_init();
140 #endif
141
142 #ifdef USE_WINDOWS_SSPI
143   {
144     CURLcode result = Curl_sspi_global_init();
145     if(result)
146       return result;
147   }
148 #endif
149
150   return CURLE_OK;
151 }
152
153 /* true globals -- for curl_global_init() and curl_global_cleanup() */
154 static unsigned int  initialized;
155 static long          init_flags;
156
157 /*
158  * strdup (and other memory functions) is redefined in complicated
159  * ways, but at this point it must be defined as the system-supplied strdup
160  * so the callback pointer is initialized correctly.
161  */
162 #if defined(_WIN32_WCE)
163 #define system_strdup _strdup
164 #elif !defined(HAVE_STRDUP)
165 #define system_strdup curlx_strdup
166 #else
167 #define system_strdup strdup
168 #endif
169
170 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
171 #  pragma warning(disable:4232) /* MSVC extension, dllimport identity */
172 #endif
173
174 #ifndef __SYMBIAN32__
175 /*
176  * If a memory-using function (like curl_getenv) is used before
177  * curl_global_init() is called, we need to have these pointers set already.
178  */
179 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
180 curl_free_callback Curl_cfree = (curl_free_callback)free;
181 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
182 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
183 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
184 #if defined(WIN32) && defined(UNICODE)
185 curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
186 #endif
187 #else
188 /*
189  * Symbian OS doesn't support initialization to code in writable static data.
190  * Initialization will occur in the curl_global_init() call.
191  */
192 curl_malloc_callback Curl_cmalloc;
193 curl_free_callback Curl_cfree;
194 curl_realloc_callback Curl_crealloc;
195 curl_strdup_callback Curl_cstrdup;
196 curl_calloc_callback Curl_ccalloc;
197 #endif
198
199 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
200 #  pragma warning(default:4232) /* MSVC extension, dllimport identity */
201 #endif
202
203 /**
204  * curl_global_init() globally initializes curl given a bitwise set of the
205  * different features of what to initialize.
206  */
207 static CURLcode global_init(long flags, bool memoryfuncs)
208 {
209   if(initialized++)
210     return CURLE_OK;
211
212 #ifdef USE_TIZEN_FEATURE_DLP
213   /**
214    * Initialize Tizen DLP
215    */
216   curl_extensions_tizen_dlp_init();
217 #endif
218
219   if(memoryfuncs) {
220     /* Setup the default memory functions here (again) */
221     Curl_cmalloc = (curl_malloc_callback)malloc;
222     Curl_cfree = (curl_free_callback)free;
223     Curl_crealloc = (curl_realloc_callback)realloc;
224     Curl_cstrdup = (curl_strdup_callback)system_strdup;
225     Curl_ccalloc = (curl_calloc_callback)calloc;
226 #if defined(WIN32) && defined(UNICODE)
227     Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
228 #endif
229   }
230
231   if(!Curl_ssl_init()) {
232     DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
233     return CURLE_FAILED_INIT;
234   }
235
236   if(flags & CURL_GLOBAL_WIN32)
237     if(win32_init()) {
238       DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
239       return CURLE_FAILED_INIT;
240     }
241
242 #ifdef __AMIGA__
243   if(!Curl_amiga_init()) {
244     DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
245     return CURLE_FAILED_INIT;
246   }
247 #endif
248
249 #ifdef NETWARE
250   if(netware_init()) {
251     DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
252   }
253 #endif
254
255   if(Curl_resolver_global_init()) {
256     DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
257     return CURLE_FAILED_INIT;
258   }
259
260   (void)Curl_ipv6works();
261
262 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
263   if(libssh2_init(0)) {
264     DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
265     return CURLE_FAILED_INIT;
266   }
267 #endif
268
269 #if defined(USE_LIBSSH)
270   if(ssh_init()) {
271     DEBUGF(fprintf(stderr, "Error: libssh_init failed\n"));
272     return CURLE_FAILED_INIT;
273   }
274 #endif
275
276   if(flags & CURL_GLOBAL_ACK_EINTR)
277     Curl_ack_eintr = 1;
278
279   init_flags = flags;
280
281   Curl_version_init();
282
283   return CURLE_OK;
284 }
285
286
287 /**
288  * curl_global_init() globally initializes curl given a bitwise set of the
289  * different features of what to initialize.
290  */
291 CURLcode curl_global_init(long flags)
292 {
293   return global_init(flags, TRUE);
294 }
295
296 /*
297  * curl_global_init_mem() globally initializes curl and also registers the
298  * user provided callback routines.
299  */
300 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
301                               curl_free_callback f, curl_realloc_callback r,
302                               curl_strdup_callback s, curl_calloc_callback c)
303 {
304   /* Invalid input, return immediately */
305   if(!m || !f || !r || !s || !c)
306     return CURLE_FAILED_INIT;
307
308   if(initialized) {
309     /* Already initialized, don't do it again, but bump the variable anyway to
310        work like curl_global_init() and require the same amount of cleanup
311        calls. */
312     initialized++;
313     return CURLE_OK;
314   }
315
316   /* set memory functions before global_init() in case it wants memory
317      functions */
318   Curl_cmalloc = m;
319   Curl_cfree = f;
320   Curl_cstrdup = s;
321   Curl_crealloc = r;
322   Curl_ccalloc = c;
323
324   /* Call the actual init function, but without setting */
325   return global_init(flags, FALSE);
326 }
327
328 /**
329  * curl_global_cleanup() globally cleanups curl, uses the value of
330  * "init_flags" to determine what needs to be cleaned up and what doesn't.
331  */
332 void curl_global_cleanup(void)
333 {
334   if(!initialized)
335     return;
336
337   if(--initialized)
338     return;
339
340   Curl_global_host_cache_dtor();
341   Curl_ssl_cleanup();
342   Curl_resolver_global_cleanup();
343
344   if(init_flags & CURL_GLOBAL_WIN32)
345     win32_cleanup();
346
347   Curl_amiga_cleanup();
348
349 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
350   (void)libssh2_exit();
351 #endif
352
353 #if defined(USE_LIBSSH)
354   (void)ssh_finalize();
355 #endif
356
357   init_flags  = 0;
358 }
359
360 /*
361  * curl_easy_init() is the external interface to alloc, setup and init an
362  * easy handle that is returned. If anything goes wrong, NULL is returned.
363  */
364 struct Curl_easy *curl_easy_init(void)
365 {
366   CURLcode result;
367   struct Curl_easy *data;
368
369   /* Make sure we inited the global SSL stuff */
370   if(!initialized) {
371     result = curl_global_init(CURL_GLOBAL_DEFAULT);
372     if(result) {
373       /* something in the global init failed, return nothing */
374       DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
375       return NULL;
376     }
377   }
378
379   /* We use curl_open() with undefined URL so far */
380   result = Curl_open(&data);
381   if(result) {
382     DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
383     return NULL;
384   }
385
386   return data;
387 }
388
389 #ifdef CURLDEBUG
390
391 struct socketmonitor {
392   struct socketmonitor *next; /* the next node in the list or NULL */
393   struct pollfd socket; /* socket info of what to monitor */
394 };
395
396 struct events {
397   long ms;              /* timeout, run the timeout function when reached */
398   bool msbump;          /* set TRUE when timeout is set by callback */
399   int num_sockets;      /* number of nodes in the monitor list */
400   struct socketmonitor *list; /* list of sockets to monitor */
401   int running_handles;  /* store the returned number */
402 };
403
404 /* events_timer
405  *
406  * Callback that gets called with a new value when the timeout should be
407  * updated.
408  */
409
410 static int events_timer(struct Curl_multi *multi,    /* multi handle */
411                         long timeout_ms, /* see above */
412                         void *userp)    /* private callback pointer */
413 {
414   struct events *ev = userp;
415   (void)multi;
416   if(timeout_ms == -1)
417     /* timeout removed */
418     timeout_ms = 0;
419   else if(timeout_ms == 0)
420     /* timeout is already reached! */
421     timeout_ms = 1; /* trigger asap */
422
423   ev->ms = timeout_ms;
424   ev->msbump = TRUE;
425   return 0;
426 }
427
428
429 /* poll2cselect
430  *
431  * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
432  */
433 static int poll2cselect(int pollmask)
434 {
435   int omask = 0;
436   if(pollmask & POLLIN)
437     omask |= CURL_CSELECT_IN;
438   if(pollmask & POLLOUT)
439     omask |= CURL_CSELECT_OUT;
440   if(pollmask & POLLERR)
441     omask |= CURL_CSELECT_ERR;
442   return omask;
443 }
444
445
446 /* socketcb2poll
447  *
448  * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
449  */
450 static short socketcb2poll(int pollmask)
451 {
452   short omask = 0;
453   if(pollmask & CURL_POLL_IN)
454     omask |= POLLIN;
455   if(pollmask & CURL_POLL_OUT)
456     omask |= POLLOUT;
457   return omask;
458 }
459
460 /* events_socket
461  *
462  * Callback that gets called with information about socket activity to
463  * monitor.
464  */
465 static int events_socket(struct Curl_easy *easy,      /* easy handle */
466                          curl_socket_t s, /* socket */
467                          int what,        /* see above */
468                          void *userp,     /* private callback
469                                              pointer */
470                          void *socketp)   /* private socket
471                                              pointer */
472 {
473   struct events *ev = userp;
474   struct socketmonitor *m;
475   struct socketmonitor *prev = NULL;
476
477 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
478   (void) easy;
479 #endif
480   (void)socketp;
481
482   m = ev->list;
483   while(m) {
484     if(m->socket.fd == s) {
485
486       if(what == CURL_POLL_REMOVE) {
487         struct socketmonitor *nxt = m->next;
488         /* remove this node from the list of monitored sockets */
489         if(prev)
490           prev->next = nxt;
491         else
492           ev->list = nxt;
493         free(m);
494         m = nxt;
495         infof(easy, "socket cb: socket %d REMOVED\n", s);
496       }
497       else {
498         /* The socket 's' is already being monitored, update the activity
499            mask. Convert from libcurl bitmask to the poll one. */
500         m->socket.events = socketcb2poll(what);
501         infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
502               what&CURL_POLL_IN?"IN":"",
503               what&CURL_POLL_OUT?"OUT":"");
504       }
505       break;
506     }
507     prev = m;
508     m = m->next; /* move to next node */
509   }
510   if(!m) {
511     if(what == CURL_POLL_REMOVE) {
512       /* this happens a bit too often, libcurl fix perhaps? */
513       /* fprintf(stderr,
514          "%s: socket %d asked to be REMOVED but not present!\n",
515                  __func__, s); */
516     }
517     else {
518       m = malloc(sizeof(struct socketmonitor));
519       if(m) {
520         m->next = ev->list;
521         m->socket.fd = s;
522         m->socket.events = socketcb2poll(what);
523         m->socket.revents = 0;
524         ev->list = m;
525         infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
526               what&CURL_POLL_IN?"IN":"",
527               what&CURL_POLL_OUT?"OUT":"");
528       }
529       else
530         return CURLE_OUT_OF_MEMORY;
531     }
532   }
533
534   return 0;
535 }
536
537
538 /*
539  * events_setup()
540  *
541  * Do the multi handle setups that only event-based transfers need.
542  */
543 static void events_setup(struct Curl_multi *multi, struct events *ev)
544 {
545   /* timer callback */
546   curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
547   curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
548
549   /* socket callback */
550   curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
551   curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
552 }
553
554
555 /* wait_or_timeout()
556  *
557  * waits for activity on any of the given sockets, or the timeout to trigger.
558  */
559
560 static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
561 {
562   bool done = FALSE;
563   CURLMcode mcode = CURLM_OK;
564   CURLcode result = CURLE_OK;
565
566   while(!done) {
567     CURLMsg *msg;
568     struct socketmonitor *m;
569     struct pollfd *f;
570     struct pollfd fds[4];
571     int numfds = 0;
572     int pollrc;
573     int i;
574     struct curltime before;
575     struct curltime after;
576
577     /* populate the fds[] array */
578     for(m = ev->list, f = &fds[0]; m; m = m->next) {
579       f->fd = m->socket.fd;
580       f->events = m->socket.events;
581       f->revents = 0;
582       /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
583       f++;
584       numfds++;
585     }
586
587     /* get the time stamp to use to figure out how long poll takes */
588     before = Curl_now();
589
590     /* wait for activity or timeout */
591     pollrc = Curl_poll(fds, numfds, (int)ev->ms);
592
593     after = Curl_now();
594
595     ev->msbump = FALSE; /* reset here */
596
597     if(0 == pollrc) {
598       /* timeout! */
599       ev->ms = 0;
600       /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */
601       mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
602                                        &ev->running_handles);
603     }
604     else if(pollrc > 0) {
605       /* loop over the monitored sockets to see which ones had activity */
606       for(i = 0; i< numfds; i++) {
607         if(fds[i].revents) {
608           /* socket activity, tell libcurl */
609           int act = poll2cselect(fds[i].revents); /* convert */
610           infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n",
611                 fds[i].fd);
612           mcode = curl_multi_socket_action(multi, fds[i].fd, act,
613                                            &ev->running_handles);
614         }
615       }
616
617       if(!ev->msbump) {
618         /* If nothing updated the timeout, we decrease it by the spent time.
619          * If it was updated, it has the new timeout time stored already.
620          */
621         timediff_t timediff = Curl_timediff(after, before);
622         if(timediff > 0) {
623           if(timediff > ev->ms)
624             ev->ms = 0;
625           else
626             ev->ms -= (long)timediff;
627         }
628       }
629     }
630     else
631       return CURLE_RECV_ERROR;
632
633     if(mcode)
634       return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
635
636     /* we don't really care about the "msgs_in_queue" value returned in the
637        second argument */
638     msg = curl_multi_info_read(multi, &pollrc);
639     if(msg) {
640       result = msg->data.result;
641       done = TRUE;
642     }
643   }
644
645   return result;
646 }
647
648
649 /* easy_events()
650  *
651  * Runs a transfer in a blocking manner using the events-based API
652  */
653 static CURLcode easy_events(struct Curl_multi *multi)
654 {
655   /* this struct is made static to allow it to be used after this function
656      returns and curl_multi_remove_handle() is called */
657   static struct events evs = {2, FALSE, 0, NULL, 0};
658
659   /* if running event-based, do some further multi inits */
660   events_setup(multi, &evs);
661
662   return wait_or_timeout(multi, &evs);
663 }
664 #else /* CURLDEBUG */
665 /* when not built with debug, this function doesn't exist */
666 #define easy_events(x) CURLE_NOT_BUILT_IN
667 #endif
668
669 static CURLcode easy_transfer(struct Curl_multi *multi)
670 {
671   bool done = FALSE;
672   CURLMcode mcode = CURLM_OK;
673   CURLcode result = CURLE_OK;
674   struct curltime before;
675   int without_fds = 0;  /* count number of consecutive returns from
676                            curl_multi_wait() without any filedescriptors */
677
678   while(!done && !mcode) {
679     int still_running = 0;
680     int rc;
681
682     before = Curl_now();
683     mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
684
685     if(!mcode) {
686       if(!rc) {
687         struct curltime after = Curl_now();
688
689         /* If it returns without any filedescriptor instantly, we need to
690            avoid busy-looping during periods where it has nothing particular
691            to wait for */
692         if(Curl_timediff(after, before) <= 10) {
693           without_fds++;
694           if(without_fds > 2) {
695             int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
696             Curl_wait_ms(sleep_ms);
697           }
698         }
699         else
700           /* it wasn't "instant", restart counter */
701           without_fds = 0;
702       }
703       else
704         /* got file descriptor, restart counter */
705         without_fds = 0;
706
707       mcode = curl_multi_perform(multi, &still_running);
708     }
709
710     /* only read 'still_running' if curl_multi_perform() return OK */
711     if(!mcode && !still_running) {
712       CURLMsg *msg = curl_multi_info_read(multi, &rc);
713       if(msg) {
714         result = msg->data.result;
715         done = TRUE;
716       }
717     }
718   }
719
720   /* Make sure to return some kind of error if there was a multi problem */
721   if(mcode) {
722     result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
723               /* The other multi errors should never happen, so return
724                  something suitably generic */
725               CURLE_BAD_FUNCTION_ARGUMENT;
726   }
727
728   return result;
729 }
730
731
732 /*
733  * easy_perform() is the external interface that performs a blocking
734  * transfer as previously setup.
735  *
736  * CONCEPT: This function creates a multi handle, adds the easy handle to it,
737  * runs curl_multi_perform() until the transfer is done, then detaches the
738  * easy handle, destroys the multi handle and returns the easy handle's return
739  * code.
740  *
741  * REALITY: it can't just create and destroy the multi handle that easily. It
742  * needs to keep it around since if this easy handle is used again by this
743  * function, the same multi handle must be re-used so that the same pools and
744  * caches can be used.
745  *
746  * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
747  * instead of curl_multi_perform() and use curl_multi_socket_action().
748  */
749 static CURLcode easy_perform(struct Curl_easy *data, bool events)
750 {
751   struct Curl_multi *multi;
752   CURLMcode mcode;
753   CURLcode result = CURLE_OK;
754   SIGPIPE_VARIABLE(pipe_st);
755
756   if(!data)
757     return CURLE_BAD_FUNCTION_ARGUMENT;
758
759   if(data->multi) {
760     failf(data, "easy handle already used in multi handle");
761     return CURLE_FAILED_INIT;
762   }
763
764   if(data->multi_easy)
765     multi = data->multi_easy;
766   else {
767     /* this multi handle will only ever have a single easy handled attached
768        to it, so make it use minimal hashes */
769     multi = Curl_multi_handle(1, 3);
770     if(!multi)
771       return CURLE_OUT_OF_MEMORY;
772     data->multi_easy = multi;
773   }
774
775   if(multi->in_callback)
776     return CURLE_RECURSIVE_API_CALL;
777
778   /* Copy the MAXCONNECTS option to the multi handle */
779   curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
780
781   mcode = curl_multi_add_handle(multi, data);
782   if(mcode) {
783     curl_multi_cleanup(multi);
784     if(mcode == CURLM_OUT_OF_MEMORY)
785       return CURLE_OUT_OF_MEMORY;
786     return CURLE_FAILED_INIT;
787   }
788
789   sigpipe_ignore(data, &pipe_st);
790
791   /* assign this after curl_multi_add_handle() since that function checks for
792      it and rejects this handle otherwise */
793   data->multi = multi;
794
795   /* run the transfer */
796   result = events ? easy_events(multi) : easy_transfer(multi);
797
798   /* ignoring the return code isn't nice, but atm we can't really handle
799      a failure here, room for future improvement! */
800   (void)curl_multi_remove_handle(multi, data);
801
802   sigpipe_restore(&pipe_st);
803
804   /* The multi handle is kept alive, owned by the easy handle */
805   return result;
806 }
807
808
809 /*
810  * curl_easy_perform() is the external interface that performs a blocking
811  * transfer as previously setup.
812  */
813 CURLcode curl_easy_perform(struct Curl_easy *data)
814 {
815   return easy_perform(data, FALSE);
816 }
817
818 #ifdef CURLDEBUG
819 /*
820  * curl_easy_perform_ev() is the external interface that performs a blocking
821  * transfer using the event-based API internally.
822  */
823 CURLcode curl_easy_perform_ev(struct Curl_easy *data)
824 {
825   return easy_perform(data, TRUE);
826 }
827
828 #endif
829
830 /*
831  * curl_easy_cleanup() is the external interface to cleaning/freeing the given
832  * easy handle.
833  */
834 void curl_easy_cleanup(struct Curl_easy *data)
835 {
836   SIGPIPE_VARIABLE(pipe_st);
837
838   if(!data)
839     return;
840
841   sigpipe_ignore(data, &pipe_st);
842   Curl_close(data);
843   sigpipe_restore(&pipe_st);
844 }
845
846 /*
847  * curl_easy_getinfo() is an external interface that allows an app to retrieve
848  * information from a performed transfer and similar.
849  */
850 #undef curl_easy_getinfo
851 CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
852 {
853   va_list arg;
854   void *paramp;
855   CURLcode result;
856
857   va_start(arg, info);
858   paramp = va_arg(arg, void *);
859
860   result = Curl_getinfo(data, info, paramp);
861
862   va_end(arg);
863   return result;
864 }
865
866 static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
867 {
868   CURLcode result = CURLE_OK;
869   enum dupstring i;
870
871   /* Copy src->set into dst->set first, then deal with the strings
872      afterwards */
873   dst->set = src->set;
874   Curl_mime_initpart(&dst->set.mimepost, dst);
875
876   /* clear all string pointers first */
877   memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
878
879   /* duplicate all strings */
880   for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
881     result = Curl_setstropt(&dst->set.str[i], src->set.str[i]);
882     if(result)
883       return result;
884   }
885
886   /* duplicate memory areas pointed to */
887   i = STRING_COPYPOSTFIELDS;
888   if(src->set.postfieldsize && src->set.str[i]) {
889     /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
890     dst->set.str[i] = Curl_memdup(src->set.str[i],
891                                   curlx_sotouz(src->set.postfieldsize));
892     if(!dst->set.str[i])
893       return CURLE_OUT_OF_MEMORY;
894     /* point to the new copy */
895     dst->set.postfields = dst->set.str[i];
896   }
897
898   /* Duplicate mime data. */
899   result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost);
900
901   return result;
902 }
903
904 /*
905  * curl_easy_duphandle() is an external interface to allow duplication of a
906  * given input easy handle. The returned handle will be a new working handle
907  * with all options set exactly as the input source handle.
908  */
909 struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
910 {
911   struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
912   if(NULL == outcurl)
913     goto fail;
914
915   /*
916    * We setup a few buffers we need. We should probably make them
917    * get setup on-demand in the code, as that would probably decrease
918    * the likeliness of us forgetting to init a buffer here in the future.
919    */
920   outcurl->set.buffer_size = data->set.buffer_size;
921   outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
922   if(!outcurl->state.buffer)
923     goto fail;
924
925   outcurl->state.headerbuff = malloc(HEADERSIZE);
926   if(!outcurl->state.headerbuff)
927     goto fail;
928   outcurl->state.headersize = HEADERSIZE;
929
930   /* copy all userdefined values */
931   if(dupset(outcurl, data))
932     goto fail;
933
934   /* the connection cache is setup on demand */
935   outcurl->state.conn_cache = NULL;
936
937   outcurl->state.lastconnect = NULL;
938
939   outcurl->progress.flags    = data->progress.flags;
940   outcurl->progress.callback = data->progress.callback;
941
942   if(data->cookies) {
943     /* If cookies are enabled in the parent handle, we enable them
944        in the clone as well! */
945     outcurl->cookies = Curl_cookie_init(data,
946                                         data->cookies->filename,
947                                         outcurl->cookies,
948                                         data->set.cookiesession);
949     if(!outcurl->cookies)
950       goto fail;
951   }
952
953   /* duplicate all values in 'change' */
954   if(data->change.cookielist) {
955     outcurl->change.cookielist =
956       Curl_slist_duplicate(data->change.cookielist);
957     if(!outcurl->change.cookielist)
958       goto fail;
959   }
960
961   if(data->change.url) {
962     outcurl->change.url = strdup(data->change.url);
963     if(!outcurl->change.url)
964       goto fail;
965     outcurl->change.url_alloc = TRUE;
966   }
967
968   if(data->change.referer) {
969     outcurl->change.referer = strdup(data->change.referer);
970     if(!outcurl->change.referer)
971       goto fail;
972     outcurl->change.referer_alloc = TRUE;
973   }
974
975   /* Clone the resolver handle, if present, for the new handle */
976   if(Curl_resolver_duphandle(&outcurl->state.resolver,
977                              data->state.resolver))
978     goto fail;
979
980   Curl_convert_setup(outcurl);
981
982   Curl_initinfo(outcurl);
983
984   outcurl->magic = CURLEASY_MAGIC_NUMBER;
985
986   /* we reach this point and thus we are OK */
987
988   return outcurl;
989
990   fail:
991
992   if(outcurl) {
993     curl_slist_free_all(outcurl->change.cookielist);
994     outcurl->change.cookielist = NULL;
995     Curl_safefree(outcurl->state.buffer);
996     Curl_safefree(outcurl->state.headerbuff);
997     Curl_safefree(outcurl->change.url);
998     Curl_safefree(outcurl->change.referer);
999     Curl_freeset(outcurl);
1000     free(outcurl);
1001   }
1002
1003   return NULL;
1004 }
1005
1006 /*
1007  * curl_easy_reset() is an external interface that allows an app to re-
1008  * initialize a session handle to the default values.
1009  */
1010 void curl_easy_reset(struct Curl_easy *data)
1011 {
1012   Curl_safefree(data->state.pathbuffer);
1013
1014   data->state.path = NULL;
1015
1016   Curl_free_request_state(data);
1017
1018   /* zero out UserDefined data: */
1019   Curl_freeset(data);
1020   memset(&data->set, 0, sizeof(struct UserDefined));
1021   (void)Curl_init_userdefined(data);
1022
1023   /* zero out Progress data: */
1024   memset(&data->progress, 0, sizeof(struct Progress));
1025
1026   /* zero out PureInfo data: */
1027   Curl_initinfo(data);
1028
1029   data->progress.flags |= PGRS_HIDE;
1030   data->state.current_speed = -1; /* init to negative == impossible */
1031
1032   /* zero out authentication data: */
1033   memset(&data->state.authhost, 0, sizeof(struct auth));
1034   memset(&data->state.authproxy, 0, sizeof(struct auth));
1035   Curl_digest_cleanup(data);
1036 }
1037
1038 /*
1039  * curl_easy_pause() allows an application to pause or unpause a specific
1040  * transfer and direction. This function sets the full new state for the
1041  * current connection this easy handle operates on.
1042  *
1043  * NOTE: if you have the receiving paused and you call this function to remove
1044  * the pausing, you may get your write callback called at this point.
1045  *
1046  * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
1047  *
1048  * NOTE: This is one of few API functions that are allowed to be called from
1049  * within a callback.
1050  */
1051 CURLcode curl_easy_pause(struct Curl_easy *data, int action)
1052 {
1053   struct SingleRequest *k = &data->req;
1054   CURLcode result = CURLE_OK;
1055
1056   /* first switch off both pause bits */
1057   int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
1058
1059   /* set the new desired pause bits */
1060   newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
1061     ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
1062
1063   /* put it back in the keepon */
1064   k->keepon = newstate;
1065
1066   if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) {
1067     /* there are buffers for sending that can be delivered as the receive
1068        pausing is lifted! */
1069     unsigned int i;
1070     unsigned int count = data->state.tempcount;
1071     struct tempbuf writebuf[3]; /* there can only be three */
1072     struct connectdata *conn = data->easy_conn;
1073     struct Curl_easy *saved_data = NULL;
1074
1075     /* copy the structs to allow for immediate re-pausing */
1076     for(i = 0; i < data->state.tempcount; i++) {
1077       writebuf[i] = data->state.tempwrite[i];
1078       data->state.tempwrite[i].buf = NULL;
1079     }
1080     data->state.tempcount = 0;
1081
1082     /* set the connection's current owner */
1083     if(conn->data != data) {
1084       saved_data = conn->data;
1085       conn->data = data;
1086     }
1087
1088     for(i = 0; i < count; i++) {
1089       /* even if one function returns error, this loops through and frees all
1090          buffers */
1091       if(!result)
1092         result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf,
1093                                    writebuf[i].len);
1094       free(writebuf[i].buf);
1095     }
1096
1097     /* recover previous owner of the connection */
1098     if(saved_data)
1099       conn->data = saved_data;
1100
1101     if(result)
1102       return result;
1103   }
1104
1105   /* if there's no error and we're not pausing both directions, we want
1106      to have this handle checked soon */
1107   if(!result &&
1108      ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
1109       (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
1110     Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
1111
1112   return result;
1113 }
1114
1115
1116 static CURLcode easy_connection(struct Curl_easy *data,
1117                                 curl_socket_t *sfd,
1118                                 struct connectdata **connp)
1119 {
1120   if(data == NULL)
1121     return CURLE_BAD_FUNCTION_ARGUMENT;
1122
1123   /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
1124   if(!data->set.connect_only) {
1125     failf(data, "CONNECT_ONLY is required!");
1126     return CURLE_UNSUPPORTED_PROTOCOL;
1127   }
1128
1129   *sfd = Curl_getconnectinfo(data, connp);
1130
1131   if(*sfd == CURL_SOCKET_BAD) {
1132     failf(data, "Failed to get recent socket");
1133     return CURLE_UNSUPPORTED_PROTOCOL;
1134   }
1135
1136   return CURLE_OK;
1137 }
1138
1139 /*
1140  * Receives data from the connected socket. Use after successful
1141  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1142  * Returns CURLE_OK on success, error code on error.
1143  */
1144 CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
1145                         size_t *n)
1146 {
1147   curl_socket_t sfd;
1148   CURLcode result;
1149   ssize_t n1;
1150   struct connectdata *c;
1151
1152   if(Curl_is_in_callback(data))
1153     return CURLE_RECURSIVE_API_CALL;
1154
1155   result = easy_connection(data, &sfd, &c);
1156   if(result)
1157     return result;
1158
1159   *n = 0;
1160   result = Curl_read(c, sfd, buffer, buflen, &n1);
1161
1162   if(result)
1163     return result;
1164
1165   *n = (size_t)n1;
1166
1167   return CURLE_OK;
1168 }
1169
1170 /*
1171  * Sends data over the connected socket. Use after successful
1172  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1173  */
1174 CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
1175                         size_t buflen, size_t *n)
1176 {
1177   curl_socket_t sfd;
1178   CURLcode result;
1179   ssize_t n1;
1180   struct connectdata *c = NULL;
1181
1182   if(Curl_is_in_callback(data))
1183     return CURLE_RECURSIVE_API_CALL;
1184
1185   result = easy_connection(data, &sfd, &c);
1186   if(result)
1187     return result;
1188
1189   *n = 0;
1190   result = Curl_write(c, sfd, buffer, buflen, &n1);
1191
1192   if(n1 == -1)
1193     return CURLE_SEND_ERROR;
1194
1195   /* detect EAGAIN */
1196   if(!result && !n1)
1197     return CURLE_AGAIN;
1198
1199   *n = (size_t)n1;
1200
1201   return result;
1202 }