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 -- */
37 #ifdef HAVE_SYS_SOCKET_H
38 #include <sys/socket.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
49 #ifdef HAVE_ARPA_INET_H
50 #include <arpa/inet.h>
55 #ifdef HAVE_SYS_IOCTL_H
56 #include <sys/ioctl.h>
59 #ifdef HAVE_SYS_PARAM_H
60 #include <sys/param.h>
63 #endif /* WIN32 ... */
66 #include <curl/curl.h>
74 #include "curl_memory.h"
78 #include "sendf.h" /* for failf function prototype */
79 #include "http_ntlm.h"
80 #include "connect.h" /* for Curl_getconnectinfo */
82 #include "curl_rand.h"
83 #include "non-ascii.h"
86 #define _MPRINTF_REPLACE /* use our functions only */
87 #include <curl/mprintf.h>
89 /* The last #include file should be: */
92 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
94 static void win32_cleanup(void)
99 #ifdef USE_WINDOWS_SSPI
100 Curl_sspi_global_cleanup();
104 /* win32_init() performs win32 socket initialization to properly setup the
105 stack to allow networking */
106 static CURLcode win32_init(void)
109 WORD wVersionRequested;
113 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
114 Error IPV6_requires_winsock2
117 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
119 res = WSAStartup(wVersionRequested, &wsaData);
122 /* Tell the user that we couldn't find a useable */
124 return CURLE_FAILED_INIT;
126 /* Confirm that the Windows Sockets DLL supports what we need.*/
127 /* Note that if the DLL supports versions greater */
128 /* than wVersionRequested, it will still return */
129 /* wVersionRequested in wVersion. wHighVersion contains the */
130 /* highest supported version. */
132 if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
133 HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
134 /* Tell the user that we couldn't find a useable */
138 return CURLE_FAILED_INIT;
140 /* The Windows Sockets DLL is acceptable. Proceed. */
143 #ifdef USE_WINDOWS_SSPI
145 CURLcode err = Curl_sspi_global_init();
156 * Initialise use of IDNA library.
157 * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
158 * idna_to_ascii_lz().
160 static void idna_init (void)
166 if(!getenv("CHARSET") && cp > 0) {
167 snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
174 #endif /* USE_LIBIDN */
176 /* true globals -- for curl_global_init() and curl_global_cleanup() */
177 static unsigned int initialized;
178 static long init_flags;
181 * strdup (and other memory functions) is redefined in complicated
182 * ways, but at this point it must be defined as the system-supplied strdup
183 * so the callback pointer is initialized correctly.
185 #if defined(_WIN32_WCE)
186 #define system_strdup _strdup
187 #elif !defined(HAVE_STRDUP)
188 #define system_strdup curlx_strdup
190 #define system_strdup strdup
193 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
194 # pragma warning(disable:4232) /* MSVC extension, dllimport identity */
197 #ifndef __SYMBIAN32__
199 * If a memory-using function (like curl_getenv) is used before
200 * curl_global_init() is called, we need to have these pointers set already.
202 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
203 curl_free_callback Curl_cfree = (curl_free_callback)free;
204 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
205 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
206 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
209 * Symbian OS doesn't support initialization to code in writeable static data.
210 * Initialization will occur in the curl_global_init() call.
212 curl_malloc_callback Curl_cmalloc;
213 curl_free_callback Curl_cfree;
214 curl_realloc_callback Curl_crealloc;
215 curl_strdup_callback Curl_cstrdup;
216 curl_calloc_callback Curl_ccalloc;
219 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
220 # pragma warning(default:4232) /* MSVC extension, dllimport identity */
224 * curl_global_init() globally initializes cURL given a bitwise set of the
225 * different features of what to initialize.
227 CURLcode curl_global_init(long flags)
232 /* Setup the default memory functions here (again) */
233 Curl_cmalloc = (curl_malloc_callback)malloc;
234 Curl_cfree = (curl_free_callback)free;
235 Curl_crealloc = (curl_realloc_callback)realloc;
236 Curl_cstrdup = (curl_strdup_callback)system_strdup;
237 Curl_ccalloc = (curl_calloc_callback)calloc;
239 if(flags & CURL_GLOBAL_SSL)
240 if(!Curl_ssl_init()) {
241 DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
242 return CURLE_FAILED_INIT;
245 if(flags & CURL_GLOBAL_WIN32)
246 if(win32_init() != CURLE_OK) {
247 DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
248 return CURLE_FAILED_INIT;
253 DEBUGF(fprintf(stderr, "Error: amiga_init failed\n"));
254 return CURLE_FAILED_INIT;
260 DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
268 if(Curl_resolver_global_init() != CURLE_OK) {
269 DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
270 return CURLE_FAILED_INIT;
273 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
274 if(libssh2_init(0)) {
275 DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
276 return CURLE_FAILED_INIT;
282 /* Preset pseudo-random number sequence. */
290 * curl_global_init_mem() globally initializes cURL and also registers the
291 * user provided callback routines.
293 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
294 curl_free_callback f, curl_realloc_callback r,
295 curl_strdup_callback s, curl_calloc_callback c)
297 CURLcode code = CURLE_OK;
299 /* Invalid input, return immediately */
300 if(!m || !f || !r || !s || !c)
301 return CURLE_FAILED_INIT;
303 /* Already initialized, don't do it again */
307 /* Call the actual init function first */
308 code = curl_global_init(flags);
309 if(code == CURLE_OK) {
321 * curl_global_cleanup() globally cleanups cURL, uses the value of
322 * "init_flags" to determine what needs to be cleaned up and what doesn't.
324 void curl_global_cleanup(void)
332 Curl_global_host_cache_dtor();
334 if(init_flags & CURL_GLOBAL_SSL)
337 Curl_resolver_global_cleanup();
339 if(init_flags & CURL_GLOBAL_WIN32)
346 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
347 (void)libssh2_exit();
354 * curl_easy_init() is the external interface to alloc, setup and init an
355 * easy handle that is returned. If anything goes wrong, NULL is returned.
357 CURL *curl_easy_init(void)
360 struct SessionHandle *data;
362 /* Make sure we inited the global SSL stuff */
364 res = curl_global_init(CURL_GLOBAL_DEFAULT);
366 /* something in the global init failed, return nothing */
367 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
372 /* We use curl_open() with undefined URL so far */
373 res = Curl_open(&data);
374 if(res != CURLE_OK) {
375 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
383 * curl_easy_setopt() is the external interface for setting options on an
387 #undef curl_easy_setopt
388 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
391 struct SessionHandle *data = curl;
395 return CURLE_BAD_FUNCTION_ARGUMENT;
399 ret = Curl_setopt(data, tag, arg);
405 #ifdef CURL_MULTIEASY
406 /***************************************************************************
407 * This function is still only for testing purposes. It makes a great way
408 * to run the full test suite on the multi interface instead of the easy one.
409 ***************************************************************************
411 * The *new* curl_easy_perform() is the external interface that performs a
412 * transfer previously setup.
414 * Wrapper-function that: creates a multi handle, adds the easy handle to it,
415 * runs curl_multi_perform() until the transfer is done, then detaches the
416 * easy handle, destroys the multi handle and returns the easy handle's return
417 * code. This will make everything internally use and assume multi interface.
419 CURLcode curl_easy_perform(CURL *easy)
423 CURLcode code = CURLE_OK;
425 struct timeval timeout;
434 return CURLE_BAD_FUNCTION_ARGUMENT;
436 multi = curl_multi_init();
438 return CURLE_OUT_OF_MEMORY;
440 mcode = curl_multi_add_handle(multi, easy);
442 curl_multi_cleanup(multi);
443 if(mcode == CURLM_OUT_OF_MEMORY)
444 return CURLE_OUT_OF_MEMORY;
446 return CURLE_FAILED_INIT;
449 /* we start some action by calling perform right away */
452 while(CURLM_CALL_MULTI_PERFORM ==
453 curl_multi_perform(multi, &still_running));
462 /* timeout once per second */
466 /* Old deprecated style: get file descriptors from the transfers */
467 curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
468 rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
470 /* The way is to extract the sockets and wait for them without using
471 select. This whole alternative version should probably rather use the
472 curl_multi_socket() approach. */
478 /* timeout or data to send/receive => loop! */
479 } while(still_running);
481 msg = curl_multi_info_read(multi, &rc);
483 code = msg->data.result;
485 mcode = curl_multi_remove_handle(multi, easy);
486 /* what to do if it fails? */
488 mcode = curl_multi_cleanup(multi);
489 /* what to do if it fails? */
495 * curl_easy_perform() is the external interface that performs a transfer
498 CURLcode curl_easy_perform(CURL *curl)
500 struct SessionHandle *data = (struct SessionHandle *)curl;
503 return CURLE_BAD_FUNCTION_ARGUMENT;
505 if(! (data->share && data->share->hostcache)) {
506 /* this handle is not using a shared dns cache */
508 if(data->set.global_dns_cache &&
509 (data->dns.hostcachetype != HCACHE_GLOBAL)) {
510 /* global dns cache was requested but still isn't */
511 struct curl_hash *ptr;
513 if(data->dns.hostcachetype == HCACHE_PRIVATE) {
514 /* if the current cache is private, kill it first */
515 Curl_hash_destroy(data->dns.hostcache);
516 data->dns.hostcachetype = HCACHE_NONE;
517 data->dns.hostcache = NULL;
520 ptr = Curl_global_host_cache_init();
522 /* only do this if the global cache init works */
523 data->dns.hostcache = ptr;
524 data->dns.hostcachetype = HCACHE_GLOBAL;
528 if(!data->dns.hostcache) {
529 data->dns.hostcachetype = HCACHE_PRIVATE;
530 data->dns.hostcache = Curl_mk_dnscache();
532 if(!data->dns.hostcache)
533 /* While we possibly could survive and do good without a host cache,
534 the fact that creating it failed indicates that things are truly
535 screwed up and we should bail out! */
536 return CURLE_OUT_OF_MEMORY;
541 if(!data->state.connc) {
542 /* oops, no connection cache, make one up */
543 data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1L);
544 if(!data->state.connc)
545 return CURLE_OUT_OF_MEMORY;
548 return Curl_perform(data);
553 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
556 void curl_easy_cleanup(CURL *curl)
558 struct SessionHandle *data = (struct SessionHandle *)curl;
567 * Store a pointed to the multi handle within the easy handle's data struct.
569 void Curl_easy_addmulti(struct SessionHandle *data,
574 /* the association is cleared, mark the easy handle as not used by an
576 data->state.used_interface = Curl_if_none;
579 void Curl_easy_initHandleData(struct SessionHandle *data)
581 memset(&data->req, 0, sizeof(struct SingleRequest));
583 data->req.maxdownload = -1;
587 * curl_easy_getinfo() is an external interface that allows an app to retrieve
588 * information from a performed transfer and similar.
590 #undef curl_easy_getinfo
591 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
595 struct SessionHandle *data = (struct SessionHandle *)curl;
598 paramp = va_arg(arg, void *);
600 return Curl_getinfo(data, info, paramp);
604 * curl_easy_duphandle() is an external interface to allow duplication of a
605 * given input easy handle. The returned handle will be a new working handle
606 * with all options set exactly as the input source handle.
608 CURL *curl_easy_duphandle(CURL *incurl)
610 struct SessionHandle *data=(struct SessionHandle *)incurl;
612 struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
617 * We setup a few buffers we need. We should probably make them
618 * get setup on-demand in the code, as that would probably decrease
619 * the likeliness of us forgetting to init a buffer here in the future.
621 outcurl->state.headerbuff = malloc(HEADERSIZE);
622 if(!outcurl->state.headerbuff)
624 outcurl->state.headersize = HEADERSIZE;
626 /* copy all userdefined values */
627 if(Curl_dupset(outcurl, data) != CURLE_OK)
630 /* the connection cache is setup on demand */
631 outcurl->state.connc = NULL;
633 outcurl->state.lastconnect = -1;
635 outcurl->progress.flags = data->progress.flags;
636 outcurl->progress.callback = data->progress.callback;
639 /* If cookies are enabled in the parent handle, we enable them
640 in the clone as well! */
641 outcurl->cookies = Curl_cookie_init(data,
642 data->cookies->filename,
644 data->set.cookiesession);
645 if(!outcurl->cookies)
649 /* duplicate all values in 'change' */
650 if(data->change.cookielist) {
651 outcurl->change.cookielist =
652 Curl_slist_duplicate(data->change.cookielist);
653 if(!outcurl->change.cookielist)
657 if(data->change.url) {
658 outcurl->change.url = strdup(data->change.url);
659 if(!outcurl->change.url)
661 outcurl->change.url_alloc = TRUE;
664 if(data->change.referer) {
665 outcurl->change.referer = strdup(data->change.referer);
666 if(!outcurl->change.referer)
668 outcurl->change.referer_alloc = TRUE;
671 /* Clone the resolver handle, if present, for the new handle */
672 if(Curl_resolver_duphandle(&outcurl->state.resolver,
673 data->state.resolver) != CURLE_OK)
676 Curl_convert_setup(outcurl);
678 Curl_easy_initHandleData(outcurl);
680 outcurl->magic = CURLEASY_MAGIC_NUMBER;
682 /* we reach this point and thus we are OK */
689 if(outcurl->state.connc &&
690 (outcurl->state.connc->type == CONNCACHE_PRIVATE))
691 Curl_rm_connc(outcurl->state.connc);
692 if(outcurl->state.headerbuff)
693 free(outcurl->state.headerbuff);
694 if(outcurl->change.cookielist)
695 curl_slist_free_all(outcurl->change.cookielist);
696 if(outcurl->change.url)
697 free(outcurl->change.url);
698 if(outcurl->change.referer)
699 free(outcurl->change.referer);
700 Curl_freeset(outcurl);
708 * curl_easy_reset() is an external interface that allows an app to re-
709 * initialize a session handle to the default values.
711 void curl_easy_reset(CURL *curl)
713 struct SessionHandle *data = (struct SessionHandle *)curl;
715 Curl_safefree(data->state.pathbuffer);
716 data->state.pathbuffer=NULL;
718 Curl_safefree(data->state.proto.generic);
719 data->state.proto.generic=NULL;
721 /* zero out UserDefined data: */
723 memset(&data->set, 0, sizeof(struct UserDefined));
724 (void)Curl_init_userdefined(&data->set);
726 /* zero out Progress data: */
727 memset(&data->progress, 0, sizeof(struct Progress));
729 /* init Handle data */
730 Curl_easy_initHandleData(data);
732 data->progress.flags |= PGRS_HIDE;
733 data->state.current_speed = -1; /* init to negative == impossible */
737 * curl_easy_pause() allows an application to pause or unpause a specific
738 * transfer and direction. This function sets the full new state for the
739 * current connection this easy handle operates on.
741 * NOTE: if you have the receiving paused and you call this function to remove
742 * the pausing, you may get your write callback called at this point.
744 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
746 CURLcode curl_easy_pause(CURL *curl, int action)
748 struct SessionHandle *data = (struct SessionHandle *)curl;
749 struct SingleRequest *k = &data->req;
750 CURLcode result = CURLE_OK;
752 /* first switch off both pause bits */
753 int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
755 /* set the new desired pause bits */
756 newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
757 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
759 /* put it back in the keepon */
760 k->keepon = newstate;
762 if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
763 /* we have a buffer for sending that we now seem to be able to deliver
764 since the receive pausing is lifted! */
766 /* get the pointer, type and length in local copies since the function may
767 return PAUSE again and then we'll get a new copy allocted and stored in
768 the tempwrite variables */
769 char *tempwrite = data->state.tempwrite;
770 char *freewrite = tempwrite; /* store this pointer to free it later */
771 size_t tempsize = data->state.tempwritesize;
772 int temptype = data->state.tempwritetype;
775 /* clear tempwrite here just to make sure it gets cleared if there's no
776 further use of it, and make sure we don't clear it after the function
777 invoke as it may have been set to a new value by then */
778 data->state.tempwrite = NULL;
780 /* since the write callback API is define to never exceed
781 CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
782 have more data than that in our buffer here, we must loop sending the
783 data in multiple calls until there's no data left or we get another
786 A tricky part is that the function we call will "buffer" the data
787 itself when it pauses on a particular buffer, so we may need to do some
788 extra trickery if we get a pause return here.
791 chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
793 result = Curl_client_write(data->state.current_conn,
794 temptype, tempwrite, chunklen);
796 /* failures abort the loop at once */
799 if(data->state.tempwrite && (tempsize - chunklen)) {
800 /* Ouch, the reading is again paused and the block we send is now
801 "cached". If this is the final chunk we can leave it like this, but
802 if we have more chunks that are cached after this, we need to free
803 the newly cached one and put back a version that is truly the entire
804 contents that is saved for later
808 /* note that tempsize is still the size as before the callback was
809 used, and thus the whole piece of data to keep */
810 newptr = realloc(data->state.tempwrite, tempsize);
813 free(data->state.tempwrite); /* free old area */
814 data->state.tempwrite = NULL;
815 result = CURLE_OUT_OF_MEMORY;
816 /* tempwrite will be freed further down */
819 data->state.tempwrite = newptr; /* store new pointer */
820 memcpy(newptr, tempwrite, tempsize);
821 data->state.tempwritesize = tempsize; /* store new size */
822 /* tempwrite will be freed further down */
823 break; /* go back to pausing until further notice */
826 tempsize -= chunklen; /* left after the call above */
827 tempwrite += chunklen; /* advance the pointer */
830 } while((result == CURLE_OK) && tempsize);
832 free(freewrite); /* this is unconditionally no longer used */
839 static CURLcode easy_connection(struct SessionHandle *data,
841 struct connectdata **connp)
844 return CURLE_BAD_FUNCTION_ARGUMENT;
846 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
847 if(!data->set.connect_only) {
848 failf(data, "CONNECT_ONLY is required!");
849 return CURLE_UNSUPPORTED_PROTOCOL;
852 *sfd = Curl_getconnectinfo(data, connp);
854 if(*sfd == CURL_SOCKET_BAD) {
855 failf(data, "Failed to get recent socket");
856 return CURLE_UNSUPPORTED_PROTOCOL;
863 * Receives data from the connected socket. Use after successful
864 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
865 * Returns CURLE_OK on success, error code on error.
867 CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
872 struct connectdata *c;
873 struct SessionHandle *data = (struct SessionHandle *)curl;
875 ret = easy_connection(data, &sfd, &c);
880 ret = Curl_read(c, sfd, buffer, buflen, &n1);
891 * Sends data over the connected socket. Use after successful
892 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
894 CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
900 struct connectdata *c = NULL;
901 struct SessionHandle *data = (struct SessionHandle *)curl;
903 ret = easy_connection(data, &sfd, &c);
908 ret = Curl_write(c, sfd, buffer, buflen, &n1);
911 return CURLE_SEND_ERROR;
914 if((CURLE_OK == ret) && (0 == n1))