]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
20 #include <thrift/async/TEvhttpClientChannel.h>
22 #include <event2/buffer.h>
23 #include <event2/buffer_compat.h>
24 #include <thrift/transport/TBufferTransports.h>
25 #include <thrift/protocol/TProtocolException.h>
30 using namespace apache::thrift::protocol
;
31 using apache::thrift::transport::TTransportException
;
37 TEvhttpClientChannel::TEvhttpClientChannel(const std::string
& host
,
38 const std::string
& path
,
41 struct event_base
* eb
,
42 struct evdns_base
* dnsbase
)
44 : host_(host
), path_(path
), conn_(nullptr) {
45 conn_
= evhttp_connection_base_new(eb
, dnsbase
, address
, port
);
46 if (conn_
== nullptr) {
47 throw TException("evhttp_connection_new failed");
51 TEvhttpClientChannel::~TEvhttpClientChannel() {
52 if (conn_
!= nullptr) {
53 evhttp_connection_free(conn_
);
57 void TEvhttpClientChannel::sendAndRecvMessage(const VoidCallback
& cob
,
58 apache::thrift::transport::TMemoryBuffer
* sendBuf
,
59 apache::thrift::transport::TMemoryBuffer
* recvBuf
) {
60 struct evhttp_request
* req
= evhttp_request_new(response
, this);
62 throw TException("evhttp_request_new failed");
67 rv
= evhttp_add_header(req
->output_headers
, "Host", host_
.c_str());
69 throw TException("evhttp_add_header failed");
72 rv
= evhttp_add_header(req
->output_headers
, "Content-Type", "application/x-thrift");
74 throw TException("evhttp_add_header failed");
79 sendBuf
->getBuffer(&obuf
, &sz
);
80 rv
= evbuffer_add(req
->output_buffer
, obuf
, sz
);
82 throw TException("evbuffer_add failed");
85 rv
= evhttp_make_request(conn_
, req
, EVHTTP_REQ_POST
, path_
.c_str());
87 throw TException("evhttp_make_request failed");
90 completionQueue_
.push(Completion(cob
, recvBuf
));
93 void TEvhttpClientChannel::sendMessage(const VoidCallback
& cob
,
94 apache::thrift::transport::TMemoryBuffer
* message
) {
97 throw TProtocolException(TProtocolException::NOT_IMPLEMENTED
,
98 "Unexpected call to TEvhttpClientChannel::sendMessage");
101 void TEvhttpClientChannel::recvMessage(const VoidCallback
& cob
,
102 apache::thrift::transport::TMemoryBuffer
* message
) {
105 throw TProtocolException(TProtocolException::NOT_IMPLEMENTED
,
106 "Unexpected call to TEvhttpClientChannel::recvMessage");
109 void TEvhttpClientChannel::finish(struct evhttp_request
* req
) {
110 assert(!completionQueue_
.empty());
111 Completion completion
= completionQueue_
.front();
112 completionQueue_
.pop();
113 if (req
== nullptr) {
116 } catch (const TTransportException
& e
) {
117 if (e
.getType() == TTransportException::END_OF_FILE
)
118 throw TException("connect failed");
123 } else if (req
->response_code
!= 200) {
126 } catch (const TTransportException
& e
) {
127 std::stringstream ss
;
128 ss
<< "server returned code " << req
->response_code
;
129 if (req
->response_code_line
)
130 ss
<< ": " << req
->response_code_line
;
131 if (e
.getType() == TTransportException::END_OF_FILE
)
132 throw TException(ss
.str());
138 completion
.second
->resetBuffer(EVBUFFER_DATA(req
->input_buffer
),
139 static_cast<uint32_t>(EVBUFFER_LENGTH(req
->input_buffer
)));
144 /* static */ void TEvhttpClientChannel::response(struct evhttp_request
* req
, void* arg
) {
145 auto* self
= (TEvhttpClientChannel
*)arg
;
148 } catch (std::exception
& e
) {
149 // don't propagate a C++ exception in C code (e.g. libevent)
150 std::cerr
<< "TEvhttpClientChannel::response exception thrown (ignored): " << e
.what()
156 } // apache::thrift::async