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