Home | History | Annotate | Download | only in sample
      1 #include "event2/event-config.h"
      2 
      3 #include <event2/event.h>
      4 #include <event2/http.h>
      5 #include <event2/http_struct.h>
      6 #include <event2/buffer.h>
      7 #include <stdlib.h>
      8 #include <stdio.h>
      9 #include <limits.h>
     10 
     11 #define VERIFY(cond) do {                       \
     12 	if (!(cond)) {                              \
     13 		fprintf(stderr, "[error] %s\n", #cond); \
     14 	}                                           \
     15 } while (0);                                    \
     16 
     17 #define URL_MAX 4096
     18 
     19 struct connect_base
     20 {
     21 	struct evhttp_connection *evcon;
     22 	struct evhttp_uri *location;
     23 };
     24 
     25 static void get_cb(struct evhttp_request *req, void *arg)
     26 {
     27 	ev_ssize_t len;
     28 	struct evbuffer *evbuf;
     29 
     30 	VERIFY(req);
     31 
     32 	evbuf = evhttp_request_get_input_buffer(req);
     33 	len = evbuffer_get_length(evbuf);
     34 	fwrite(evbuffer_pullup(evbuf, len), len, 1, stdout);
     35 	evbuffer_drain(evbuf, len);
     36 }
     37 
     38 static void connect_cb(struct evhttp_request *proxy_req, void *arg)
     39 {
     40 	char buffer[URL_MAX];
     41 
     42 	struct connect_base *base = arg;
     43 	struct evhttp_connection *evcon = base->evcon;
     44 	struct evhttp_uri *location = base->location;
     45 
     46 	VERIFY(proxy_req);
     47 	if (evcon) {
     48 		struct evhttp_request *req = evhttp_request_new(get_cb, NULL);
     49 		evhttp_add_header(req->output_headers, "Connection", "close");
     50 		VERIFY(!evhttp_make_request(evcon, req, EVHTTP_REQ_GET,
     51 			evhttp_uri_join(location, buffer, URL_MAX)));
     52 	}
     53 }
     54 
     55 int main(int argc, const char **argv)
     56 {
     57 	char buffer[URL_MAX];
     58 
     59 	struct evhttp_uri *host_port;
     60 	struct evhttp_uri *location;
     61 	struct evhttp_uri *proxy;
     62 
     63 	struct event_base *base;
     64 	struct evhttp_connection *evcon;
     65 	struct evhttp_request *req;
     66 
     67 	struct connect_base connect_base;
     68 
     69 	if (argc != 3) {
     70 		printf("Usage: %s proxy url\n", argv[0]);
     71 		return 1;
     72 	}
     73 
     74 	{
     75 		proxy = evhttp_uri_parse(argv[1]);
     76 		VERIFY(evhttp_uri_get_host(proxy));
     77 		VERIFY(evhttp_uri_get_port(proxy) > 0);
     78 	}
     79 	{
     80 		host_port = evhttp_uri_parse(argv[2]);
     81 		evhttp_uri_set_scheme(host_port, NULL);
     82 		evhttp_uri_set_userinfo(host_port, NULL);
     83 		evhttp_uri_set_path(host_port, NULL);
     84 		evhttp_uri_set_query(host_port, NULL);
     85 		evhttp_uri_set_fragment(host_port, NULL);
     86 		VERIFY(evhttp_uri_get_host(host_port));
     87 		VERIFY(evhttp_uri_get_port(host_port) > 0);
     88 	}
     89 	{
     90 		location = evhttp_uri_parse(argv[2]);
     91 		evhttp_uri_set_scheme(location, NULL);
     92 		evhttp_uri_set_userinfo(location, 0);
     93 		evhttp_uri_set_host(location, NULL);
     94 		evhttp_uri_set_port(location, -1);
     95 	}
     96 
     97 	VERIFY(base = event_base_new());
     98 	VERIFY(evcon = evhttp_connection_base_new(base, NULL,
     99 		evhttp_uri_get_host(proxy), evhttp_uri_get_port(proxy)));
    100 	connect_base.evcon = evcon;
    101 	connect_base.location = location;
    102 	VERIFY(req = evhttp_request_new(connect_cb, &connect_base));
    103 
    104 	evhttp_add_header(req->output_headers, "Connection", "keep-alive");
    105 	evhttp_add_header(req->output_headers, "Proxy-Connection", "keep-alive");
    106 	evutil_snprintf(buffer, URL_MAX, "%s:%d",
    107 		evhttp_uri_get_host(host_port), evhttp_uri_get_port(host_port));
    108 	evhttp_make_request(evcon, req, EVHTTP_REQ_CONNECT, buffer);
    109 
    110 	event_base_dispatch(base);
    111 	evhttp_connection_free(evcon);
    112 	event_base_free(base);
    113 	evhttp_uri_free(proxy);
    114 	evhttp_uri_free(host_port);
    115 	evhttp_uri_free(location);
    116 	return 0;
    117 }
    118