xref: /libevent-2.1.12/sample/http-connect.c (revision e2424229)
11bf75956SAzat Khuzhin #include "event2/event-config.h"
21bf75956SAzat Khuzhin 
31d34498eSAzat Khuzhin #include <event2/event.h>
41d34498eSAzat Khuzhin #include <event2/http.h>
51d34498eSAzat Khuzhin #include <event2/http_struct.h>
61d34498eSAzat Khuzhin #include <event2/buffer.h>
71d34498eSAzat Khuzhin #include <stdlib.h>
81d34498eSAzat Khuzhin #include <stdio.h>
91d34498eSAzat Khuzhin #include <limits.h>
101d34498eSAzat Khuzhin 
116dc71e70SAzat Khuzhin #define VERIFY(cond) do {                       \
126dc71e70SAzat Khuzhin 	if (!(cond)) {                              \
136dc71e70SAzat Khuzhin 		fprintf(stderr, "[error] %s\n", #cond); \
14c544222fSAzat Khuzhin 		exit(EXIT_FAILURE);                     \
156dc71e70SAzat Khuzhin 	}                                           \
166dc71e70SAzat Khuzhin } while (0);                                    \
176dc71e70SAzat Khuzhin 
181bf75956SAzat Khuzhin #define URL_MAX 4096
191bf75956SAzat Khuzhin 
201d34498eSAzat Khuzhin struct connect_base
211d34498eSAzat Khuzhin {
221d34498eSAzat Khuzhin 	struct evhttp_connection *evcon;
231d34498eSAzat Khuzhin 	struct evhttp_uri *location;
241d34498eSAzat Khuzhin };
251d34498eSAzat Khuzhin 
uri_parse(const char * str)26*e2424229SAzat Khuzhin static struct evhttp_uri* uri_parse(const char *str)
27*e2424229SAzat Khuzhin {
28*e2424229SAzat Khuzhin 	struct evhttp_uri *uri;
29*e2424229SAzat Khuzhin 	VERIFY(uri = evhttp_uri_parse(str));
30*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_get_host(uri));
31*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_get_port(uri) > 0);
32*e2424229SAzat Khuzhin 	return uri;
33*e2424229SAzat Khuzhin }
uri_path(struct evhttp_uri * uri,char buffer[URL_MAX])34*e2424229SAzat Khuzhin static char* uri_path(struct evhttp_uri *uri, char buffer[URL_MAX])
35*e2424229SAzat Khuzhin {
36*e2424229SAzat Khuzhin 	struct evhttp_uri *path;
37*e2424229SAzat Khuzhin 
38*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_join(uri, buffer, URL_MAX));
39*e2424229SAzat Khuzhin 
40*e2424229SAzat Khuzhin 	path = evhttp_uri_parse(buffer);
41*e2424229SAzat Khuzhin 	evhttp_uri_set_scheme(path, NULL);
42*e2424229SAzat Khuzhin 	evhttp_uri_set_userinfo(path, 0);
43*e2424229SAzat Khuzhin 	evhttp_uri_set_host(path, NULL);
44*e2424229SAzat Khuzhin 	evhttp_uri_set_port(path, -1);
45*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_join(path, buffer, URL_MAX));
46*e2424229SAzat Khuzhin 	return buffer;
47*e2424229SAzat Khuzhin }
uri_hostport(struct evhttp_uri * uri,char buffer[URL_MAX])48*e2424229SAzat Khuzhin static char* uri_hostport(struct evhttp_uri *uri, char buffer[URL_MAX])
49*e2424229SAzat Khuzhin {
50*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_join(uri, buffer, URL_MAX));
51*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_get_host(uri));
52*e2424229SAzat Khuzhin 	VERIFY(evhttp_uri_get_port(uri) > 0);
53*e2424229SAzat Khuzhin 	evutil_snprintf(buffer, URL_MAX, "%s:%d",
54*e2424229SAzat Khuzhin 		evhttp_uri_get_host(uri), evhttp_uri_get_port(uri));
55*e2424229SAzat Khuzhin 	return buffer;
56*e2424229SAzat Khuzhin }
57*e2424229SAzat Khuzhin 
get_cb(struct evhttp_request * req,void * arg)58f976d436SAzat Khuzhin static void get_cb(struct evhttp_request *req, void *arg)
591d34498eSAzat Khuzhin {
601bf75956SAzat Khuzhin 	ev_ssize_t len;
611bf75956SAzat Khuzhin 	struct evbuffer *evbuf;
621bf75956SAzat Khuzhin 
636dc71e70SAzat Khuzhin 	VERIFY(req);
641bf75956SAzat Khuzhin 
651bf75956SAzat Khuzhin 	evbuf = evhttp_request_get_input_buffer(req);
661bf75956SAzat Khuzhin 	len = evbuffer_get_length(evbuf);
671bf75956SAzat Khuzhin 	fwrite(evbuffer_pullup(evbuf, len), len, 1, stdout);
681bf75956SAzat Khuzhin 	evbuffer_drain(evbuf, len);
691d34498eSAzat Khuzhin }
701d34498eSAzat Khuzhin 
connect_cb(struct evhttp_request * proxy_req,void * arg)71f976d436SAzat Khuzhin static void connect_cb(struct evhttp_request *proxy_req, void *arg)
721d34498eSAzat Khuzhin {
731d34498eSAzat Khuzhin 	struct connect_base *base = arg;
741d34498eSAzat Khuzhin 	struct evhttp_connection *evcon = base->evcon;
751d34498eSAzat Khuzhin 	struct evhttp_uri *location = base->location;
76*e2424229SAzat Khuzhin 	struct evhttp_request *req;
77*e2424229SAzat Khuzhin 	char buffer[URL_MAX];
781d34498eSAzat Khuzhin 
796dc71e70SAzat Khuzhin 	VERIFY(proxy_req);
80*e2424229SAzat Khuzhin 	VERIFY(evcon);
81*e2424229SAzat Khuzhin 
82*e2424229SAzat Khuzhin 	req = evhttp_request_new(get_cb, NULL);
831d34498eSAzat Khuzhin 	evhttp_add_header(req->output_headers, "Connection", "close");
84*e2424229SAzat Khuzhin 	evhttp_add_header(req->output_headers, "Host", evhttp_uri_get_host(location));
856dc71e70SAzat Khuzhin 	VERIFY(!evhttp_make_request(evcon, req, EVHTTP_REQ_GET,
86*e2424229SAzat Khuzhin 		uri_path(location, buffer)));
871d34498eSAzat Khuzhin }
881d34498eSAzat Khuzhin 
main(int argc,const char ** argv)891d34498eSAzat Khuzhin int main(int argc, const char **argv)
901d34498eSAzat Khuzhin {
91*e2424229SAzat Khuzhin 	char hostport[URL_MAX];
921d34498eSAzat Khuzhin 
931d34498eSAzat Khuzhin 	struct evhttp_uri *location;
941d34498eSAzat Khuzhin 	struct evhttp_uri *proxy;
951d34498eSAzat Khuzhin 
961d34498eSAzat Khuzhin 	struct event_base *base;
971d34498eSAzat Khuzhin 	struct evhttp_connection *evcon;
981d34498eSAzat Khuzhin 	struct evhttp_request *req;
991d34498eSAzat Khuzhin 
100f976d436SAzat Khuzhin 	struct connect_base connect_base;
101f976d436SAzat Khuzhin 
1021d34498eSAzat Khuzhin 	if (argc != 3) {
1031d34498eSAzat Khuzhin 		printf("Usage: %s proxy url\n", argv[0]);
1041d34498eSAzat Khuzhin 		return 1;
1051d34498eSAzat Khuzhin 	}
1061d34498eSAzat Khuzhin 
107*e2424229SAzat Khuzhin 	proxy    = uri_parse(argv[1]);
108*e2424229SAzat Khuzhin 	location = uri_parse(argv[2]);
1091d34498eSAzat Khuzhin 
1106dc71e70SAzat Khuzhin 	VERIFY(base = event_base_new());
1116dc71e70SAzat Khuzhin 	VERIFY(evcon = evhttp_connection_base_new(base, NULL,
1121d34498eSAzat Khuzhin 		evhttp_uri_get_host(proxy), evhttp_uri_get_port(proxy)));
1130abe4ebaSAzat Khuzhin 	connect_base.evcon = evcon;
1140abe4ebaSAzat Khuzhin 	connect_base.location = location;
1156dc71e70SAzat Khuzhin 	VERIFY(req = evhttp_request_new(connect_cb, &connect_base));
1161d34498eSAzat Khuzhin 
117*e2424229SAzat Khuzhin 	uri_hostport(location, hostport);
1181d34498eSAzat Khuzhin 	evhttp_add_header(req->output_headers, "Connection", "keep-alive");
1191d34498eSAzat Khuzhin 	evhttp_add_header(req->output_headers, "Proxy-Connection", "keep-alive");
120*e2424229SAzat Khuzhin 	evhttp_add_header(req->output_headers, "Host", hostport);
121*e2424229SAzat Khuzhin 	evhttp_make_request(evcon, req, EVHTTP_REQ_CONNECT, hostport);
1221d34498eSAzat Khuzhin 
1231d34498eSAzat Khuzhin 	event_base_dispatch(base);
124*e2424229SAzat Khuzhin 
1251d34498eSAzat Khuzhin 	evhttp_connection_free(evcon);
1261d34498eSAzat Khuzhin 	event_base_free(base);
1271d34498eSAzat Khuzhin 	evhttp_uri_free(proxy);
1281d34498eSAzat Khuzhin 	evhttp_uri_free(location);
129*e2424229SAzat Khuzhin 
1301d34498eSAzat Khuzhin 	return 0;
1311d34498eSAzat Khuzhin }
132