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