]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_http_client_curl.cc
update sources to v12.2.5
[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
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 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 static void check_curl()
70 {
71 #ifndef HAVE_CURL_MULTI_WAIT
72 derr << "WARNING: libcurl doesn't support curl_multi_wait()" << dendl;
73 derr << "WARNING: cross zone / region transfer performance may be affected" << dendl;
74 #endif
75 }
76
77 #if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L
78 void init_ssl() {
79 ::openssl::init_ssl();
80 }
81
82 bool fe_inits_ssl(boost::optional <const fe_map_t&> m, long& curl_global_flags){
83 if (m) {
84 for (const auto& kv: *m){
85 if (kv.first == "civetweb" || kv.first == "beast"){
86 std::string cert;
87 kv.second->get_val("ssl_certificate","", &cert);
88 if (!cert.empty()){
89 /* TODO this flag is no op for curl > 7.57 */
90 curl_global_flags &= ~CURL_GLOBAL_SSL;
91 return true;
92 }
93 }
94 }
95 }
96 return false;
97 }
98 #endif // WITH_CURL_OPENSSL
99
100 std::once_flag curl_init_flag;
101
102 void setup_curl(boost::optional<const fe_map_t&> m) {
103 check_curl();
104
105 long curl_global_flags = CURL_GLOBAL_ALL;
106
107 #if defined(WITH_CURL_OPENSSL) && OPENSSL_API_COMPAT < 0x10100000L
108 if (!fe_inits_ssl(m, curl_global_flags))
109 init_ssl();
110 #endif
111
112 std::call_once(curl_init_flag, curl_global_init, curl_global_flags);
113 rgw_setup_saved_curl_handles();
114 }
115
116 void cleanup_curl() {
117 rgw_release_all_curl_handles();
118 curl_global_cleanup();
119 }
120
121 } /* namespace curl */
122 } /* namespace rgw */