blob: af2c86a8db9539c3f8202a81cda24527647265b0 [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); \
Haibo Huangb2279672019-05-31 16:12:39 -070014 exit(EXIT_FAILURE); \
Narayan Kamathfc74cb42017-09-13 12:53:52 +010015 } \
16} while (0); \
17
18#define URL_MAX 4096
19
20struct connect_base
21{
22 struct evhttp_connection *evcon;
23 struct evhttp_uri *location;
24};
25
26static void get_cb(struct evhttp_request *req, void *arg)
27{
28 ev_ssize_t len;
29 struct evbuffer *evbuf;
Haibo Huangb2279672019-05-31 16:12:39 -070030 struct evhttp_connection *evcon;
Narayan Kamathfc74cb42017-09-13 12:53:52 +010031
32 VERIFY(req);
Haibo Huangb2279672019-05-31 16:12:39 -070033 evcon = evhttp_request_get_connection(req);
34 VERIFY(evcon);
Narayan Kamathfc74cb42017-09-13 12:53:52 +010035
36 evbuf = evhttp_request_get_input_buffer(req);
37 len = evbuffer_get_length(evbuf);
38 fwrite(evbuffer_pullup(evbuf, len), len, 1, stdout);
39 evbuffer_drain(evbuf, len);
40}
41
42static void connect_cb(struct evhttp_request *proxy_req, void *arg)
43{
44 char buffer[URL_MAX];
45
46 struct connect_base *base = arg;
47 struct evhttp_connection *evcon = base->evcon;
48 struct evhttp_uri *location = base->location;
49
50 VERIFY(proxy_req);
51 if (evcon) {
52 struct evhttp_request *req = evhttp_request_new(get_cb, NULL);
53 evhttp_add_header(req->output_headers, "Connection", "close");
54 VERIFY(!evhttp_make_request(evcon, req, EVHTTP_REQ_GET,
55 evhttp_uri_join(location, buffer, URL_MAX)));
56 }
57}
58
59int main(int argc, const char **argv)
60{
61 char buffer[URL_MAX];
62
63 struct evhttp_uri *host_port;
64 struct evhttp_uri *location;
65 struct evhttp_uri *proxy;
66
67 struct event_base *base;
68 struct evhttp_connection *evcon;
69 struct evhttp_request *req;
70
71 struct connect_base connect_base;
72
73 if (argc != 3) {
74 printf("Usage: %s proxy url\n", argv[0]);
75 return 1;
76 }
77
78 {
Haibo Huangb2279672019-05-31 16:12:39 -070079 VERIFY(proxy = evhttp_uri_parse(argv[1]));
Narayan Kamathfc74cb42017-09-13 12:53:52 +010080 VERIFY(evhttp_uri_get_host(proxy));
81 VERIFY(evhttp_uri_get_port(proxy) > 0);
82 }
83 {
84 host_port = evhttp_uri_parse(argv[2]);
85 evhttp_uri_set_scheme(host_port, NULL);
86 evhttp_uri_set_userinfo(host_port, NULL);
87 evhttp_uri_set_path(host_port, NULL);
88 evhttp_uri_set_query(host_port, NULL);
89 evhttp_uri_set_fragment(host_port, NULL);
90 VERIFY(evhttp_uri_get_host(host_port));
91 VERIFY(evhttp_uri_get_port(host_port) > 0);
92 }
93 {
94 location = evhttp_uri_parse(argv[2]);
95 evhttp_uri_set_scheme(location, NULL);
96 evhttp_uri_set_userinfo(location, 0);
97 evhttp_uri_set_host(location, NULL);
98 evhttp_uri_set_port(location, -1);
99 }
100
101 VERIFY(base = event_base_new());
102 VERIFY(evcon = evhttp_connection_base_new(base, NULL,
103 evhttp_uri_get_host(proxy), evhttp_uri_get_port(proxy)));
104 connect_base.evcon = evcon;
105 connect_base.location = location;
106 VERIFY(req = evhttp_request_new(connect_cb, &connect_base));
107
108 evhttp_add_header(req->output_headers, "Connection", "keep-alive");
109 evhttp_add_header(req->output_headers, "Proxy-Connection", "keep-alive");
110 evutil_snprintf(buffer, URL_MAX, "%s:%d",
111 evhttp_uri_get_host(host_port), evhttp_uri_get_port(host_port));
112 evhttp_make_request(evcon, req, EVHTTP_REQ_CONNECT, buffer);
113
114 event_base_dispatch(base);
115 evhttp_connection_free(evcon);
116 event_base_free(base);
117 evhttp_uri_free(proxy);
118 evhttp_uri_free(host_port);
119 evhttp_uri_free(location);
120 return 0;
121}