Last active
December 15, 2015 00:09
-
-
Save gkres/5170799 to your computer and use it in GitHub Desktop.
Libevent http server that acts like a middle man between a client and http server.
(A quick example, just to try and clear a few libevent related things up. Pretty sure it could have been done better.)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <event.h> | |
#include <evhttp.h> | |
#include <event2/event.h> | |
#include <event2/http.h> | |
#include <event2/buffer.h> | |
#include <sys/queue.h> | |
#include <cstdlib> | |
#include <string.h> | |
using namespace std; | |
static void final_reply_cb(struct evhttp_request *req, void *arg) { | |
string body; | |
struct evhttp_request* r = (evhttp_request*)arg; | |
// Prepare things for an outgoing response | |
struct evbuffer *output_buffer; | |
output_buffer = evbuffer_new(); | |
struct evkeyvalq *output_headers = evhttp_request_get_output_headers(r); | |
evhttp_add_header(output_headers, "Content-Type", "text/plain"); | |
string response = ""; | |
// Parse the incoming response body | |
int len = evbuffer_get_length(req->input_buffer); | |
void *buf = malloc(len); | |
evbuffer_copyout(req->input_buffer, buf, len); | |
body = string(static_cast<char*>(buf), len); | |
// Send the outgoing response | |
evbuffer_add_printf(output_buffer, "%s", body.c_str()); | |
evhttp_send_reply(r, HTTP_OK, "OK", output_buffer); | |
evbuffer_free(output_buffer); | |
} | |
void request_to_endpoint_cb(struct evhttp_request *r, void *arg) { | |
// Parse the URI parameters | |
struct evkeyvalq* args = new evkeyvalq; | |
const char *uri = evhttp_request_get_uri(r); | |
const char *query_part; | |
struct evhttp_uri* parsed_uri = NULL; | |
parsed_uri = evhttp_uri_parse(uri); | |
if (parsed_uri != NULL) query_part = evhttp_uri_get_query(parsed_uri); | |
else query_part = uri; | |
string type = ""; | |
evhttp_parse_query_str(query_part,args); | |
struct evkeyval *param; | |
TAILQ_FOREACH(param, args,next) { | |
if (strcmp(param->key,"type") == 0) { | |
type = param->value; | |
break; | |
} | |
} | |
string url = ""; | |
string host = ""; | |
string host_ip = ""; | |
if (type == "1") { | |
url = "http://www.google.com/robots.txt"; | |
host = "google.com"; | |
host_ip = "173.194.70.113"; | |
} else { | |
url = "http://localhost/sleep10"; // nginx set to wait 10 sec before replying | |
host = "localhost"; | |
host_ip = "192.168.2.15"; | |
} | |
// Create new connection to server | |
const char *addr = host_ip.c_str(); | |
unsigned int port = 80; | |
struct evhttp_connection *connection = evhttp_connection_new(addr, port); | |
evhttp_connection_set_timeout(connection, 15); | |
// Create the http request | |
struct evhttp_request *request = evhttp_request_new(final_reply_cb, r); | |
evhttp_add_header(request->output_headers, "Host", host.c_str()); | |
evhttp_add_header(request->output_headers, "Content-Length", "0"); | |
cout << "(proxy) Making a request to endpoint (" << url << ")." << endl; | |
evhttp_make_request(connection, request, EVHTTP_REQ_GET, url.c_str()); | |
cout << "(proxy) Request to endpoint made (" << url << "), waiting for a reply." << endl; | |
} | |
int main(int argc, char* argv[]) { | |
cout << "Starting test http server" << endl; | |
// Setup evhttp server | |
struct event_base *libeventbase = event_init(); | |
struct evhttp *metrics_server; | |
metrics_server = evhttp_new(libeventbase); | |
evhttp_bind_socket(metrics_server, "0.0.0.0", 8080); | |
evhttp_set_cb(metrics_server, "/test", request_to_endpoint_cb, libeventbase); | |
event_dispatch(); | |
event_base_free(libeventbase); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment