blob: a44d001ac71fa4ac50e90951b1276e179eb1a9ed [file] [log] [blame]
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001#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
19struct connect_base
20{
21 struct evhttp_connection *evcon;
22 struct evhttp_uri *location;
23};
24
25static 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
38static 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
55int 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}