1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
25 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h>
31 #ifdef HAVE_ARPA_INET_H
32 #include <arpa/inet.h>
37 #ifdef HAVE_SYS_IOCTL_H
38 #include <sys/ioctl.h>
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
47 #include <curl/curl.h>
55 #include "curl_memory.h"
59 #include "sendf.h" /* for failf function prototype */
60 #include "curl_ntlm.h"
61 #include "connect.h" /* for Curl_getconnectinfo */
64 #include "curl_rand.h"
65 #include "non-ascii.h"
67 #include "conncache.h"
69 #define _MPRINTF_REPLACE /* use our functions only */
70 #include <curl/mprintf.h>
72 /* The last #include file should be: */
75 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
77 static void win32_cleanup(void)
82 #ifdef USE_WINDOWS_SSPI
83 Curl_sspi_global_cleanup();
87 /* win32_init() performs win32 socket initialization to properly setup the
88 stack to allow networking */
89 static CURLcode win32_init(void)
92 WORD wVersionRequested;
96 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
97 Error IPV6_requires_winsock2
100 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
102 res = WSAStartup(wVersionRequested, &wsaData);
105 /* Tell the user that we couldn't find a useable */
107 return CURLE_FAILED_INIT;
109 /* Confirm that the Windows Sockets DLL supports what we need.*/
110 /* Note that if the DLL supports versions greater */
111 /* than wVersionRequested, it will still return */
112 /* wVersionRequested in wVersion. wHighVersion contains the */
113 /* highest supported version. */
115 if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
116 HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
117 /* Tell the user that we couldn't find a useable */
121 return CURLE_FAILED_INIT;
123 /* The Windows Sockets DLL is acceptable. Proceed. */
124 #elif defined(USE_LWIPSOCK)
128 #ifdef USE_WINDOWS_SSPI
130 CURLcode err = Curl_sspi_global_init();
141 * Initialise use of IDNA library.
142 * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
143 * idna_to_ascii_lz().
145 static void idna_init (void)
151 if(!getenv("CHARSET") && cp > 0) {
152 snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
159 #endif /* USE_LIBIDN */
161 /* true globals -- for curl_global_init() and curl_global_cleanup() */
162 static unsigned int initialized;
163 static long init_flags;
166 * strdup (and other memory functions) is redefined in complicated
167 * ways, but at this point it must be defined as the system-supplied strdup
168 * so the callback pointer is initialized correctly.
170 #if defined(_WIN32_WCE)
171 #define system_strdup _strdup
172 #elif !defined(HAVE_STRDUP)
173 #define system_strdup curlx_strdup
175 #define system_strdup strdup
178 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
179 # pragma warning(disable:4232) /* MSVC extension, dllimport identity */
182 #ifndef __SYMBIAN32__
184 * If a memory-using function (like curl_getenv) is used before
185 * curl_global_init() is called, we need to have these pointers set already.
187 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
188 curl_free_callback Curl_cfree = (curl_free_callback)free;
189 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
190 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
191 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
194 * Symbian OS doesn't support initialization to code in writeable static data.
195 * Initialization will occur in the curl_global_init() call.
197 curl_malloc_callback Curl_cmalloc;
198 curl_free_callback Curl_cfree;
199 curl_realloc_callback Curl_crealloc;
200 curl_strdup_callback Curl_cstrdup;
201 curl_calloc_callback Curl_ccalloc;
204 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
205 # pragma warning(default:4232) /* MSVC extension, dllimport identity */
209 * curl_global_init() globally initializes cURL given a bitwise set of the
210 * different features of what to initialize.
212 CURLcode curl_global_init(long flags)
217 /* Setup the default memory functions here (again) */
218 Curl_cmalloc = (curl_malloc_callback)malloc;
219 Curl_cfree = (curl_free_callback)free;
220 Curl_crealloc = (curl_realloc_callback)realloc;
221 Curl_cstrdup = (curl_strdup_callback)system_strdup;
222 Curl_ccalloc = (curl_calloc_callback)calloc;
224 if(flags & CURL_GLOBAL_SSL)
225 if(!Curl_ssl_init()) {
226 DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
227 return CURLE_FAILED_INIT;
230 if(flags & CURL_GLOBAL_WIN32)
231 if(win32_init() != CURLE_OK) {
232 DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
233 return CURLE_FAILED_INIT;
237 if(!Curl_amiga_init()) {
238 DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
239 return CURLE_FAILED_INIT;
245 DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
253 if(Curl_resolver_global_init() != CURLE_OK) {
254 DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
255 return CURLE_FAILED_INIT;
258 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
259 if(libssh2_init(0)) {
260 DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
261 return CURLE_FAILED_INIT;
267 /* Preset pseudo-random number sequence. */
275 * curl_global_init_mem() globally initializes cURL and also registers the
276 * user provided callback routines.
278 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
279 curl_free_callback f, curl_realloc_callback r,
280 curl_strdup_callback s, curl_calloc_callback c)
282 CURLcode code = CURLE_OK;
284 /* Invalid input, return immediately */
285 if(!m || !f || !r || !s || !c)
286 return CURLE_FAILED_INIT;
288 /* Already initialized, don't do it again */
292 /* Call the actual init function first */
293 code = curl_global_init(flags);
294 if(code == CURLE_OK) {
306 * curl_global_cleanup() globally cleanups cURL, uses the value of
307 * "init_flags" to determine what needs to be cleaned up and what doesn't.
309 void curl_global_cleanup(void)
317 Curl_global_host_cache_dtor();
319 if(init_flags & CURL_GLOBAL_SSL)
322 Curl_resolver_global_cleanup();
324 if(init_flags & CURL_GLOBAL_WIN32)
327 Curl_amiga_cleanup();
329 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
330 (void)libssh2_exit();
337 * curl_easy_init() is the external interface to alloc, setup and init an
338 * easy handle that is returned. If anything goes wrong, NULL is returned.
340 CURL *curl_easy_init(void)
343 struct SessionHandle *data;
345 /* Make sure we inited the global SSL stuff */
347 res = curl_global_init(CURL_GLOBAL_DEFAULT);
349 /* something in the global init failed, return nothing */
350 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
355 /* We use curl_open() with undefined URL so far */
356 res = Curl_open(&data);
357 if(res != CURLE_OK) {
358 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
366 * curl_easy_setopt() is the external interface for setting options on an
370 #undef curl_easy_setopt
371 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
374 struct SessionHandle *data = curl;
378 return CURLE_BAD_FUNCTION_ARGUMENT;
382 ret = Curl_setopt(data, tag, arg);
388 #ifdef CURL_MULTIEASY
389 /***************************************************************************
390 * This function is still only for testing purposes. It makes a great way
391 * to run the full test suite on the multi interface instead of the easy one.
392 ***************************************************************************
394 * The *new* curl_easy_perform() is the external interface that performs a
395 * transfer previously setup.
397 * Wrapper-function that: creates a multi handle, adds the easy handle to it,
398 * runs curl_multi_perform() until the transfer is done, then detaches the
399 * easy handle, destroys the multi handle and returns the easy handle's return
400 * code. This will make everything internally use and assume multi interface.
402 CURLcode curl_easy_perform(CURL *easy)
406 CURLcode code = CURLE_OK;
408 struct timeval timeout;
417 return CURLE_BAD_FUNCTION_ARGUMENT;
419 multi = curl_multi_init();
421 return CURLE_OUT_OF_MEMORY;
423 mcode = curl_multi_add_handle(multi, easy);
425 curl_multi_cleanup(multi);
426 if(mcode == CURLM_OUT_OF_MEMORY)
427 return CURLE_OUT_OF_MEMORY;
429 return CURLE_FAILED_INIT;
432 /* we start some action by calling perform right away */
435 while(CURLM_CALL_MULTI_PERFORM ==
436 curl_multi_perform(multi, &still_running));
445 /* timeout once per second */
449 /* Old deprecated style: get file descriptors from the transfers */
450 curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
451 rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
453 /* The way is to extract the sockets and wait for them without using
454 select. This whole alternative version should probably rather use the
455 curl_multi_socket() approach. */
461 /* timeout or data to send/receive => loop! */
462 } while(still_running);
464 msg = curl_multi_info_read(multi, &rc);
466 code = msg->data.result;
468 mcode = curl_multi_remove_handle(multi, easy);
469 /* what to do if it fails? */
471 mcode = curl_multi_cleanup(multi);
472 /* what to do if it fails? */
478 * curl_easy_perform() is the external interface that performs a transfer
481 CURLcode curl_easy_perform(CURL *curl)
483 struct SessionHandle *data = (struct SessionHandle *)curl;
486 return CURLE_BAD_FUNCTION_ARGUMENT;
488 if(! (data->share && data->share->hostcache)) {
489 /* this handle is not using a shared dns cache */
491 if(data->set.global_dns_cache &&
492 (data->dns.hostcachetype != HCACHE_GLOBAL)) {
493 /* global dns cache was requested but still isn't */
494 struct curl_hash *ptr;
496 if(data->dns.hostcachetype == HCACHE_PRIVATE) {
497 /* if the current cache is private, kill it first */
498 Curl_hash_destroy(data->dns.hostcache);
499 data->dns.hostcachetype = HCACHE_NONE;
500 data->dns.hostcache = NULL;
503 ptr = Curl_global_host_cache_init();
505 /* only do this if the global cache init works */
506 data->dns.hostcache = ptr;
507 data->dns.hostcachetype = HCACHE_GLOBAL;
511 if(!data->dns.hostcache) {
512 data->dns.hostcachetype = HCACHE_PRIVATE;
513 data->dns.hostcache = Curl_mk_dnscache();
515 if(!data->dns.hostcache)
516 /* While we possibly could survive and do good without a host cache,
517 the fact that creating it failed indicates that things are truly
518 screwed up and we should bail out! */
519 return CURLE_OUT_OF_MEMORY;
524 if(!data->state.conn_cache) {
525 /* Oops, no connection cache, create one */
526 data->state.conn_cache = Curl_conncache_init(CONNCACHE_PRIVATE);
527 if(!data->state.conn_cache)
528 return CURLE_OUT_OF_MEMORY;
531 return Curl_perform(data);
536 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
539 void curl_easy_cleanup(CURL *curl)
541 struct SessionHandle *data = (struct SessionHandle *)curl;
550 * Store a pointed to the multi handle within the easy handle's data struct.
552 void Curl_easy_addmulti(struct SessionHandle *data,
557 /* the association is cleared, mark the easy handle as not used by an
559 data->state.used_interface = Curl_if_none;
562 void Curl_easy_initHandleData(struct SessionHandle *data)
564 memset(&data->req, 0, sizeof(struct SingleRequest));
566 data->req.maxdownload = -1;
570 * curl_easy_getinfo() is an external interface that allows an app to retrieve
571 * information from a performed transfer and similar.
573 #undef curl_easy_getinfo
574 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
578 struct SessionHandle *data = (struct SessionHandle *)curl;
581 paramp = va_arg(arg, void *);
583 return Curl_getinfo(data, info, paramp);
587 * curl_easy_duphandle() is an external interface to allow duplication of a
588 * given input easy handle. The returned handle will be a new working handle
589 * with all options set exactly as the input source handle.
591 CURL *curl_easy_duphandle(CURL *incurl)
593 struct SessionHandle *data=(struct SessionHandle *)incurl;
595 struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
600 * We setup a few buffers we need. We should probably make them
601 * get setup on-demand in the code, as that would probably decrease
602 * the likeliness of us forgetting to init a buffer here in the future.
604 outcurl->state.headerbuff = malloc(HEADERSIZE);
605 if(!outcurl->state.headerbuff)
607 outcurl->state.headersize = HEADERSIZE;
609 /* copy all userdefined values */
610 if(Curl_dupset(outcurl, data) != CURLE_OK)
613 /* the connection cache is setup on demand */
614 outcurl->state.conn_cache = NULL;
616 outcurl->state.lastconnect = NULL;
618 outcurl->progress.flags = data->progress.flags;
619 outcurl->progress.callback = data->progress.callback;
622 /* If cookies are enabled in the parent handle, we enable them
623 in the clone as well! */
624 outcurl->cookies = Curl_cookie_init(data,
625 data->cookies->filename,
627 data->set.cookiesession);
628 if(!outcurl->cookies)
632 /* duplicate all values in 'change' */
633 if(data->change.cookielist) {
634 outcurl->change.cookielist =
635 Curl_slist_duplicate(data->change.cookielist);
636 if(!outcurl->change.cookielist)
640 if(data->change.url) {
641 outcurl->change.url = strdup(data->change.url);
642 if(!outcurl->change.url)
644 outcurl->change.url_alloc = TRUE;
647 if(data->change.referer) {
648 outcurl->change.referer = strdup(data->change.referer);
649 if(!outcurl->change.referer)
651 outcurl->change.referer_alloc = TRUE;
654 /* Clone the resolver handle, if present, for the new handle */
655 if(Curl_resolver_duphandle(&outcurl->state.resolver,
656 data->state.resolver) != CURLE_OK)
659 Curl_convert_setup(outcurl);
661 Curl_easy_initHandleData(outcurl);
663 outcurl->magic = CURLEASY_MAGIC_NUMBER;
665 /* we reach this point and thus we are OK */
672 curl_slist_free_all(outcurl->change.cookielist);
673 outcurl->change.cookielist = NULL;
674 Curl_safefree(outcurl->state.headerbuff);
675 Curl_safefree(outcurl->change.url);
676 Curl_safefree(outcurl->change.referer);
677 Curl_freeset(outcurl);
685 * curl_easy_reset() is an external interface that allows an app to re-
686 * initialize a session handle to the default values.
688 void curl_easy_reset(CURL *curl)
690 struct SessionHandle *data = (struct SessionHandle *)curl;
692 Curl_safefree(data->state.pathbuffer);
694 data->state.path = NULL;
696 Curl_safefree(data->state.proto.generic);
698 /* zero out UserDefined data: */
700 memset(&data->set, 0, sizeof(struct UserDefined));
701 (void)Curl_init_userdefined(&data->set);
703 /* zero out Progress data: */
704 memset(&data->progress, 0, sizeof(struct Progress));
706 /* init Handle data */
707 Curl_easy_initHandleData(data);
709 data->progress.flags |= PGRS_HIDE;
710 data->state.current_speed = -1; /* init to negative == impossible */
714 * curl_easy_pause() allows an application to pause or unpause a specific
715 * transfer and direction. This function sets the full new state for the
716 * current connection this easy handle operates on.
718 * NOTE: if you have the receiving paused and you call this function to remove
719 * the pausing, you may get your write callback called at this point.
721 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
723 CURLcode curl_easy_pause(CURL *curl, int action)
725 struct SessionHandle *data = (struct SessionHandle *)curl;
726 struct SingleRequest *k = &data->req;
727 CURLcode result = CURLE_OK;
729 /* first switch off both pause bits */
730 int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
732 /* set the new desired pause bits */
733 newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
734 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
736 /* put it back in the keepon */
737 k->keepon = newstate;
739 if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
740 /* we have a buffer for sending that we now seem to be able to deliver
741 since the receive pausing is lifted! */
743 /* get the pointer, type and length in local copies since the function may
744 return PAUSE again and then we'll get a new copy allocted and stored in
745 the tempwrite variables */
746 char *tempwrite = data->state.tempwrite;
747 char *freewrite = tempwrite; /* store this pointer to free it later */
748 size_t tempsize = data->state.tempwritesize;
749 int temptype = data->state.tempwritetype;
752 /* clear tempwrite here just to make sure it gets cleared if there's no
753 further use of it, and make sure we don't clear it after the function
754 invoke as it may have been set to a new value by then */
755 data->state.tempwrite = NULL;
757 /* since the write callback API is define to never exceed
758 CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
759 have more data than that in our buffer here, we must loop sending the
760 data in multiple calls until there's no data left or we get another
763 A tricky part is that the function we call will "buffer" the data
764 itself when it pauses on a particular buffer, so we may need to do some
765 extra trickery if we get a pause return here.
768 chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
770 result = Curl_client_write(data->state.current_conn,
771 temptype, tempwrite, chunklen);
773 /* failures abort the loop at once */
776 if(data->state.tempwrite && (tempsize - chunklen)) {
777 /* Ouch, the reading is again paused and the block we send is now
778 "cached". If this is the final chunk we can leave it like this, but
779 if we have more chunks that are cached after this, we need to free
780 the newly cached one and put back a version that is truly the entire
781 contents that is saved for later
785 /* note that tempsize is still the size as before the callback was
786 used, and thus the whole piece of data to keep */
787 newptr = realloc(data->state.tempwrite, tempsize);
790 free(data->state.tempwrite); /* free old area */
791 data->state.tempwrite = NULL;
792 result = CURLE_OUT_OF_MEMORY;
793 /* tempwrite will be freed further down */
796 data->state.tempwrite = newptr; /* store new pointer */
797 memcpy(newptr, tempwrite, tempsize);
798 data->state.tempwritesize = tempsize; /* store new size */
799 /* tempwrite will be freed further down */
800 break; /* go back to pausing until further notice */
803 tempsize -= chunklen; /* left after the call above */
804 tempwrite += chunklen; /* advance the pointer */
807 } while((result == CURLE_OK) && tempsize);
809 free(freewrite); /* this is unconditionally no longer used */
816 static CURLcode easy_connection(struct SessionHandle *data,
818 struct connectdata **connp)
821 return CURLE_BAD_FUNCTION_ARGUMENT;
823 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
824 if(!data->set.connect_only) {
825 failf(data, "CONNECT_ONLY is required!");
826 return CURLE_UNSUPPORTED_PROTOCOL;
829 *sfd = Curl_getconnectinfo(data, connp);
831 if(*sfd == CURL_SOCKET_BAD) {
832 failf(data, "Failed to get recent socket");
833 return CURLE_UNSUPPORTED_PROTOCOL;
840 * Receives data from the connected socket. Use after successful
841 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
842 * Returns CURLE_OK on success, error code on error.
844 CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
849 struct connectdata *c;
850 struct SessionHandle *data = (struct SessionHandle *)curl;
852 ret = easy_connection(data, &sfd, &c);
857 ret = Curl_read(c, sfd, buffer, buflen, &n1);
868 * Sends data over the connected socket. Use after successful
869 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
871 CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
877 struct connectdata *c = NULL;
878 struct SessionHandle *data = (struct SessionHandle *)curl;
880 ret = easy_connection(data, &sfd, &c);
885 ret = Curl_write(c, sfd, buffer, buflen, &n1);
888 return CURLE_SEND_ERROR;
891 if((CURLE_OK == ret) && (0 == n1))