1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, 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 ***************************************************************************/
23 #include "curl_setup.h"
26 * See comment in curl_memory.h for the explanation of this sanity check.
29 #ifdef CURLX_NO_MEMORY_CALLBACKS
30 #error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
39 #ifdef HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
45 #ifdef HAVE_SYS_IOCTL_H
46 #include <sys/ioctl.h>
49 #ifdef HAVE_SYS_PARAM_H
50 #include <sys/param.h>
55 #include <curl/curl.h>
57 #include "vtls/sslgen.h"
63 #include "curl_memory.h"
67 #include "sendf.h" /* for failf function prototype */
68 #include "curl_ntlm.h"
69 #include "connect.h" /* for Curl_getconnectinfo */
72 #include "non-ascii.h"
74 #include "conncache.h"
78 #define _MPRINTF_REPLACE /* use our functions only */
79 #include <curl/mprintf.h>
81 /* The last #include file should be: */
84 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
86 static void win32_cleanup(void)
91 #ifdef USE_WINDOWS_SSPI
92 Curl_sspi_global_cleanup();
96 /* win32_init() performs win32 socket initialization to properly setup the
97 stack to allow networking */
98 static CURLcode win32_init(void)
101 WORD wVersionRequested;
105 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
106 Error IPV6_requires_winsock2
109 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
111 res = WSAStartup(wVersionRequested, &wsaData);
114 /* Tell the user that we couldn't find a useable */
116 return CURLE_FAILED_INIT;
118 /* Confirm that the Windows Sockets DLL supports what we need.*/
119 /* Note that if the DLL supports versions greater */
120 /* than wVersionRequested, it will still return */
121 /* wVersionRequested in wVersion. wHighVersion contains the */
122 /* highest supported version. */
124 if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
125 HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
126 /* Tell the user that we couldn't find a useable */
130 return CURLE_FAILED_INIT;
132 /* The Windows Sockets DLL is acceptable. Proceed. */
133 #elif defined(USE_LWIPSOCK)
137 #ifdef USE_WINDOWS_SSPI
139 CURLcode err = Curl_sspi_global_init();
150 * Initialise use of IDNA library.
151 * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
152 * idna_to_ascii_lz().
154 static void idna_init (void)
160 if(!getenv("CHARSET") && cp > 0) {
161 snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
168 #endif /* USE_LIBIDN */
170 /* true globals -- for curl_global_init() and curl_global_cleanup() */
171 static unsigned int initialized;
172 static long init_flags;
175 * strdup (and other memory functions) is redefined in complicated
176 * ways, but at this point it must be defined as the system-supplied strdup
177 * so the callback pointer is initialized correctly.
179 #if defined(_WIN32_WCE)
180 #define system_strdup _strdup
181 #elif !defined(HAVE_STRDUP)
182 #define system_strdup curlx_strdup
184 #define system_strdup strdup
187 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
188 # pragma warning(disable:4232) /* MSVC extension, dllimport identity */
191 #ifndef __SYMBIAN32__
193 * If a memory-using function (like curl_getenv) is used before
194 * curl_global_init() is called, we need to have these pointers set already.
196 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
197 curl_free_callback Curl_cfree = (curl_free_callback)free;
198 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
199 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
200 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
201 #if defined(WIN32) && defined(UNICODE)
202 curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
206 * Symbian OS doesn't support initialization to code in writeable static data.
207 * Initialization will occur in the curl_global_init() call.
209 curl_malloc_callback Curl_cmalloc;
210 curl_free_callback Curl_cfree;
211 curl_realloc_callback Curl_crealloc;
212 curl_strdup_callback Curl_cstrdup;
213 curl_calloc_callback Curl_ccalloc;
216 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
217 # pragma warning(default:4232) /* MSVC extension, dllimport identity */
221 * curl_global_init() globally initializes cURL given a bitwise set of the
222 * different features of what to initialize.
224 CURLcode curl_global_init(long flags)
229 /* Setup the default memory functions here (again) */
230 Curl_cmalloc = (curl_malloc_callback)malloc;
231 Curl_cfree = (curl_free_callback)free;
232 Curl_crealloc = (curl_realloc_callback)realloc;
233 Curl_cstrdup = (curl_strdup_callback)system_strdup;
234 Curl_ccalloc = (curl_calloc_callback)calloc;
235 #if defined(WIN32) && defined(UNICODE)
236 Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
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;
252 if(!Curl_amiga_init()) {
253 DEBUGF(fprintf(stderr, "Error: Curl_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;
280 if(flags & CURL_GLOBAL_ACK_EINTR)
289 * curl_global_init_mem() globally initializes cURL and also registers the
290 * user provided callback routines.
292 CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
293 curl_free_callback f, curl_realloc_callback r,
294 curl_strdup_callback s, curl_calloc_callback c)
296 CURLcode code = CURLE_OK;
298 /* Invalid input, return immediately */
299 if(!m || !f || !r || !s || !c)
300 return CURLE_FAILED_INIT;
302 /* Already initialized, don't do it again */
306 /* Call the actual init function first */
307 code = curl_global_init(flags);
308 if(code == CURLE_OK) {
320 * curl_global_cleanup() globally cleanups cURL, uses the value of
321 * "init_flags" to determine what needs to be cleaned up and what doesn't.
323 void curl_global_cleanup(void)
331 Curl_global_host_cache_dtor();
333 if(init_flags & CURL_GLOBAL_SSL)
336 Curl_resolver_global_cleanup();
338 if(init_flags & CURL_GLOBAL_WIN32)
341 Curl_amiga_cleanup();
343 #if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
344 (void)libssh2_exit();
351 * curl_easy_init() is the external interface to alloc, setup and init an
352 * easy handle that is returned. If anything goes wrong, NULL is returned.
354 CURL *curl_easy_init(void)
357 struct SessionHandle *data;
359 /* Make sure we inited the global SSL stuff */
361 res = curl_global_init(CURL_GLOBAL_DEFAULT);
363 /* something in the global init failed, return nothing */
364 DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
369 /* We use curl_open() with undefined URL so far */
370 res = Curl_open(&data);
371 if(res != CURLE_OK) {
372 DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
380 * curl_easy_setopt() is the external interface for setting options on an
384 #undef curl_easy_setopt
385 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
388 struct SessionHandle *data = curl;
392 return CURLE_BAD_FUNCTION_ARGUMENT;
396 ret = Curl_setopt(data, tag, arg);
404 struct socketmonitor {
405 struct socketmonitor *next; /* the next node in the list or NULL */
406 struct pollfd socket; /* socket info of what to monitor */
410 long ms; /* timeout, run the timeout function when reached */
411 bool msbump; /* set TRUE when timeout is set by callback */
412 int num_sockets; /* number of nodes in the monitor list */
413 struct socketmonitor *list; /* list of sockets to monitor */
414 int running_handles; /* store the returned number */
419 * Callback that gets called with a new value when the timeout should be
423 static int events_timer(CURLM *multi, /* multi handle */
424 long timeout_ms, /* see above */
425 void *userp) /* private callback pointer */
427 struct events *ev = userp;
430 /* timeout removed */
432 else if(timeout_ms == 0)
433 /* timeout is already reached! */
434 timeout_ms = 1; /* trigger asap */
444 * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
446 static int poll2cselect(int pollmask)
449 if(pollmask & POLLIN)
450 omask |= CURL_CSELECT_IN;
451 if(pollmask & POLLOUT)
452 omask |= CURL_CSELECT_OUT;
453 if(pollmask & POLLERR)
454 omask |= CURL_CSELECT_ERR;
461 * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
463 static short socketcb2poll(int pollmask)
466 if(pollmask & CURL_POLL_IN)
468 if(pollmask & CURL_POLL_OUT)
475 * Callback that gets called with information about socket activity to
478 static int events_socket(CURL *easy, /* easy handle */
479 curl_socket_t s, /* socket */
480 int what, /* see above */
481 void *userp, /* private callback
483 void *socketp) /* private socket
486 struct events *ev = userp;
487 struct socketmonitor *m;
488 struct socketmonitor *prev=NULL;
493 if(m->socket.fd == s) {
495 if(what == CURL_POLL_REMOVE) {
496 struct socketmonitor *nxt = m->next;
497 /* remove this node from the list of monitored sockets */
504 infof(easy, "socket cb: socket %d REMOVED\n", s);
507 /* The socket 's' is already being monitored, update the activity
508 mask. Convert from libcurl bitmask to the poll one. */
509 m->socket.events = socketcb2poll(what);
510 infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
511 what&CURL_POLL_IN?"IN":"",
512 what&CURL_POLL_OUT?"OUT":"");
517 m = m->next; /* move to next node */
520 if(what == CURL_POLL_REMOVE) {
521 /* this happens a bit too often, libcurl fix perhaps? */
523 "%s: socket %d asked to be REMOVED but not present!\n",
527 m = malloc(sizeof(struct socketmonitor));
530 m->socket.events = socketcb2poll(what);
531 m->socket.revents = 0;
533 infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
534 what&CURL_POLL_IN?"IN":"",
535 what&CURL_POLL_OUT?"OUT":"");
546 * Do the multi handle setups that only event-based transfers need.
548 static void events_setup(CURLM *multi, struct events *ev)
551 curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
552 curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
554 /* socket callback */
555 curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
556 curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
562 * waits for activity on any of the given sockets, or the timeout to trigger.
565 static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
569 CURLcode rc = CURLE_OK;
573 struct socketmonitor *m;
575 struct pollfd fds[4];
579 struct timeval before;
580 struct timeval after;
582 /* populate the fds[] array */
583 for(m = ev->list, f=&fds[0]; m; m = m->next) {
584 f->fd = m->socket.fd;
585 f->events = m->socket.events;
587 /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
592 /* get the time stamp to use to figure out how long poll takes */
593 before = curlx_tvnow();
595 /* wait for activity or timeout */
596 pollrc = Curl_poll(fds, numfds, (int)ev->ms);
598 after = curlx_tvnow();
600 ev->msbump = FALSE; /* reset here */
605 /* fprintf(stderr, "call curl_multi_socket_action( TIMEOUT )\n"); */
606 mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
607 &ev->running_handles);
609 else if(pollrc > 0) {
610 /* loop over the monitored sockets to see which ones had activity */
611 for(i = 0; i< numfds; i++) {
613 /* socket activity, tell libcurl */
614 int act = poll2cselect(fds[i].revents); /* convert */
615 infof(multi->easyp, "call curl_multi_socket_action( socket %d )\n",
617 mcode = curl_multi_socket_action(multi, fds[i].fd, act,
618 &ev->running_handles);
623 /* If nothing updated the timeout, we decrease it by the spent time.
624 * If it was updated, it has the new timeout time stored already.
626 ev->ms += curlx_tvdiff(after, before);
630 return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
632 /* we don't really care about the "msgs_in_queue" value returned in the
634 msg = curl_multi_info_read(multi, &pollrc);
636 rc = msg->data.result;
647 * Runs a transfer in a blocking manner using the events-based API
649 static CURLcode easy_events(CURLM *multi)
651 struct events evs= {2, FALSE, 0, NULL, 0};
653 /* if running event-based, do some further multi inits */
654 events_setup(multi, &evs);
656 return wait_or_timeout(multi, &evs);
658 #else /* CURLDEBUG */
659 /* when not built with debug, this function doesn't exist */
660 #define easy_events(x) CURLE_NOT_BUILT_IN
663 static CURLcode easy_transfer(CURLM *multi)
666 CURLMcode mcode = CURLM_OK;
667 CURLcode code = CURLE_OK;
668 struct timeval before;
669 int without_fds = 0; /* count number of consecutive returns from
670 curl_multi_wait() without any filedescriptors */
672 while(!done && !mcode) {
676 before = curlx_tvnow();
677 mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
679 if(mcode == CURLM_OK) {
681 /* poll() failed not on EINTR, indicate a network problem */
682 code = CURLE_RECV_ERROR;
686 struct timeval after = curlx_tvnow();
687 /* If it returns without any filedescriptor instantly, we need to
688 avoid busy-looping during periods where it has nothing particular
690 if(curlx_tvdiff(after, before) <= 10) {
692 if(without_fds > 2) {
693 int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
694 Curl_wait_ms(sleep_ms);
698 /* it wasn't "instant", restart counter */
702 /* got file descriptor, restart counter */
705 mcode = curl_multi_perform(multi, &still_running);
708 /* only read 'still_running' if curl_multi_perform() return OK */
709 if((mcode == CURLM_OK) && !still_running) {
711 CURLMsg *msg = curl_multi_info_read(multi, &rc);
713 code = msg->data.result;
723 * easy_perform() is the external interface that performs a blocking
724 * transfer as previously setup.
726 * CONCEPT: This function creates a multi handle, adds the easy handle to it,
727 * runs curl_multi_perform() until the transfer is done, then detaches the
728 * easy handle, destroys the multi handle and returns the easy handle's return
731 * REALITY: it can't just create and destroy the multi handle that easily. It
732 * needs to keep it around since if this easy handle is used again by this
733 * function, the same multi handle must be re-used so that the same pools and
734 * caches can be used.
736 * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
737 * instead of curl_multi_perform() and use curl_multi_socket_action().
739 static CURLcode easy_perform(struct SessionHandle *data, bool events)
743 CURLcode code = CURLE_OK;
744 SIGPIPE_VARIABLE(pipe_st);
747 return CURLE_BAD_FUNCTION_ARGUMENT;
750 failf(data, "easy handled already used in multi handle");
751 return CURLE_FAILED_INIT;
755 multi = data->multi_easy;
757 /* this multi handle will only ever have a single easy handled attached
758 to it, so make it use minimal hashes */
759 multi = Curl_multi_handle(1, 3);
761 return CURLE_OUT_OF_MEMORY;
762 data->multi_easy = multi;
765 /* Copy the MAXCONNECTS option to the multi handle */
766 curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
768 mcode = curl_multi_add_handle(multi, data);
770 curl_multi_cleanup(multi);
771 if(mcode == CURLM_OUT_OF_MEMORY)
772 return CURLE_OUT_OF_MEMORY;
774 return CURLE_FAILED_INIT;
777 sigpipe_ignore(data, &pipe_st);
779 /* assign this after curl_multi_add_handle() since that function checks for
780 it and rejects this handle otherwise */
783 /* run the transfer */
784 code = events ? easy_events(multi) : easy_transfer(multi);
786 /* ignoring the return code isn't nice, but atm we can't really handle
787 a failure here, room for future improvement! */
788 (void)curl_multi_remove_handle(multi, data);
790 sigpipe_restore(&pipe_st);
792 /* The multi handle is kept alive, owned by the easy handle */
798 * curl_easy_perform() is the external interface that performs a blocking
799 * transfer as previously setup.
801 CURLcode curl_easy_perform(CURL *easy)
803 return easy_perform(easy, FALSE);
808 * curl_easy_perform_ev() is the external interface that performs a blocking
809 * transfer using the event-based API internally.
811 CURLcode curl_easy_perform_ev(CURL *easy)
813 return easy_perform(easy, TRUE);
819 * curl_easy_cleanup() is the external interface to cleaning/freeing the given
822 void curl_easy_cleanup(CURL *curl)
824 struct SessionHandle *data = (struct SessionHandle *)curl;
825 SIGPIPE_VARIABLE(pipe_st);
830 sigpipe_ignore(data, &pipe_st);
832 sigpipe_restore(&pipe_st);
836 * curl_easy_getinfo() is an external interface that allows an app to retrieve
837 * information from a performed transfer and similar.
839 #undef curl_easy_getinfo
840 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
845 struct SessionHandle *data = (struct SessionHandle *)curl;
848 paramp = va_arg(arg, void *);
850 ret = Curl_getinfo(data, info, paramp);
857 * curl_easy_duphandle() is an external interface to allow duplication of a
858 * given input easy handle. The returned handle will be a new working handle
859 * with all options set exactly as the input source handle.
861 CURL *curl_easy_duphandle(CURL *incurl)
863 struct SessionHandle *data=(struct SessionHandle *)incurl;
865 struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
870 * We setup a few buffers we need. We should probably make them
871 * get setup on-demand in the code, as that would probably decrease
872 * the likeliness of us forgetting to init a buffer here in the future.
874 outcurl->state.headerbuff = malloc(HEADERSIZE);
875 if(!outcurl->state.headerbuff)
877 outcurl->state.headersize = HEADERSIZE;
879 /* copy all userdefined values */
880 if(Curl_dupset(outcurl, data) != CURLE_OK)
883 /* the connection cache is setup on demand */
884 outcurl->state.conn_cache = NULL;
886 outcurl->state.lastconnect = NULL;
888 outcurl->progress.flags = data->progress.flags;
889 outcurl->progress.callback = data->progress.callback;
892 /* If cookies are enabled in the parent handle, we enable them
893 in the clone as well! */
894 outcurl->cookies = Curl_cookie_init(data,
895 data->cookies->filename,
897 data->set.cookiesession);
898 if(!outcurl->cookies)
902 /* duplicate all values in 'change' */
903 if(data->change.cookielist) {
904 outcurl->change.cookielist =
905 Curl_slist_duplicate(data->change.cookielist);
906 if(!outcurl->change.cookielist)
910 if(data->change.url) {
911 outcurl->change.url = strdup(data->change.url);
912 if(!outcurl->change.url)
914 outcurl->change.url_alloc = TRUE;
917 if(data->change.referer) {
918 outcurl->change.referer = strdup(data->change.referer);
919 if(!outcurl->change.referer)
921 outcurl->change.referer_alloc = TRUE;
924 /* Clone the resolver handle, if present, for the new handle */
925 if(Curl_resolver_duphandle(&outcurl->state.resolver,
926 data->state.resolver) != CURLE_OK)
929 Curl_convert_setup(outcurl);
931 outcurl->magic = CURLEASY_MAGIC_NUMBER;
933 /* we reach this point and thus we are OK */
940 curl_slist_free_all(outcurl->change.cookielist);
941 outcurl->change.cookielist = NULL;
942 Curl_safefree(outcurl->state.headerbuff);
943 Curl_safefree(outcurl->change.url);
944 Curl_safefree(outcurl->change.referer);
945 Curl_freeset(outcurl);
953 * curl_easy_reset() is an external interface that allows an app to re-
954 * initialize a session handle to the default values.
956 void curl_easy_reset(CURL *curl)
958 struct SessionHandle *data = (struct SessionHandle *)curl;
960 Curl_safefree(data->state.pathbuffer);
962 data->state.path = NULL;
964 Curl_free_request_state(data);
966 /* zero out UserDefined data: */
968 memset(&data->set, 0, sizeof(struct UserDefined));
969 (void)Curl_init_userdefined(&data->set);
971 /* zero out Progress data: */
972 memset(&data->progress, 0, sizeof(struct Progress));
974 data->progress.flags |= PGRS_HIDE;
975 data->state.current_speed = -1; /* init to negative == impossible */
979 * curl_easy_pause() allows an application to pause or unpause a specific
980 * transfer and direction. This function sets the full new state for the
981 * current connection this easy handle operates on.
983 * NOTE: if you have the receiving paused and you call this function to remove
984 * the pausing, you may get your write callback called at this point.
986 * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
988 CURLcode curl_easy_pause(CURL *curl, int action)
990 struct SessionHandle *data = (struct SessionHandle *)curl;
991 struct SingleRequest *k = &data->req;
992 CURLcode result = CURLE_OK;
994 /* first switch off both pause bits */
995 int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
997 /* set the new desired pause bits */
998 newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
999 ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
1001 /* put it back in the keepon */
1002 k->keepon = newstate;
1004 if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
1005 /* we have a buffer for sending that we now seem to be able to deliver
1006 since the receive pausing is lifted! */
1008 /* get the pointer, type and length in local copies since the function may
1009 return PAUSE again and then we'll get a new copy allocted and stored in
1010 the tempwrite variables */
1011 char *tempwrite = data->state.tempwrite;
1012 char *freewrite = tempwrite; /* store this pointer to free it later */
1013 size_t tempsize = data->state.tempwritesize;
1014 int temptype = data->state.tempwritetype;
1017 /* clear tempwrite here just to make sure it gets cleared if there's no
1018 further use of it, and make sure we don't clear it after the function
1019 invoke as it may have been set to a new value by then */
1020 data->state.tempwrite = NULL;
1022 /* since the write callback API is define to never exceed
1023 CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
1024 have more data than that in our buffer here, we must loop sending the
1025 data in multiple calls until there's no data left or we get another
1028 A tricky part is that the function we call will "buffer" the data
1029 itself when it pauses on a particular buffer, so we may need to do some
1030 extra trickery if we get a pause return here.
1033 chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
1035 result = Curl_client_write(data->easy_conn,
1036 temptype, tempwrite, chunklen);
1038 /* failures abort the loop at once */
1041 if(data->state.tempwrite && (tempsize - chunklen)) {
1042 /* Ouch, the reading is again paused and the block we send is now
1043 "cached". If this is the final chunk we can leave it like this, but
1044 if we have more chunks that are cached after this, we need to free
1045 the newly cached one and put back a version that is truly the entire
1046 contents that is saved for later
1050 /* note that tempsize is still the size as before the callback was
1051 used, and thus the whole piece of data to keep */
1052 newptr = realloc(data->state.tempwrite, tempsize);
1055 free(data->state.tempwrite); /* free old area */
1056 data->state.tempwrite = NULL;
1057 result = CURLE_OUT_OF_MEMORY;
1058 /* tempwrite will be freed further down */
1061 data->state.tempwrite = newptr; /* store new pointer */
1062 memcpy(newptr, tempwrite, tempsize);
1063 data->state.tempwritesize = tempsize; /* store new size */
1064 /* tempwrite will be freed further down */
1065 break; /* go back to pausing until further notice */
1068 tempsize -= chunklen; /* left after the call above */
1069 tempwrite += chunklen; /* advance the pointer */
1072 } while((result == CURLE_OK) && tempsize);
1074 free(freewrite); /* this is unconditionally no longer used */
1077 /* if there's no error and we're not pausing both directions, we want
1078 to have this handle checked soon */
1080 ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
1081 (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
1082 Curl_expire(data, 1); /* get this handle going again */
1088 static CURLcode easy_connection(struct SessionHandle *data,
1090 struct connectdata **connp)
1093 return CURLE_BAD_FUNCTION_ARGUMENT;
1095 /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
1096 if(!data->set.connect_only) {
1097 failf(data, "CONNECT_ONLY is required!");
1098 return CURLE_UNSUPPORTED_PROTOCOL;
1101 *sfd = Curl_getconnectinfo(data, connp);
1103 if(*sfd == CURL_SOCKET_BAD) {
1104 failf(data, "Failed to get recent socket");
1105 return CURLE_UNSUPPORTED_PROTOCOL;
1112 * Receives data from the connected socket. Use after successful
1113 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1114 * Returns CURLE_OK on success, error code on error.
1116 CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
1121 struct connectdata *c;
1122 struct SessionHandle *data = (struct SessionHandle *)curl;
1124 ret = easy_connection(data, &sfd, &c);
1129 ret = Curl_read(c, sfd, buffer, buflen, &n1);
1140 * Sends data over the connected socket. Use after successful
1141 * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
1143 CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
1149 struct connectdata *c = NULL;
1150 struct SessionHandle *data = (struct SessionHandle *)curl;
1152 ret = easy_connection(data, &sfd, &c);
1157 ret = Curl_write(c, sfd, buffer, buflen, &n1);
1160 return CURLE_SEND_ERROR;
1163 if((CURLE_OK == ret) && (0 == n1))