/* * curl_easy_perform() is the external interface that performs a transfer * previously setup. */ CURLcode curl_easy_perform(CURL *curl) { struct SessionHandle *data = (struct SessionHandle *)curl; if(!data) return CURLE_BAD_FUNCTION_ARGUMENT; if( ! (data->share && data->share->hostcache) ) { /* this handle is not using a shared dns cache */ if(data->set.global_dns_cache && (data->dns.hostcachetype != HCACHE_GLOBAL)) { /* global dns cache was requested but still isn't */ struct curl_hash *ptr; if(data->dns.hostcachetype == HCACHE_PRIVATE) { /* if the current cache is private, kill it first */ Curl_hash_destroy(data->dns.hostcache); data->dns.hostcachetype = HCACHE_NONE; data->dns.hostcache = NULL; } ptr = Curl_global_host_cache_init(); if(ptr) { /* only do this if the global cache init works */ data->dns.hostcache = ptr; data->dns.hostcachetype = HCACHE_GLOBAL; } } if(!data->dns.hostcache) { data->dns.hostcachetype = HCACHE_PRIVATE; data->dns.hostcache = Curl_mk_dnscache(); if(!data->dns.hostcache) /* While we possibly could survive and do good without a host cache, the fact that creating it failed indicates that things are truly screwed up and we should bail out! */ return CURLE_OUT_OF_MEMORY; } } if(!data->state.connc) { /* oops, no connection cache, make one up */ data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1L); if(!data->state.connc) return CURLE_OUT_OF_MEMORY; } return Curl_perform(data); }
/* * curl_easy_perform() is the external interface that performs a transfer * previously setup. */ CURLcode curl_easy_perform(CURL *curl) { struct SessionHandle *data = (struct SessionHandle *)curl; if(!data) return CURLE_BAD_FUNCTION_ARGUMENT; if ( ! (data->share && data->share->hostcache) ) { if (Curl_global_host_cache_use(data) && (data->dns.hostcachetype != HCACHE_GLOBAL)) { if (data->dns.hostcachetype == HCACHE_PRIVATE) Curl_hash_destroy(data->dns.hostcache); data->dns.hostcache = Curl_global_host_cache_get(); data->dns.hostcachetype = HCACHE_GLOBAL; } if (!data->dns.hostcache) { data->dns.hostcachetype = HCACHE_PRIVATE; data->dns.hostcache = Curl_mk_dnscache(); if(!data->dns.hostcache) /* While we possibly could survive and do good without a host cache, the fact that creating it failed indicates that things are truly screwed up and we should bail out! */ return CURLE_OUT_OF_MEMORY; } } if(!data->state.connc) { /* oops, no connection cache, make one up */ data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE); if(!data->state.connc) return CURLE_OUT_OF_MEMORY; } return Curl_perform(data); }
/* * curl_easy_duphandle() is an external interface to allow duplication of a * given input easy handle. The returned handle will be a new working handle * with all options set exactly as the input source handle. */ CURL *curl_easy_duphandle(CURL *incurl) { bool fail = TRUE; struct SessionHandle *data=(struct SessionHandle *)incurl; struct SessionHandle *outcurl = (struct SessionHandle *) calloc(sizeof(struct SessionHandle), 1); if(NULL == outcurl) return NULL; /* failure */ do { /* * We setup a few buffers we need. We should probably make them * get setup on-demand in the code, as that would probably decrease * the likeliness of us forgetting to init a buffer here in the future. */ outcurl->state.headerbuff=(char*)malloc(HEADERSIZE); if(!outcurl->state.headerbuff) { break; } outcurl->state.headersize=HEADERSIZE; /* copy all userdefined values */ outcurl->set = data->set; if(data->state.used_interface == Curl_if_multi) outcurl->state.connc = data->state.connc; else outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE); if(!outcurl->state.connc) break; outcurl->state.lastconnect = -1; outcurl->progress.flags = data->progress.flags; outcurl->progress.callback = data->progress.callback; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(data->cookies) { /* If cookies are enabled in the parent handle, we enable them in the clone as well! */ outcurl->cookies = Curl_cookie_init(data, data->cookies->filename, outcurl->cookies, data->set.cookiesession); if(!outcurl->cookies) { break; } } #endif /* CURL_DISABLE_HTTP */ /* duplicate all values in 'change' */ if(data->change.url) { outcurl->change.url = strdup(data->change.url); if(!outcurl->change.url) break; outcurl->change.url_alloc = TRUE; } if(data->change.proxy) { outcurl->change.proxy = strdup(data->change.proxy); if(!outcurl->change.proxy) break; outcurl->change.proxy_alloc = TRUE; } if(data->change.referer) { outcurl->change.referer = strdup(data->change.referer); if(!outcurl->change.referer) break; outcurl->change.referer_alloc = TRUE; } #ifdef USE_ARES /* If we use ares, we setup a new ares channel for the new handle */ if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel)) break; #endif #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_OF_NETWORK); outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, CURL_ICONV_CODESET_OF_HOST); outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_FOR_UTF8); #endif Curl_easy_initHandleData(outcurl); fail = FALSE; /* we reach this point and thus we are OK */ } while(0); if(fail) { if(outcurl) { if(outcurl->state.connc->type == CONNCACHE_PRIVATE) Curl_rm_connc(outcurl->state.connc); if(outcurl->state.headerbuff) free(outcurl->state.headerbuff); if(outcurl->change.proxy) free(outcurl->change.proxy); if(outcurl->change.url) free(outcurl->change.url); if(outcurl->change.referer) free(outcurl->change.referer); free(outcurl); /* free the memory again */ outcurl = NULL; } } return outcurl; }