bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
CurlHandlePool.h
1// -*- mode: c++; c-basic-offset:4 -*-
2
3// This file is part of the BES
4
5// Copyright (c) 2018 OPeNDAP, Inc.
6// Author: James Gallagher<jgallagher@opendap.org>
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11// version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21//
22// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
23
24#ifndef _HandlePool_h
25#define _HandlePool_h 1
26
27#include <memory>
28#include <string>
29#include <vector>
30#include <mutex>
31
32#include <curl/curl.h>
33
34#include "url_impl.h"
35
36namespace dmrpp {
37
38class Chunk;
39
48 bool d_in_use = false;
49 std::shared_ptr<http::url> d_url;
50 Chunk *d_chunk = nullptr;
51 std::vector<char> d_errbuf = std::vector<char>(CURL_ERROR_SIZE, '\0');
52
53 CURL *d_handle = nullptr;
54 curl_slist *d_request_headers = nullptr;
55
56 friend class CurlHandlePool;
57
58public:
60
62
63 void read_data();
64};
65
78class CurlHandlePool {
79private:
80 std::string d_cookies_filename;
81 std::string d_hyrax_user_agent;
82 unsigned long d_max_redirects = 3;
83 std::string d_netrc_file;
84
85 CURLSH *d_share = nullptr;
86
87 static std::recursive_mutex d_share_mutex;
88
89 static std::recursive_mutex d_cookie_mutex;
90 static std::recursive_mutex d_dns_mutex;
91 static std::recursive_mutex d_ssl_session_mutex;
92 static std::recursive_mutex d_connect_mutex;
93
94 static std::recursive_mutex d_mutex; // Use this for the default case.
95
96 static void lock_cb(CURL */*handle*/, curl_lock_data data, curl_lock_access /*access*/, void */*userptr*/) {
97 switch (data) {
98 case CURL_LOCK_DATA_SHARE: // CURL_LOCK_DATA_SHARE is used internally
99 d_share_mutex.lock();
100 break;
101
102 case CURL_LOCK_DATA_COOKIE:
103 d_cookie_mutex.lock();
104 break;
105
106 case CURL_LOCK_DATA_DNS:
107 d_dns_mutex.lock();
108 break;
109 case CURL_LOCK_DATA_SSL_SESSION:
110 d_ssl_session_mutex.lock();
111 break;
112 case CURL_LOCK_DATA_CONNECT:
113 d_connect_mutex.lock();
114 break;
115 default:
116 d_mutex.lock();
117 break;
118 }
119 }
120
121 static void unlock_cb(CURL */*handle*/, curl_lock_data data, void * /*userptr*/) {
122 switch (data) {
123 case CURL_LOCK_DATA_SHARE: // CURL_LOCK_DATA_SHARE is used internally
124 d_share_mutex.unlock();
125 break;
126
127 case CURL_LOCK_DATA_COOKIE:
128 d_cookie_mutex.unlock();
129 break;
130
131 case CURL_LOCK_DATA_DNS:
132 d_dns_mutex.unlock();
133 break;
134 case CURL_LOCK_DATA_SSL_SESSION:
135 d_ssl_session_mutex.unlock();
136 break;
137 case CURL_LOCK_DATA_CONNECT:
138 d_connect_mutex.unlock();
139 break;
140 default:
141 d_mutex.unlock();
142 break;
143 }
144 }
145
146public:
147 CurlHandlePool() = default;
148 ~CurlHandlePool();
149
150 void initialize();
152
153 static void release_handle(dmrpp_easy_handle *h);
154};
155
156} // namespace dmrpp
157
158#endif // _HandlePool_h
static void release_handle(dmrpp_easy_handle *h)
dmrpp_easy_handle * get_easy_handle(Chunk *chunk)
Bundle a libcurl easy handle with other information.
void read_data()
This is the read_data() method for all transfers.
dmrpp_easy_handle()
Build a string with hex info about stuff libcurl gets.