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