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