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