]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_http_client_curl.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rgw / rgw_http_client_curl.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #include "rgw_http_client_curl.h"
5 #include <mutex>
6 #include <vector>
7 #include <curl/curl.h>
8
9 #include "rgw_common.h"
10 #define dout_context g_ceph_context
11 #define dout_subsys ceph_subsys_rgw
12
13 #ifdef WITH_CURL_OPENSSL
14 #include <openssl/crypto.h>
15 #endif
16
17 #if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L
18 namespace openssl {
19
20 class RGWSSLSetup
21 {
22 std::vector <std::mutex> locks;
23 public:
24 explicit RGWSSLSetup(int n) : locks (n){}
25
26 void set_lock(int id){
27 try {
28 locks.at(id).lock();
29 } catch (std::out_of_range& e) {
30 dout(0) << __func__ << " failed to set locks" << dendl;
31 }
32 }
33
34 void clear_lock(int id){
35 try {
36 locks.at(id).unlock();
37 } catch (std::out_of_range& e) {
38 dout(0) << __func__ << " failed to unlock" << dendl;
39 }
40 }
41 };
42
43
44 void rgw_ssl_locking_callback(int mode, int id, const char *file, int line)
45 {
46 static RGWSSLSetup locks(CRYPTO_num_locks());
47 if (mode & CRYPTO_LOCK)
48 locks.set_lock(id);
49 else
50 locks.clear_lock(id);
51 }
52
53 unsigned long rgw_ssl_thread_id_callback(){
54 return (unsigned long)pthread_self();
55 }
56
57 void init_ssl(){
58 CRYPTO_set_id_callback((unsigned long (*) ()) rgw_ssl_thread_id_callback);
59 CRYPTO_set_locking_callback(rgw_ssl_locking_callback);
60 }
61
62 } /* namespace openssl */
63 #endif // WITH_CURL_OPENSSL
64
65
66 namespace rgw {
67 namespace curl {
68
69 #if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L
70 void init_ssl() {
71 ::openssl::init_ssl();
72 }
73
74 bool fe_inits_ssl(boost::optional <const fe_map_t&> m, long& curl_global_flags){
75 if (m) {
76 for (const auto& kv: *m){
77 if (kv.first == "beast"){
78 std::string cert;
79 kv.second->get_val("ssl_certificate","", &cert);
80 if (!cert.empty()){
81 /* TODO this flag is no op for curl > 7.57 */
82 curl_global_flags &= ~CURL_GLOBAL_SSL;
83 return true;
84 }
85 }
86 }
87 }
88 return false;
89 }
90 #endif // WITH_CURL_OPENSSL
91
92 std::once_flag curl_init_flag;
93
94 void setup_curl(boost::optional<const fe_map_t&> m) {
95 long curl_global_flags = CURL_GLOBAL_ALL;
96
97 #if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L
98 if (!fe_inits_ssl(m, curl_global_flags))
99 init_ssl();
100 #endif
101
102 std::call_once(curl_init_flag, curl_global_init, curl_global_flags);
103 rgw_setup_saved_curl_handles();
104 }
105
106 void cleanup_curl() {
107 rgw_release_all_curl_handles();
108 curl_global_cleanup();
109 }
110
111 } /* namespace curl */
112 } /* namespace rgw */