1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RGW_HTTP_CLIENT_H
5 #define CEPH_RGW_HTTP_CLIENT_H
7 #include "common/RWLock.h"
8 #include "common/Cond.h"
9 #include "rgw_common.h"
10 #include "rgw_string.h"
14 using param_pair_t
= pair
<string
, string
>;
15 using param_vec_t
= vector
<param_pair_t
>;
17 struct rgw_http_req_data
;
21 friend class RGWHTTPManager
;
24 bufferlist::iterator send_iter
;
29 rgw_http_req_data
*req_data
;
35 bool verify_ssl
; // Do not validate self signed certificates, default to false
37 std::atomic
<unsigned> stopped
{ 0 };
43 int init_request(const char *method
,
45 rgw_http_req_data
*req_data
);
47 virtual int receive_header(void *ptr
, size_t len
) {
50 virtual int receive_data(void *ptr
, size_t len
) {
53 virtual int send_data(void *ptr
, size_t len
) {
57 /* Callbacks for libcurl. */
58 static size_t simple_receive_http_header(void *ptr
,
62 static size_t receive_http_header(void *ptr
,
67 static size_t simple_receive_http_data(void *ptr
,
71 static size_t receive_http_data(void *ptr
,
76 static size_t simple_send_http_data(void *ptr
,
80 static size_t send_http_data(void *ptr
,
85 static const long HTTP_STATUS_NOSTATUS
= 0;
86 static const long HTTP_STATUS_UNAUTHORIZED
= 401;
87 static const long HTTP_STATUS_NOTFOUND
= 404;
89 virtual ~RGWHTTPClient();
90 explicit RGWHTTPClient(CephContext
*cct
)
93 http_status(HTTP_STATUS_NOSTATUS
),
100 void set_user_info(void *info
) {
104 void *get_user_info() {
108 void append_header(const string
& name
, const string
& val
) {
109 headers
.push_back(pair
<string
, string
>(name
, val
));
112 void set_send_length(size_t len
) {
118 long get_http_status() const {
122 void set_verify_ssl(bool flag
) {
126 int process(const char *method
, const char *url
);
127 int process(const char *url
) { return process("GET", url
); }
130 rgw_http_req_data
*get_req_data() { return req_data
; }
134 int get_req_retcode();
138 class RGWHTTPHeadersCollector
: public RGWHTTPClient
{
140 typedef std::string header_name_t
;
141 typedef std::string header_value_t
;
142 typedef std::set
<header_name_t
, ltstr_nocase
> header_spec_t
;
144 RGWHTTPHeadersCollector(CephContext
* const cct
,
145 const header_spec_t relevant_headers
)
146 : RGWHTTPClient(cct
),
147 relevant_headers(relevant_headers
) {
150 std::map
<header_name_t
, header_value_t
, ltstr_nocase
> get_headers() const {
151 return found_headers
;
154 /* Throws std::out_of_range */
155 const header_value_t
& get_header_value(const header_name_t
& name
) const {
156 return found_headers
.at(name
);
160 int receive_header(void *ptr
, size_t len
) override
;
162 int receive_data(void *ptr
, size_t len
) override
{
166 int send_data(void *ptr
, size_t len
) override
{
171 const std::set
<header_name_t
, ltstr_nocase
> relevant_headers
;
172 std::map
<header_name_t
, header_value_t
, ltstr_nocase
> found_headers
;
176 class RGWHTTPTransceiver
: public RGWHTTPHeadersCollector
{
177 bufferlist
* const read_bl
;
178 std::string post_data
;
179 size_t post_data_index
;
182 RGWHTTPTransceiver(CephContext
* const cct
,
183 bufferlist
* const read_bl
,
184 const header_spec_t intercept_headers
= {})
185 : RGWHTTPHeadersCollector(cct
, intercept_headers
),
190 RGWHTTPTransceiver(CephContext
* const cct
,
191 bufferlist
* const read_bl
,
192 const bool verify_ssl
,
193 const header_spec_t intercept_headers
= {})
194 : RGWHTTPHeadersCollector(cct
, intercept_headers
),
197 set_verify_ssl(verify_ssl
);
200 void set_post_data(const std::string
& _post_data
) {
201 this->post_data
= _post_data
;
205 int send_data(void* ptr
, size_t len
) override
;
207 int receive_data(void *ptr
, size_t len
) override
{
208 read_bl
->append((char *)ptr
, len
);
213 typedef RGWHTTPTransceiver RGWPostHTTPData
;
216 class RGWCompletionManager
;
218 class RGWHTTPManager
{
220 RGWCompletionManager
*completion_mgr
;
223 std::atomic
<unsigned> going_down
{ 0 };
224 std::atomic
<unsigned> is_stopped
{ 0 };
227 map
<uint64_t, rgw_http_req_data
*> reqs
;
228 list
<rgw_http_req_data
*> unregistered_reqs
;
229 map
<uint64_t, rgw_http_req_data
*> complete_reqs
;
231 int64_t max_threaded_req
;
234 void register_request(rgw_http_req_data
*req_data
);
235 void complete_request(rgw_http_req_data
*req_data
);
236 void _complete_request(rgw_http_req_data
*req_data
);
237 void unregister_request(rgw_http_req_data
*req_data
);
238 void _unlink_request(rgw_http_req_data
*req_data
);
239 void unlink_request(rgw_http_req_data
*req_data
);
240 void finish_request(rgw_http_req_data
*req_data
, int r
);
241 void _finish_request(rgw_http_req_data
*req_data
, int r
);
242 int link_request(rgw_http_req_data
*req_data
);
244 void manage_pending_requests();
246 class ReqsThread
: public Thread
{
247 RGWHTTPManager
*manager
;
250 ReqsThread(RGWHTTPManager
*_m
) : manager(_m
) {}
251 void *entry() override
;
254 ReqsThread
*reqs_thread
;
256 void *reqs_thread_entry();
261 RGWHTTPManager(CephContext
*_cct
, RGWCompletionManager
*completion_mgr
= NULL
);
267 int add_request(RGWHTTPClient
*client
, const char *method
, const char *url
);
268 int remove_request(RGWHTTPClient
*client
);
270 /* only for non threaded case */
271 int process_requests(bool wait_for_data
, bool *done
);
273 int complete_requests();