1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, 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 /* -- WIN32 approved -- */
39 #ifdef HAVE_SYS_SOCKET_H
40 #include <sys/socket.h>
42 #ifdef HAVE_NETINET_IN_H
43 #include <netinet/in.h>
45 #ifdef HAVE_SYS_TIME_H
54 #ifdef HAVE_ARPA_INET_H
55 #include <arpa/inet.h>
60 #ifdef HAVE_SYS_IOCTL_H
61 #include <sys/ioctl.h>
64 #ifdef HAVE_SYS_PARAM_H
65 #include <sys/param.h>
68 #endif /* WIN32 ... */
71 #include <curl/curl.h>
79 #include "curl_memory.h"
83 #include "sendf.h" /* for failf function prototype */
84 #include "http_ntlm.h"
85 #include "connect.h" /* for Curl_getconnectinfo */
87 #include "curl_rand.h"
88 #include "non-ascii.h"
90 #define _MPRINTF_REPLACE /* use our functions only */
91 #include <curl/mprintf.h>
93 /* The last #include file should be: */
96 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
98 static void win32_cleanup(void)
103 #ifdef USE_WINDOWS_SSPI
104 Curl_sspi_global_cleanup();
108 /* win32_init() performs win32 socket initialization to properly setup the
109 stack to allow networking */
110 static CURLcode win32_init(void)
113 WORD wVersionRequested;
117 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
118 Error IPV6_requires_winsock2
121 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
123 res = WSAStartup(wVersionRequested, &wsaData);
126 /* Tell the user that we couldn't find a useable */
128 return CURLE_FAILED_INIT;
130 /* Confirm that the Windows Sockets DLL supports what we need.*/
131 /* Note that if the DLL supports versions greater */
132 /* than wVersionRequested, it will still return */
133 /* wVersionRequested in wVersion. wHighVersion contains the */
134 /* highest supported version. */
136 if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
137 HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
138 /* Tell the user that we couldn't find a useable */
142 return CURLE_FAILED_INIT;
144 /* The Windows Sockets DLL is acceptable. Proceed. */
147 #ifdef USE_WINDOWS_SSPI
149 CURLcode err = Curl_sspi_global_init();
160 * Initialise use of IDNA library.
161 * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
162 * idna_to_ascii_lz().
164 static void idna_init (void)
170 if(!getenv("CHARSET") && cp > 0) {
171 snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
178 #endif /* USE_LIBIDN */
180 /* true globals -- for curl_global_init() and curl_global_cleanup() */
181 static unsigned int initialized;
182 static long init_flags;
185 * strdup (and other memory functions) is redefined in complicated
186 * ways, but at this point it must be defined as the system-supplied strdup
187 * so the callback pointer is initialized correctly.
189 #if defined(_WIN32_WCE)
190 #define system_strdup _strdup
191 #elif !defined(HAVE_STRDUP)
192 #define system_strdup curlx_strdup
194 #define system_strdup strdup
197 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
198 # pragma warning(disable:4232) /* MSVC extension, dllimport identity */
201 #ifndef __SYMBIAN32__
203 * If a memory-using function (like curl_getenv) is used before
204 * curl_global_init() is called, we need to have these pointers set already.
206 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
207 curl_free_callback Curl_cfree = (curl_free_callback)free;
208 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
209 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
210 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
213 * Symbian OS doesn't support initialization to code in writeable static data.
214 * Initialization will occur in the curl_global_init() call.
216 curl_malloc_callback Curl_cmalloc;
217 curl_free_callback Curl_cfree;
218 curl_realloc_callback Curl_crealloc;
219 curl_strdup_callback Curl_cstrdup;
220 curl_calloc_callback Curl_ccalloc;
223 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
224 # pragma warning(default:4232) /* MSVC extension, dllimport identity */
228 * curl_global_init() globally initializes cURL given a bitwise set of the
229 * different features of what to initialize.
231 CURLcode curl_global_init(long flags)
236 /* Setup the default memory functions here (again) */
237 Curl_cmalloc = (curl_malloc_callback)malloc;
238 Curl_cfree = (curl_free_callback)free;
239 Curl_crealloc = (curl_realloc_callback)realloc;
240 Curl_cstrdup = (curl_strdup_callback)system_strdup;
241 Curl_ccalloc = (curl_calloc_callback)calloc;
243 if(flags & CURL_GLOBAL_SSL)
244 if(!Curl_ssl_init()) {
245 DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
246 return CURLE_FAILED_INIT;
249 if(flags & CURL_GLOBAL_WIN32)
250 if(win32_init() != CURLE_OK) {
251 DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
252 return CURLE_FAILED_INIT;
257 DEBUGF(fprintf(stderr, "Error: amiga_init failed\n"));
258 return CURLE_FAILED_INIT;
264 DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
272 if(Curl_resolver_global_init() != CURLE_OK) {
273 DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
274 return CURLE_FAILED_INIT;
277 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
278 if(libssh2_init(0)) {
279 DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
280 return CURLE_FAILED_INIT;
286 /* Preset pseudo-random number sequence. */
294 * curl_global_init_mem() globally initializes cURL and also registers the
295 * user provided callback routines.
297 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
298 curl_free_callback f, curl_realloc_callback r,
299 curl_strdup_callback s, curl_calloc_callback c)
301 CURLcode code = CURLE_OK;
303 /* Invalid input, return immediately */
304 if(!m || !f || !r || !s || !c)
305 return CURLE_FAILED_INIT;
307 /* Already initialized, don't do it again */
311 /* Call the actual init function first */
312 code = curl_global_init(flags);
313 if(code == CURLE_OK) {
325 * curl_global_cleanup() globally cleanups cURL, uses the value of
326 * "init_flags" to determine what needs to be cleaned up and what doesn't.
328 void curl_global_cleanup(void)
336 Curl_global_host_cache_dtor();
338 if(init_flags & CURL_GLOBAL_SSL)
341 Curl_resolver_global_cleanup();
343 if(init_flags & CURL_GLOBAL_WIN32)
350 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
351 (void)libssh2_exit();
358 * curl_easy_init() is the external interface to alloc, setup and init an
359 * easy handle that is returned. If anything goes wrong, NULL is returned.
361 CURL *curl_easy_init(void)
364 struct SessionHandle *data;
366 /* Make sure we inited the global SSL stuff */
368 res = curl_global_init(CURL_GLOBAL_DEFAULT);
370 /* something in the global init failed, return nothing */
371 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
376 /* We use curl_open() with undefined URL so far */
377 res = Curl_open(&data);
378 if(res != CURLE_OK) {
379 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
387 * curl_easy_setopt() is the external interface for setting options on an
391 #undef curl_easy_setopt
392 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
395 struct SessionHandle *data = curl;
399 return CURLE_BAD_FUNCTION_ARGUMENT;
403 ret = Curl_setopt(data, tag, arg);
409 #ifdef CURL_MULTIEASY
410 /***************************************************************************
411 * This function is still only for testing purposes. It makes a great way
412 * to run the full test suite on the multi interface instead of the easy one.
413 ***************************************************************************
415 * The *new* curl_easy_perform() is the external interface that performs a
416 * transfer previously setup.
418 * Wrapper-function that: creates a multi handle, adds the easy handle to it,
419 * runs curl_multi_perform() until the transfer is done, then detaches the
420 * easy handle, destroys the multi handle and returns the easy handle's return
421 * code. This will make everything internally use and assume multi interface.
423 CURLcode curl_easy_perform(CURL *easy)
427 CURLcode code = CURLE_OK;
429 struct timeval timeout;
438 return CURLE_BAD_FUNCTION_ARGUMENT;
440 multi = curl_multi_init();
442 return CURLE_OUT_OF_MEMORY;
444 mcode = curl_multi_add_handle(multi, easy);
446 curl_multi_cleanup(multi);
447 if(mcode == CURLM_OUT_OF_MEMORY)
448 return CURLE_OUT_OF_MEMORY;
450 return CURLE_FAILED_INIT;
453 /* we start some action by calling perform right away */
456 while(CURLM_CALL_MULTI_PERFORM ==
457 curl_multi_perform(multi, &still_running));
466 /* timeout once per second */
470 /* Old deprecated style: get file descriptors from the transfers */
471 curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
472 rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
474 /* The way is to extract the sockets and wait for them without using
475 select. This whole alternative version should probably rather use the
476 curl_multi_socket() approach. */
482 /* timeout or data to send/receive => loop! */
483 } while(still_running);
485 msg = curl_multi_info_read(multi, &rc);
487 code = msg->data.result;
489 mcode = curl_multi_remove_handle(multi, easy);
490 /* what to do if it fails? */
492 mcode = curl_multi_cleanup(multi);
493 /* what to do if it fails? */
499 * curl_easy_perform() is the external interface that performs a transfer
502 CURLcode curl_easy_perform(CURL *curl)
504 struct SessionHandle *data = (struct SessionHandle *)curl;
507 return CURLE_BAD_FUNCTION_ARGUMENT;
509 if(! (data->share && data->share->hostcache)) {
510 /* this handle is not using a shared dns cache */
512 if(data->set.global_dns_cache &&
513 (data->dns.hostcachetype != HCACHE_GLOBAL)) {
514 /* global dns cache was requested but still isn't */
515 struct curl_hash *ptr;
517 if(data->dns.hostcachetype == HCACHE_PRIVATE) {
518 /* if the current cache is private, kill it first */
519 Curl_hash_destroy(data->dns.hostcache);
520 data->dns.hostcachetype = HCACHE_NONE;
521 data->dns.hostcache = NULL;
524 ptr = Curl_global_host_cache_init();
526 /* only do this if the global cache init works */
527 data->dns.hostcache = ptr;
528 data->dns.hostcachetype = HCACHE_GLOBAL;
532 if(!data->dns.hostcache) {
533 data->dns.hostcachetype = HCACHE_PRIVATE;
534 data->dns.hostcache = Curl_mk_dnscache();
536 if(!data->dns.hostcache)
537 /* While we possibly could survive and do good without a host cache,
538 the fact that creating it failed indicates that things are truly
539 screwed up and we should bail out! */
540 return CURLE_OUT_OF_MEMORY;
545 if(!data->state.connc) {
546 /* oops, no connection cache, make one up */
547 data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1L);
548 if(!data->state.connc)
549 return CURLE_OUT_OF_MEMORY;
552 return Curl_perform(data);
557 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
560 void curl_easy_cleanup(CURL *curl)
562 struct SessionHandle *data = (struct SessionHandle *)curl;
571 * Store a pointed to the multi handle within the easy handle's data struct.
573 void Curl_easy_addmulti(struct SessionHandle *data,
578 /* the association is cleared, mark the easy handle as not used by an
580 data->state.used_interface = Curl_if_none;
583 void Curl_easy_initHandleData(struct SessionHandle *data)
585 memset(&data->req, 0, sizeof(struct SingleRequest));
587 data->req.maxdownload = -1;
591 * curl_easy_getinfo() is an external interface that allows an app to retrieve
592 * information from a performed transfer and similar.
594 #undef curl_easy_getinfo
595 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
599 struct SessionHandle *data = (struct SessionHandle *)curl;
602 paramp = va_arg(arg, void *);
604 return Curl_getinfo(data, info, paramp);
608 * curl_easy_duphandle() is an external interface to allow duplication of a
609 * given input easy handle. The returned handle will be a new working handle
610 * with all options set exactly as the input source handle.
612 CURL *curl_easy_duphandle(CURL *incurl)
614 struct SessionHandle *data=(struct SessionHandle *)incurl;
616 struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
621 * We setup a few buffers we need. We should probably make them
622 * get setup on-demand in the code, as that would probably decrease
623 * the likeliness of us forgetting to init a buffer here in the future.
625 outcurl->state.headerbuff = malloc(HEADERSIZE);
626 if(!outcurl->state.headerbuff)
628 outcurl->state.headersize = HEADERSIZE;
630 /* copy all userdefined values */
631 if(Curl_dupset(outcurl, data) != CURLE_OK)
634 /* the connection cache is setup on demand */
635 outcurl->state.connc = NULL;
637 outcurl->state.lastconnect = -1;
639 outcurl->progress.flags = data->progress.flags;
640 outcurl->progress.callback = data->progress.callback;
643 /* If cookies are enabled in the parent handle, we enable them
644 in the clone as well! */
645 outcurl->cookies = Curl_cookie_init(data,
646 data->cookies->filename,
648 data->set.cookiesession);
649 if(!outcurl->cookies)
653 /* duplicate all values in 'change' */
654 if(data->change.cookielist) {
655 outcurl->change.cookielist =
656 Curl_slist_duplicate(data->change.cookielist);
657 if(!outcurl->change.cookielist)
661 if(data->change.url) {
662 outcurl->change.url = strdup(data->change.url);
663 if(!outcurl->change.url)
665 outcurl->change.url_alloc = TRUE;
668 if(data->change.referer) {
669 outcurl->change.referer = strdup(data->change.referer);
670 if(!outcurl->change.referer)
672 outcurl->change.referer_alloc = TRUE;
675 /* Clone the resolver handle, if present, for the new handle */
676 if(Curl_resolver_duphandle(&outcurl->state.resolver,
677 data->state.resolver) != CURLE_OK)
680 Curl_convert_setup(outcurl);
682 Curl_easy_initHandleData(outcurl);
684 outcurl->magic = CURLEASY_MAGIC_NUMBER;
686 /* we reach this point and thus we are OK */
693 if(outcurl->state.connc &&
694 (outcurl->state.connc->type == CONNCACHE_PRIVATE))
695 Curl_rm_connc(outcurl->state.connc);
696 if(outcurl->state.headerbuff)
697 free(outcurl->state.headerbuff);
698 if(outcurl->change.cookielist)
699 curl_slist_free_all(outcurl->change.cookielist);
700 if(outcurl->change.url)
701 free(outcurl->change.url);
702 if(outcurl->change.referer)
703 free(outcurl->change.referer);
704 Curl_freeset(outcurl);
712 * curl_easy_reset() is an external interface that allows an app to re-
713 * initialize a session handle to the default values.
715 void curl_easy_reset(CURL *curl)
717 struct SessionHandle *data = (struct SessionHandle *)curl;
719 Curl_safefree(data->state.pathbuffer);
720 data->state.pathbuffer=NULL;
722 Curl_safefree(data->state.proto.generic);
723 data->state.proto.generic=NULL;
725 /* zero out UserDefined data: */
727 memset(&data->set, 0, sizeof(struct UserDefined));
728 (void)Curl_init_userdefined(&data->set);
730 /* zero out Progress data: */
731 memset(&data->progress, 0, sizeof(struct Progress));
733 /* init Handle data */
734 Curl_easy_initHandleData(data);
736 data->progress.flags |= PGRS_HIDE;
737 data->state.current_speed = -1; /* init to negative == impossible */
741 * curl_easy_pause() allows an application to pause or unpause a specific
742 * transfer and direction. This function sets the full new state for the
743 * current connection this easy handle operates on.
745 * NOTE: if you have the receiving paused and you call this function to remove
746 * the pausing, you may get your write callback called at this point.
748 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
750 CURLcode curl_easy_pause(CURL *curl, int action)
752 struct SessionHandle *data = (struct SessionHandle *)curl;
753 struct SingleRequest *k = &data->req;
754 CURLcode result = CURLE_OK;
756 /* first switch off both pause bits */
757 int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
759 /* set the new desired pause bits */
760 newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
761 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
763 /* put it back in the keepon */
764 k->keepon = newstate;
766 if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
767 /* we have a buffer for sending that we now seem to be able to deliver
768 since the receive pausing is lifted! */
770 /* get the pointer, type and length in local copies since the function may
771 return PAUSE again and then we'll get a new copy allocted and stored in
772 the tempwrite variables */
773 char *tempwrite = data->state.tempwrite;
774 char *freewrite = tempwrite; /* store this pointer to free it later */
775 size_t tempsize = data->state.tempwritesize;
776 int temptype = data->state.tempwritetype;
779 /* clear tempwrite here just to make sure it gets cleared if there's no
780 further use of it, and make sure we don't clear it after the function
781 invoke as it may have been set to a new value by then */
782 data->state.tempwrite = NULL;
784 /* since the write callback API is define to never exceed
785 CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
786 have more data than that in our buffer here, we must loop sending the
787 data in multiple calls until there's no data left or we get another
790 A tricky part is that the function we call will "buffer" the data
791 itself when it pauses on a particular buffer, so we may need to do some
792 extra trickery if we get a pause return here.
795 chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
797 result = Curl_client_write(data->state.current_conn,
798 temptype, tempwrite, chunklen);
800 /* failures abort the loop at once */
803 if(data->state.tempwrite && (tempsize - chunklen)) {
804 /* Ouch, the reading is again paused and the block we send is now
805 "cached". If this is the final chunk we can leave it like this, but
806 if we have more chunks that are cached after this, we need to free
807 the newly cached one and put back a version that is truly the entire
808 contents that is saved for later
812 /* note that tempsize is still the size as before the callback was
813 used, and thus the whole piece of data to keep */
814 newptr = realloc(data->state.tempwrite, tempsize);
817 free(data->state.tempwrite); /* free old area */
818 data->state.tempwrite = NULL;
819 result = CURLE_OUT_OF_MEMORY;
820 /* tempwrite will be freed further down */
823 data->state.tempwrite = newptr; /* store new pointer */
824 memcpy(newptr, tempwrite, tempsize);
825 data->state.tempwritesize = tempsize; /* store new size */
826 /* tempwrite will be freed further down */
827 break; /* go back to pausing until further notice */
830 tempsize -= chunklen; /* left after the call above */
831 tempwrite += chunklen; /* advance the pointer */
834 } while((result == CURLE_OK) && tempsize);
836 free(freewrite); /* this is unconditionally no longer used */
843 static CURLcode easy_connection(struct SessionHandle *data,
845 struct connectdata **connp)
848 return CURLE_BAD_FUNCTION_ARGUMENT;
850 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
851 if(!data->set.connect_only) {
852 failf(data, "CONNECT_ONLY is required!");
853 return CURLE_UNSUPPORTED_PROTOCOL;
856 *sfd = Curl_getconnectinfo(data, connp);
858 if(*sfd == CURL_SOCKET_BAD) {
859 failf(data, "Failed to get recent socket");
860 return CURLE_UNSUPPORTED_PROTOCOL;
867 * Receives data from the connected socket. Use after successful
868 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
869 * Returns CURLE_OK on success, error code on error.
871 CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
876 struct connectdata *c;
877 struct SessionHandle *data = (struct SessionHandle *)curl;
879 ret = easy_connection(data, &sfd, &c);
884 ret = Curl_read(c, sfd, buffer, buflen, &n1);
895 * Sends data over the connected socket. Use after successful
896 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
898 CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
904 struct connectdata *c = NULL;
905 struct SessionHandle *data = (struct SessionHandle *)curl;
907 ret = easy_connection(data, &sfd, &c);
912 ret = Curl_write(c, sfd, buffer, buflen, &n1);
915 return CURLE_SEND_ERROR;
918 if((CURLE_OK == ret) && (0 == n1))