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