threaded-ssl.c
上传用户:coffee44
上传日期:2018-10-23
资源大小:12304k
文件大小:4k
源码类别:

TAPI编程

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  *                                  _   _ ____  _
  3.  *  Project                     ___| | | |  _ | |
  4.  *                             / __| | | | |_) | |
  5.  *                            | (__| |_| |  _ <| |___
  6.  *                             ___|___/|_| ______|
  7.  *
  8.  * $Id: threaded-ssl.c,v 1.4 2008-05-22 21:20:09 danf Exp $
  9.  *
  10.  * A multi-threaded example that uses pthreads and fetches 4 remote files at
  11.  * once over HTTPS. The lock callbacks and stuff assume OpenSSL or GnuTLS
  12.  * (libgcrypt) so far.
  13.  *
  14.  * OpenSSL docs for this:
  15.  *   http://www.openssl.org/docs/crypto/threads.html
  16.  * gcrypt docs for this:
  17.  *   http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
  18.  */
  19. #define USE_OPENSSL /* or USE_GNUTLS accordingly */
  20. #include <stdio.h>
  21. #include <pthread.h>
  22. #include <curl/curl.h>
  23. #define NUMT 4
  24. /* we have this global to let the callback get easy access to it */
  25. static pthread_mutex_t *lockarray;
  26. #ifdef USE_OPENSSL
  27. #include <openssl/crypto.h>
  28. static void lock_callback(int mode, int type, char *file, int line)
  29. {
  30.   (void)file;
  31.   (void)line;
  32.   if (mode & CRYPTO_LOCK) {
  33.     pthread_mutex_lock(&(lockarray[type]));
  34.   }
  35.   else {
  36.     pthread_mutex_unlock(&(lockarray[type]));
  37.   }
  38. }
  39. static unsigned long thread_id(void)
  40. {
  41.   unsigned long ret;
  42.   ret=(unsigned long)pthread_self();
  43.   return(ret);
  44. }
  45. static void init_locks(void)
  46. {
  47.   int i;
  48.   lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
  49.                                             sizeof(pthread_mutex_t));
  50.   for (i=0; i<CRYPTO_num_locks(); i++) {
  51.     pthread_mutex_init(&(lockarray[i]),NULL);
  52.   }
  53.   CRYPTO_set_id_callback((unsigned long (*)())thread_id);
  54.   CRYPTO_set_locking_callback((void (*)())lock_callback);
  55. }
  56. static void kill_locks(void)
  57. {
  58.   int i;
  59.   CRYPTO_set_locking_callback(NULL);
  60.   for (i=0; i<CRYPTO_num_locks(); i++)
  61.     pthread_mutex_destroy(&(lockarray[i]));
  62.   OPENSSL_free(lockarray);
  63. }
  64. #endif
  65. #ifdef USE_GNUTLS
  66. #include <gcrypt.h>
  67. #include <errno.h>
  68. GCRY_THREAD_OPTION_PTHREAD_IMPL;
  69. void init_locks(void)
  70. {
  71.   gcry_control(GCRYCTL_SET_THREAD_CBS);
  72. }
  73. #define kill_locks()
  74. #endif
  75. /* List of URLs to fetch.*/
  76. const char * const urls[]= {
  77.   "https://www.sf.net/",
  78.   "https://www.openssl.org/",
  79.   "https://www.sf.net/",
  80.   "https://www.openssl.org/",
  81. };
  82. static void *pull_one_url(void *url)
  83. {
  84.   CURL *curl;
  85.   curl = curl_easy_init();
  86.   curl_easy_setopt(curl, CURLOPT_URL, url);
  87.   /* this example doesn't verify the server's certificate, which means we
  88.      might be downloading stuff from an impostor */
  89.   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
  90.   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
  91.   curl_easy_perform(curl); /* ignores error */
  92.   curl_easy_cleanup(curl);
  93.   return NULL;
  94. }
  95. int main(int argc, char **argv)
  96. {
  97.   pthread_t tid[NUMT];
  98.   int i;
  99.   int error;
  100.   (void)argc; /* we don't use any arguments in this example */
  101.   (void)argv;
  102.   /* Must initialize libcurl before any threads are started */
  103.   curl_global_init(CURL_GLOBAL_ALL);
  104.   init_locks();
  105.   for(i=0; i< NUMT; i++) {
  106.     error = pthread_create(&tid[i],
  107.                            NULL, /* default attributes please */
  108.                            pull_one_url,
  109.                            (void *)urls[i]);
  110.     if(0 != error)
  111.       fprintf(stderr, "Couldn't run thread number %d, errno %dn", i, error);
  112.     else
  113.       fprintf(stderr, "Thread %d, gets %sn", i, urls[i]);
  114.   }
  115.   /* now wait for all threads to terminate */
  116.   for(i=0; i< NUMT; i++) {
  117.     error = pthread_join(tid[i], NULL);
  118.     fprintf(stderr, "Thread %d terminatedn", i);
  119.   }
  120.   kill_locks();
  121.   return 0;
  122. }