blob: e5fc1b06e1a939c8a35d3c2f4e987db3ff29d309 [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
Roger Meier285cfaa2011-07-28 17:51:36 +000053void TEvhttpClientChannel::sendAndRecvMessage(
David Reiss5ddabb82010-10-06 17:09:37 +000054 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 }
David Reiss5ddabb82010-10-06 17:09:37 +000089}
90
91
Roger Meier285cfaa2011-07-28 17:51:36 +000092void TEvhttpClientChannel::sendMessage(
David Reiss5ddabb82010-10-06 17:09:37 +000093 const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
Roger Meiera8cef6e2011-07-17 18:55:59 +000094 (void) cob;
95 (void) message;
David Reiss5ddabb82010-10-06 17:09:37 +000096 abort(); // XXX
97}
98
99
Roger Meier285cfaa2011-07-28 17:51:36 +0000100void TEvhttpClientChannel::recvMessage(
David Reiss5ddabb82010-10-06 17:09:37 +0000101 const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) {
Roger Meiera8cef6e2011-07-17 18:55:59 +0000102 (void) cob;
103 (void) message;
David Reiss5ddabb82010-10-06 17:09:37 +0000104 abort(); // XXX
105}
106
107
108void TEvhttpClientChannel::finish(struct evhttp_request* req) {
109 if (req == NULL) {
Roger Meier285cfaa2011-07-28 17:51:36 +0000110 cob_();
111 return;
David Reiss5ddabb82010-10-06 17:09:37 +0000112 } else if (req->response_code != 200) {
Roger Meier285cfaa2011-07-28 17:51:36 +0000113 cob_();
114 return;
David Reiss5ddabb82010-10-06 17:09:37 +0000115 }
116 recvBuf_->resetBuffer(
117 EVBUFFER_DATA(req->input_buffer),
118 EVBUFFER_LENGTH(req->input_buffer));
Roger Meier285cfaa2011-07-28 17:51:36 +0000119 cob_();
120 return;
David Reiss5ddabb82010-10-06 17:09:37 +0000121}
122
123
124/* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) {
125 TEvhttpClientChannel* self = (TEvhttpClientChannel*)arg;
126 self->finish(req);
127}
128
129
130}}} // apache::thrift::async