blob: b5265ce436fb5cf49ff6fee3b3e9165c71dd8b41 [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) {
Roger Meiera8cef6e2011-07-17 18:55:59 +000096 (void) cob;
97 (void) message;
David Reiss5ddabb82010-10-06 17:09:37 +000098 abort(); // XXX
99}
100
101
102bool TEvhttpClientChannel::recvMessage(
103 const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
Roger Meiera8cef6e2011-07-17 18:55:59 +0000104 (void) cob;
105 (void) message;
David Reiss5ddabb82010-10-06 17:09:37 +0000106 abort(); // XXX
107}
108
109
110void TEvhttpClientChannel::finish(struct evhttp_request* req) {
111 if (req == NULL) {
112 return cob_();
113 } else if (req->response_code != 200) {
114 return cob_();
115 }
116 recvBuf_->resetBuffer(
117 EVBUFFER_DATA(req->input_buffer),
118 EVBUFFER_LENGTH(req->input_buffer));
119 return cob_();
120}
121
122
123/* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) {
124 TEvhttpClientChannel* self = (TEvhttpClientChannel*)arg;
125 self->finish(req);
126}
127
128
129}}} // apache::thrift::async