Ejemplo n.º 1
0
ResourceHandleManager::~ResourceHandleManager()
{
    curl_multi_cleanup(m_curlMultiHandle);
    curl_share_cleanup(m_curlShareHandle);
    if (m_cookieJarFileName)
        free(m_cookieJarFileName);
}
Ejemplo n.º 2
0
static void
util_share_close(CurlShareObject *self){
    if (self->share_handle != NULL) {
        CURLSH *share_handle = self->share_handle;
        self->share_handle = NULL;
        curl_share_cleanup(share_handle);
    }
}
Ejemplo n.º 3
0
static int lcurl_share_cleanup(lua_State *L){
  lcurl_share_t *p = lcurl_getshare(L);
  if(p->curl){
    curl_share_cleanup(p->curl);
    p->curl = NULL;
  }

  return 0;
}
Ejemplo n.º 4
0
void _php_curl_share_close(zend_resource *rsrc) /* {{{ */
{
	php_curlsh *sh = (php_curlsh *)rsrc->ptr;
	if (sh) {
		curl_share_cleanup(sh->share);
		efree(sh);
		rsrc->ptr = NULL;
	}
}
Ejemplo n.º 5
0
int l_share_gc(lua_State *L) {
  /* gc resources */
  l_share_userdata *privp = lua_touserdata(L, 1);
  CURLSH *curlsh = privp->curlsh;
  CURLSHcode  errornum;
  if ((errornum = curl_share_cleanup(curlsh)) != CURLSHE_OK)
    luaL_error(L, "%s", curl_share_strerror(errornum));

  return 0;
}
Ejemplo n.º 6
0
int FetcherManager::stop() {
    int ret = Manager::stop();

    while(!canstoped()) {
        my_sleep(500000); //0.5 seconds
    }

    curl_share_cleanup(sh);
    curl_global_cleanup();
    return ret;
}
HTTPCURLContext::~HTTPCURLContext() {
    while (!handles.empty()) {
        curl_easy_cleanup(handles.front());
        handles.pop();
    }

    curl_multi_cleanup(multi);
    multi = nullptr;

    curl_share_cleanup(share);
    share = nullptr;

    uv_timer_stop(timeout);
    uv::close(timeout);
}
	void stop() {
		{
			std::list<Request *>::iterator e = queue.end();
			std::list<Request *>::iterator i = queue.begin();
			for( ; i != e; i++ ) {
				(*i)->cancel();
			}
		}
		while( active_requests() ) {
			step();
			s3eDeviceYield(0);
		}
		curl_multi_cleanup(curlm);
		curlm = 0;
		curl_share_cleanup(curlsh);
		curlsh = 0;
	}
Ejemplo n.º 9
0
/** 
 * clean up input/output module
 **/
void
lm_uninit_io(io_t *io)
{
    if (!io->synchronous) {
        if (io->multi_h)
            curl_multi_cleanup(io->multi_h);
        if (io->share_h)
            curl_share_cleanup(io->share_h);
        if (io->queue.pos)
            free(io->queue.pos);

        pthread_mutex_destroy(&io->queue_mtx);
        pthread_rwlock_destroy(&io->cookies_mtx);
        pthread_rwlock_destroy(&io->dns_mtx);
        pthread_rwlock_destroy(&io->share_mtx);

        close(io->msg_fd[0]);
        close(io->msg_fd[1]);
    }
}
Ejemplo n.º 10
0
CurlFtp::~CurlFtp()
{
    if (this->curl != NULL) {
        curl_easy_cleanup(this->curl);
        this->curl = NULL;
    }
    if (this->shareHandle != NULL) {
        curl_share_cleanup(this->shareHandle);
        this->shareHandle = NULL;
    }

    Q_ASSERT(::curl_global_inited >= 0);
    ::curl_global_init_mutex.lock();
    ::curl_global_inited -= 1;
    if (::curl_global_inited == 0) {
        curl_global_cleanup();
        qDebug()<<"Cleanup curl global, not use ref now.";
    }
    ::curl_global_init_mutex.unlock();
}
Ejemplo n.º 11
0
static void ov_http_client_free(void* vptr) {
    ov_http_client_object* ptr;

    /* Get the pointer to the object: */
    ptr = vptr;

    /* Release the resources used by libcurl: */
    if (ptr->handle != NULL) {
        curl_multi_cleanup(ptr->handle);
        curl_share_cleanup(ptr->share);
        ptr->handle = NULL;
    }

    /* Free the strings: */
    ov_string_free(ptr->ca_file);
    ov_string_free(ptr->proxy_url);
    ov_string_free(ptr->proxy_username);
    ov_string_free(ptr->proxy_password);
    ov_string_free(ptr->cookies);

    /* Free this object: */
    xfree(ptr);
}
Ejemplo n.º 12
0
Archivo: lib506.c Proyecto: 2px/curl
/* test function */
int test(char *URL)
{
  int res;
  CURLSHcode scode = CURLSHE_OK;
  CURLcode code = CURLE_OK;
  char *url = NULL;
  struct Tdata tdata;
  CURL *curl;
  CURLSH *share;
  struct curl_slist *headers = NULL;
  struct curl_slist *cookies = NULL;
  struct curl_slist *next_cookie = NULL;
  int i;
  struct userdata user;

  user.text = (char *)"Pigs in space";
  user.counter = 0;

  printf("GLOBAL_INIT\n");
  if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  /* prepare share */
  printf("SHARE_INIT\n");
  if((share = curl_share_init()) == NULL) {
    fprintf(stderr, "curl_share_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if(CURLSHE_OK == scode) {
    printf("CURLSHOPT_LOCKFUNC\n");
    scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, my_lock);
  }
  if(CURLSHE_OK == scode) {
    printf("CURLSHOPT_UNLOCKFUNC\n");
    scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, my_unlock);
  }
  if(CURLSHE_OK == scode) {
    printf("CURLSHOPT_USERDATA\n");
    scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user);
  }
  if(CURLSHE_OK == scode) {
    printf("CURL_LOCK_DATA_COOKIE\n");
    scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
  }
  if(CURLSHE_OK == scode) {
    printf("CURL_LOCK_DATA_DNS\n");
    scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
  }

  if(CURLSHE_OK != scode) {
    fprintf(stderr, "curl_share_setopt() failed\n");
    curl_share_cleanup(share);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  /* initial cookie manipulation */
  if((curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_share_cleanup(share);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }
  printf("CURLOPT_SHARE\n");
  test_setopt(curl, CURLOPT_SHARE,      share);
  printf("CURLOPT_COOKIELIST injected_and_clobbered\n");
  test_setopt(curl, CURLOPT_COOKIELIST,
               "Set-Cookie: injected_and_clobbered=yes; "
               "domain=host.foo.com; expires=Sat Feb 2 11:56:27 GMT 2030");
  printf("CURLOPT_COOKIELIST ALL\n");
  test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
  printf("CURLOPT_COOKIELIST session\n");
  test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: session=elephants");
  printf("CURLOPT_COOKIELIST injected\n");
  test_setopt(curl, CURLOPT_COOKIELIST,
               "Set-Cookie: injected=yes; domain=host.foo.com; "
               "expires=Sat Feb 2 11:56:27 GMT 2030");
  printf("CURLOPT_COOKIELIST SESS\n");
  test_setopt(curl, CURLOPT_COOKIELIST, "SESS");
  printf("CLEANUP\n");
  curl_easy_cleanup(curl);


  res = 0;

  /* start treads */
  for(i=1; i<=THREADS; i++) {

    /* set thread data */
    tdata.url   = suburl(URL, i); /* must be curl_free()d */
    tdata.share = share;

    /* simulate thread, direct call of "thread" function */
    printf("*** run %d\n",i);
    fire(&tdata);

    curl_free(tdata.url);
  }


  /* fetch a another one and save cookies */
  printf("*** run %d\n", i);
  if((curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_share_cleanup(share);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  url = suburl(URL, i);
  headers = sethost(NULL);
  test_setopt(curl, CURLOPT_HTTPHEADER, headers);
  test_setopt(curl, CURLOPT_URL,        url);
  printf("CURLOPT_SHARE\n");
  test_setopt(curl, CURLOPT_SHARE,      share);
  printf("CURLOPT_COOKIEJAR\n");
  test_setopt(curl, CURLOPT_COOKIEJAR,  JAR);
  printf("CURLOPT_COOKIELIST FLUSH\n");
  test_setopt(curl, CURLOPT_COOKIELIST, "FLUSH");

  printf("PERFORM\n");
  curl_easy_perform(curl);

  printf("CLEANUP\n");
  curl_easy_cleanup(curl);
  curl_free(url);
  curl_slist_free_all(headers);

  /* load cookies */
  if((curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_share_cleanup(share);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }
  url = suburl(URL, i);
  headers = sethost(NULL);
  test_setopt(curl, CURLOPT_HTTPHEADER, headers);
  test_setopt(curl, CURLOPT_URL,        url);
  printf("CURLOPT_SHARE\n");
  test_setopt(curl, CURLOPT_SHARE,      share);
  printf("CURLOPT_COOKIELIST ALL\n");
  test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
  printf("CURLOPT_COOKIEJAR\n");
  test_setopt(curl, CURLOPT_COOKIEFILE, JAR);
  printf("CURLOPT_COOKIELIST RELOAD\n");
  test_setopt(curl, CURLOPT_COOKIELIST, "RELOAD");

  code = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
  if(code != CURLE_OK) {
    fprintf(stderr, "curl_easy_getinfo() failed\n");
    res = TEST_ERR_MAJOR_BAD;
    goto test_cleanup;
  }
  printf("loaded cookies:\n");
  if(!cookies) {
    fprintf(stderr, "  reloading cookies from '%s' failed\n", JAR);
    res = TEST_ERR_MAJOR_BAD;
    goto test_cleanup;
  }
  printf("-----------------\n");
  next_cookie = cookies;
  while(next_cookie) {
    printf("  %s\n", next_cookie->data);
    next_cookie = next_cookie->next;
  }
  printf("-----------------\n");
  curl_slist_free_all(cookies);

  /* try to free share, expect to fail because share is in use*/
  printf("try SHARE_CLEANUP...\n");
  scode = curl_share_cleanup(share);
  if(scode==CURLSHE_OK) {
    fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
    share = NULL;
  }
  else {
    printf("SHARE_CLEANUP failed, correct\n");
  }

test_cleanup:

  /* clean up last handle */
  printf("CLEANUP\n");
  curl_easy_cleanup(curl);
  curl_slist_free_all(headers);
  curl_free(url);

  /* free share */
  printf("SHARE_CLEANUP\n");
  scode = curl_share_cleanup(share);
  if(scode!=CURLSHE_OK)
    fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
            (int)scode);

  printf("GLOBAL_CLEANUP\n");
  curl_global_cleanup();

  return res;
}
Ejemplo n.º 13
0
/* test function */
int test(char *URL)
{
  int res;
  CURLSHcode scode = CURLSHE_OK;
  char *url;
  struct Tdata tdata;
  CURL *curl;
  CURLSH *share;
  int i;
  struct userdata user;

  user.text = (char *)"Pigs in space";
  user.counter = 0;

  printf( "GLOBAL_INIT\n" );
  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  /* prepare share */
  printf( "SHARE_INIT\n" );
  if ((share = curl_share_init()) == NULL) {
    fprintf(stderr, "curl_share_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ( CURLSHE_OK == scode ) {
    printf( "CURLSHOPT_LOCKFUNC\n" );
    scode = curl_share_setopt( share, CURLSHOPT_LOCKFUNC, my_lock);
  }
  if ( CURLSHE_OK == scode ) {
    printf( "CURLSHOPT_UNLOCKFUNC\n" );
    scode = curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, my_unlock);
  }
  if ( CURLSHE_OK == scode ) {
    printf( "CURLSHOPT_USERDATA\n" );
    scode = curl_share_setopt( share, CURLSHOPT_USERDATA, &user);
  }
  if ( CURLSHE_OK == scode ) {
    printf( "CURL_LOCK_DATA_SSL_SESSION\n" );
    scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
  }

  if ( CURLSHE_OK != scode ) {
    fprintf(stderr, "curl_share_setopt() failed\n");
    curl_share_cleanup(share);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }


  res = 0;

  /* start treads */
  for (i=1; i<=THREADS; i++ ) {

    /* set thread data */
    tdata.url   = URL;
    tdata.share = share;

    /* simulate thread, direct call of "thread" function */
    printf( "*** run %d\n",i );
    fire( &tdata );
  }


  /* fetch a another one */
  printf( "*** run %d\n", i );
  if ((curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_share_cleanup(share);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  url = URL;
  test_setopt( curl, CURLOPT_URL,        url );
  printf( "CURLOPT_SHARE\n" );
  test_setopt( curl, CURLOPT_SHARE,      share );

  printf( "PERFORM\n" );
  curl_easy_perform( curl );

  /* try to free share, expect to fail because share is in use*/
  printf( "try SHARE_CLEANUP...\n" );
  scode = curl_share_cleanup( share );
  if ( scode==CURLSHE_OK )
  {
    fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
    share = NULL;
  } else {
    printf( "SHARE_CLEANUP failed, correct\n" );
  }

test_cleanup:

  /* clean up last handle */
  printf( "CLEANUP\n" );
  curl_easy_cleanup( curl );

  /* free share */
  printf( "SHARE_CLEANUP\n" );
  scode = curl_share_cleanup( share );
  if ( scode!=CURLSHE_OK )
    fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
            (int)scode);

  printf( "GLOBAL_CLEANUP\n" );
  curl_global_cleanup();

  return res;
}
Ejemplo n.º 14
0
QuviMedia::~QuviMedia() {
	curl_easy_setopt(m_curl, CURLOPT_SHARE, nullptr);
	m_backends.clear();
	curl_share_cleanup(m_curlsh);
}
Ejemplo n.º 15
0
void adns::RemoveShareHndl() {
	if (sharehndl) {
		curl_share_cleanup(sharehndl);
		sharehndl = 0;
	}
}
Ejemplo n.º 16
0
static void handler (zsock_t *pipe, void *args) {
    curl_global_init(CURL_GLOBAL_ALL);
    CURLM *multi = curl_multi_init ();
    CURLSH *share = curl_share_init ();
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);

    long verbose = (*(bool *) args) ? 1L : 0L;
    long timeout = 30;
    CURLMcode code;

    SOCKET pipefd = zsock_fd (pipe);
    struct curl_waitfd waitfd = {pipefd, CURL_WAIT_POLLIN};

    //  List to hold pending curl handles, in case we are destroy the client
    //  while request are inprogress
    zlistx_t *pending_handles = zlistx_new ();
    zlistx_set_destructor (pending_handles, (zlistx_destructor_fn *) curl_destructor);

    zsock_signal (pipe, 0);

    bool terminated = false;
    while (!terminated) {
        int events = zsock_events (pipe);
        if ((events & ZMQ_POLLIN) == 0) {
            code = curl_multi_wait (multi, &waitfd, 1, 1000, NULL);
            assert (code == CURLM_OK);
        }

        events = zsock_events (pipe);
        if (events & ZMQ_POLLIN) {
            char* command = zstr_recv (pipe);
            if (!command)
                break;          //  Interrupted

            //  All actors must handle $TERM in this way
            if (streq (command, "$TERM"))
                terminated = true;
            else if (streq (command, "GET")) {
                char *url;
                zlistx_t *headers;
                void *userp;
                int rc = zsock_recv (pipe, "slp", &url, &headers, &userp);
                assert (rc == 0);

                zchunk_t *data = zchunk_new (NULL, 100);
                assert (data);
                struct curl_slist *curl_headers = zlistx_to_slist (headers);
                CURL *curl = curl_easy_init ();
                zlistx_add_end (pending_handles, curl);
                http_request *request = (http_request *) zmalloc (sizeof (http_request));
                assert (request);
                request->userp = userp;
                request->curl = curl;
                request->data = data;
                request->headers = curl_headers;

                curl_easy_setopt (curl, CURLOPT_SHARE, share);
                curl_easy_setopt (curl, CURLOPT_TIMEOUT, timeout);
                curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose);
                curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers);
                curl_easy_setopt (curl, CURLOPT_URL, url);
                curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
                curl_easy_setopt (curl, CURLOPT_WRITEDATA, data);
                curl_easy_setopt (curl, CURLOPT_PRIVATE, request);

                code = curl_multi_add_handle (multi, curl);
                assert (code == CURLM_OK);
                zlistx_destroy (&headers);
                zstr_free (&url);
           }
           else {
               puts ("E: invalid message to actor");
               assert (false);
           }
           zstr_free (&command);
        }

        int still_running;
        code = curl_multi_perform (multi, &still_running);
        assert (code == CURLM_OK);

        int msgq = 0;
        struct CURLMsg *msg = curl_multi_info_read(multi, &msgq);

        while (msg) {
            if(msg->msg == CURLMSG_DONE) {
                CURL *curl = msg->easy_handle;
                http_request *request;
                curl_easy_getinfo(curl, CURLINFO_PRIVATE, &request);

                long response_code_long;
                curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code_long);
                int response_code = (int)response_code_long;

                int rc = zsock_send (pipe, "icp", response_code, request->data, request->userp);
                assert (rc == 0);

                curl_multi_remove_handle (multi, curl);

                //  Remove curl from the pending handles and delete it
                void *handle = zlistx_find (pending_handles, curl);
                assert (handle);
                rc = zlistx_delete (pending_handles, handle);
                assert (rc == 0);
            }

            msg = curl_multi_info_read(multi, &msgq);
        }
    }

    zlistx_destroy (&pending_handles);
    curl_share_cleanup (share);
    curl_multi_cleanup (multi);
    curl_global_cleanup ();
}
Ejemplo n.º 17
0
int test(char *URL)
{
  CURLM *cm = NULL;
  CURLSH *sh = NULL;
  CURL *ch = NULL;
  int unfinished;

  cm = curl_multi_init();
  if(!cm)
    return 1;
  sh = curl_share_init();
  if(!sh)
    goto cleanup;

  curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
  curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);

  ch = curl_easy_init();
  if(!ch)
    goto cleanup;

  curl_easy_setopt(ch, CURLOPT_SHARE, sh);
  curl_easy_setopt(ch, CURLOPT_URL, URL);
  curl_easy_setopt(ch, CURLOPT_COOKIEFILE, "log/cookies1905");
  curl_easy_setopt(ch, CURLOPT_COOKIEJAR, "log/cookies1905");

  curl_multi_add_handle(cm, ch);

  unfinished = 1;
  while(unfinished) {
    int MAX = 0;
    long max_tout;
    fd_set R, W, E;
    struct timeval timeout;

    FD_ZERO(&R);
    FD_ZERO(&W);
    FD_ZERO(&E);
    curl_multi_perform(cm, &unfinished);

    curl_multi_fdset(cm, &R, &W, &E, &MAX);
    curl_multi_timeout(cm, &max_tout);

    if(max_tout > 0) {
      timeout.tv_sec = max_tout / 1000;
      timeout.tv_usec = (max_tout % 1000) * 1000;
    }
    else {
      timeout.tv_sec = 0;
      timeout.tv_usec = 1000;
    }

    select(MAX + 1, &R, &W, &E, &timeout);
  }

  curl_easy_setopt(ch, CURLOPT_COOKIELIST, "FLUSH");
  curl_easy_setopt(ch, CURLOPT_SHARE, NULL);

  curl_multi_remove_handle(cm, ch);
  cleanup:
  curl_easy_cleanup(ch);
  curl_share_cleanup(sh);
  curl_multi_cleanup(cm);

  return 0;
}
Ejemplo n.º 18
0
/**
 * @brief   Called when closing the shared curl data structure
 *
 * @return  none
 **/
void libhttpcomm_curlShareClose(CURLSH *curHandle)
{
    curl_share_cleanup(curHandle);
}
Ejemplo n.º 19
0
/* test function */
int test(char *URL)
{
  int res;
  CURLSHcode scode;
  char *url;
  struct Tdata tdata;
  CURL *curl;
  CURLSH *share;
  struct curl_slist *headers;
  int i;
  struct userdata user;

  user.text = (char *)"Pigs in space";
  user.counter = 0;
  
  printf( "GLOBAL_INIT\n" );
  curl_global_init( CURL_GLOBAL_ALL );

  /* prepare share */
  printf( "SHARE_INIT\n" );
  share = curl_share_init();
  curl_share_setopt( share, CURLSHOPT_LOCKFUNC,   lock);
  curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, unlock);
  curl_share_setopt( share, CURLSHOPT_USERDATA,   &user);
  printf( "CURL_LOCK_DATA_COOKIE\n" );
  curl_share_setopt( share, CURLSHOPT_SHARE,      CURL_LOCK_DATA_COOKIE);
  printf( "CURL_LOCK_DATA_DNS\n" );
  curl_share_setopt( share, CURLSHOPT_SHARE,      CURL_LOCK_DATA_DNS);
  
  res = 0;

  /* start treads */
  for (i=1; i<=THREADS; i++ ) {
    
    /* set thread data */
    tdata.url   = suburl( URL, i ); /* must be freed */
    tdata.share = share;

    /* simulate thread, direct call of "thread" function */
    printf( "*** run %d\n",i );
    fire( &tdata );

    free( tdata.url );

  }


  /* fetch a another one and save cookies */
  printf( "*** run %d\n", i );
  curl = curl_easy_init();

  url = suburl( URL, i );
  headers = sethost( NULL );
  curl_easy_setopt( curl, CURLOPT_HTTPHEADER, (void*)headers );
  curl_easy_setopt( curl, CURLOPT_URL,        url );
  printf( "CURLOPT_SHARE\n" );
  curl_easy_setopt( curl, CURLOPT_SHARE,      share );
  printf( "CURLOPT_COOKIEJAR\n" );
  curl_easy_setopt( curl, CURLOPT_COOKIEJAR,  JAR );

  printf( "PERFORM\n" );
  curl_easy_perform( curl );

  /* try to free share, expect to fail because share is in use*/
  printf( "try SHARE_CLEANUP...\n" );
  scode = curl_share_cleanup( share );
  if ( scode==CURLSHE_OK )
  {
    fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
    share = NULL;
  } else {
    printf( "SHARE_CLEANUP failed, correct\n" );
  }

  /* clean up last handle */
  printf( "CLEANUP\n" );
  curl_easy_cleanup( curl );
  curl_slist_free_all( headers );
  free(url);
  
  
  /* free share */
  printf( "SHARE_CLEANUP\n" );
  scode = curl_share_cleanup( share );
  if ( scode!=CURLSHE_OK )
  {
    fprintf(stderr, "curl_share_cleanup failed, code errno %d\n", scode);
  }
  
  printf( "GLOBAL_CLEANUP\n" );
  curl_global_cleanup();
 
  return res;
}
BCResourceHandleManagerCURL::~BCResourceHandleManagerCURL()
{
    curl_share_cleanup(m_curlShareHandle);
    curl_multi_cleanup(m_curlMultiHandle);
}