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