blob: 8b47173694e1b86403d4d2032d4e8bd603822ce7 [file] [log] [blame]
David Reiss5ddabb82010-10-06 17:09:37 +00001/*
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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
17 * under the License.
18 */
19
20#include "TEvhttpClientChannel.h"
21#include <evhttp.h>
Roger Meier7e056e72011-07-17 07:28:28 +000022#include "transport/TBufferTransports.h"
David Reiss5ddabb82010-10-06 17:09:37 +000023
24namespace apache { namespace thrift { namespace async {
25
26
27TEvhttpClientChannel::TEvhttpClientChannel(
28 const std::string& host,
29 const std::string& path,
30 const char* address,
31 int port,
32 struct event_base* eb)
33 : host_(host)
34 , path_(path)
35 , recvBuf_(NULL)
36 , conn_(NULL)
37{
38 conn_ = evhttp_connection_new(address, port);
39 if (conn_ == NULL) {
40 abort(); // XXX
41 }
42 evhttp_connection_set_base(conn_, eb);
43}
44
45
46TEvhttpClientChannel::~TEvhttpClientChannel() {
47 if (conn_ != NULL) {
48 evhttp_connection_free(conn_);
49 }
50}
51
52
53bool TEvhttpClientChannel::sendAndRecvMessage(
54 const VoidCallback& cob,
55 apache::thrift::transport::TMemoryBuffer* sendBuf,
56 apache::thrift::transport::TMemoryBuffer* recvBuf) {
57 cob_ = cob;
58 recvBuf_ = recvBuf;
59
60 struct evhttp_request* req = evhttp_request_new(response, this);
61 if (req == NULL) {
62 abort(); // XXX
63 }
64
65 int rv;
66
67 rv = evhttp_add_header(req->output_headers, "Host", host_.c_str());
68 if (rv != 0) {
69 abort(); // XXX
70 }
71
72 rv = evhttp_add_header(req->output_headers, "Content-Type", "application/x-thrift");
73 if (rv != 0) {
74 abort(); // XXX
75 }
76
77 uint8_t* obuf;
78 uint32_t sz;
79 sendBuf->getBuffer(&obuf, &sz);
80 rv = evbuffer_add(req->output_buffer, obuf, sz);
81 if (rv != 0) {
82 abort(); // XXX
83 }
84
85 rv = evhttp_make_request(conn_, req, EVHTTP_REQ_POST, path_.c_str());
86 if (rv != 0) {
87 abort(); // XXX
88 }
89
90 return true;
91}
92
93
94bool TEvhttpClientChannel::sendMessage(
95 const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
96 abort(); // XXX
97}
98
99
100bool TEvhttpClientChannel::recvMessage(
101 const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
102 abort(); // XXX
103}
104
105
106void TEvhttpClientChannel::finish(struct evhttp_request* req) {
107 if (req == NULL) {
108 return cob_();
109 } else if (req->response_code != 200) {
110 return cob_();
111 }
112 recvBuf_->resetBuffer(
113 EVBUFFER_DATA(req->input_buffer),
114 EVBUFFER_LENGTH(req->input_buffer));
115 return cob_();
116}
117
118
119/* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) {
120 TEvhttpClientChannel* self = (TEvhttpClientChannel*)arg;
121 self->finish(req);
122}
123
124
125}}} // apache::thrift::async