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