threaded-ssl.c (3266B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 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 https://curl.se/docs/copyright.html. 13 * 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. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 /* <DESC> 25 * Show the required mutex callback setups for GnuTLS and OpenSSL when using 26 * libcurl multi-threaded. 27 * </DESC> 28 */ 29 /* A multi-threaded example that uses pthreads and fetches 4 remote files at 30 * once over HTTPS. 31 * 32 * Recent versions of OpenSSL and GnuTLS are thread safe by design, assuming 33 * support for the underlying OS threading API is built-in. Older revisions 34 * of this example demonstrated locking callbacks for the SSL library, which 35 * are no longer necessary. An older revision with callbacks can be found at 36 * https://github.com/curl/curl/blob/curl-7_88_1/docs/examples/threaded-ssl.c 37 */ 38 39 #define USE_OPENSSL /* or USE_GNUTLS accordingly */ 40 41 #include <stdio.h> 42 #include <pthread.h> 43 #include <curl/curl.h> 44 45 #define NUMT 4 46 47 /* List of URLs to fetch.*/ 48 static const char * const urls[]= { 49 "https://www.example.com/", 50 "https://www2.example.com/", 51 "https://www3.example.com/", 52 "https://www4.example.com/", 53 }; 54 55 static void *pull_one_url(void *url) 56 { 57 CURL *curl; 58 59 curl = curl_easy_init(); 60 curl_easy_setopt(curl, CURLOPT_URL, url); 61 /* this example does not verify the server's certificate, which means we 62 might be downloading stuff from an impostor */ 63 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 64 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 65 curl_easy_perform(curl); /* ignores error */ 66 curl_easy_cleanup(curl); 67 68 return NULL; 69 } 70 71 int main(int argc, char **argv) 72 { 73 pthread_t tid[NUMT]; 74 int i; 75 (void)argc; /* we do not use any arguments in this example */ 76 (void)argv; 77 78 /* Must initialize libcurl before any threads are started */ 79 curl_global_init(CURL_GLOBAL_ALL); 80 81 for(i = 0; i < NUMT; i++) { 82 int error = pthread_create(&tid[i], 83 NULL, /* default attributes please */ 84 pull_one_url, 85 (void *)urls[i]); 86 if(0 != error) 87 fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); 88 else 89 fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); 90 } 91 92 /* now wait for all threads to terminate */ 93 for(i = 0; i < NUMT; i++) { 94 pthread_join(tid[i], NULL); 95 fprintf(stderr, "Thread %d terminated\n", i); 96 } 97 98 return 0; 99 }