/* * 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.conn_cache) { /* Oops, no connection cache, create one */ data->state.conn_cache = Curl_conncache_init(CONNCACHE_PRIVATE); if(!data->state.conn_cache) return CURLE_OUT_OF_MEMORY; } return Curl_perform(data); }
CURLSHcode curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...) { va_list param; int type; curl_lock_function lockfunc; curl_unlock_function unlockfunc; void *ptr; CURLSHcode res = CURLSHE_OK; if(share->dirty) /* don't allow setting options while one or more handles are already using this share */ return CURLSHE_IN_USE; va_start(param, option); switch(option) { case CURLSHOPT_SHARE: /* this is a type this share will share */ type = va_arg(param, int); share->specifier |= (1<<type); switch(type) { case CURL_LOCK_DATA_DNS: break; case CURL_LOCK_DATA_COOKIE: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(!share->cookies) { share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE); if(!share->cookies) res = CURLSHE_NOMEM; } #else /* CURL_DISABLE_HTTP */ res = CURLSHE_NOT_BUILT_IN; #endif break; case CURL_LOCK_DATA_SSL_SESSION: #ifdef USE_SSL if(!share->sslsession) { share->max_ssl_sessions = 8; share->sslsession = calloc(share->max_ssl_sessions, sizeof(struct curl_ssl_session)); share->sessionage = 0; if(!share->sslsession) res = CURLSHE_NOMEM; } #else res = CURLSHE_NOT_BUILT_IN; #endif break; case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */ if(Curl_conncache_init(&share->conn_cache, 103)) res = CURLSHE_NOMEM; break; default: res = CURLSHE_BAD_OPTION; } break; case CURLSHOPT_UNSHARE: /* this is a type this share will no longer share */ type = va_arg(param, int); share->specifier &= ~(1<<type); switch(type) { case CURL_LOCK_DATA_DNS: break; case CURL_LOCK_DATA_COOKIE: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(share->cookies) { Curl_cookie_cleanup(share->cookies); share->cookies = NULL; } #else /* CURL_DISABLE_HTTP */ res = CURLSHE_NOT_BUILT_IN; #endif break; case CURL_LOCK_DATA_SSL_SESSION: #ifdef USE_SSL Curl_safefree(share->sslsession); #else res = CURLSHE_NOT_BUILT_IN; #endif break; case CURL_LOCK_DATA_CONNECT: break; default: res = CURLSHE_BAD_OPTION; break; } break; case CURLSHOPT_LOCKFUNC: lockfunc = va_arg(param, curl_lock_function); share->lockfunc = lockfunc; break; case CURLSHOPT_UNLOCKFUNC: unlockfunc = va_arg(param, curl_unlock_function); share->unlockfunc = unlockfunc; break; case CURLSHOPT_USERDATA: ptr = va_arg(param, void *); share->clientdata = ptr; break; default: res = CURLSHE_BAD_OPTION; break; } va_end(param); return res; }