aboutsummaryrefslogtreecommitdiff
path: root/src/examples/mhd2spdy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/mhd2spdy.c')
-rw-r--r--src/examples/mhd2spdy.c323
1 files changed, 323 insertions, 0 deletions
diff --git a/src/examples/mhd2spdy.c b/src/examples/mhd2spdy.c
new file mode 100644
index 00000000..507641c2
--- /dev/null
+++ b/src/examples/mhd2spdy.c
@@ -0,0 +1,323 @@
1/*
2 Copyright (C) 2013 Andrey Uzunov
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18/**
19 * @file structures.h
20 * @author Andrey Uzunov
21 */
22
23 /*
24 * TODOs
25 * non blocking SSL connect
26 * check certificate
27 *
28 *
29 *
30 *
31
32
33 */
34
35#include "mhd2spdy_structures.h"
36#include "mhd2spdy_spdy.h"
37#include "mhd2spdy_http.h"
38
39static int run = 1;
40//static int spdy_close = 0;
41
42static void catch_signal(int signal)
43{
44 //spdy_close = 1;
45 run = 0;
46}
47
48int
49run_everything ()
50{
51 unsigned long long timeoutlong=0;
52 struct timeval timeout;
53 int ret;
54 fd_set rs;
55 fd_set ws;
56 fd_set es;
57 int maxfd = -1;
58 int maxfd_s = -1;
59 struct MHD_Daemon *daemon;
60 nfds_t spdy_npollfds = 1;
61 //struct pollfd spdy_pollfds[MAX_SPDY_CONNECTIONS];
62 struct URI * spdy2http_uri = NULL;
63 //int spdy_nfds;
64 //int spdylay_timeout = 0;
65 struct SPDY_Connection *connection;
66 struct SPDY_Connection *connections[MAX_SPDY_CONNECTIONS];
67 struct SPDY_Connection *connection_for_delete;
68
69 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
70 PRINT_INFO("signal failed");
71
72 if (signal(SIGINT, catch_signal) == SIG_ERR)
73 PRINT_INFO("signal failed");
74
75 //spdy2http_url = argv[2];
76 glob_opt.streams_opened = 0;
77 glob_opt.responses_pending = 0;
78 glob_opt.global_memory = 0;
79 //spdy_proto_version = 0;
80
81 srand(time(NULL));
82
83 if(init_parse_uri(&glob_opt.uri_preg))
84 DIE("Regexp compilation failed");
85
86
87 if(NULL != glob_opt.spdy2http_str)
88 {
89 ret = parse_uri(&glob_opt.uri_preg, glob_opt.spdy2http_str, &spdy2http_uri);
90 if(ret != 0)
91 DIE("spdy_parse_uri failed");
92 }
93
94 SSL_load_error_strings();
95 SSL_library_init();
96 glob_opt.ssl_ctx = SSL_CTX_new(SSLv23_client_method());
97 if(glob_opt.ssl_ctx == NULL) {
98 PRINT_INFO2("SSL_CTX_new %s", ERR_error_string(ERR_get_error(), NULL));
99 abort();
100 }
101 spdy_ssl_init_ssl_ctx(glob_opt.ssl_ctx, &glob_opt.spdy_proto_version);
102
103 daemon = MHD_start_daemon (
104 MHD_SUPPRESS_DATE_NO_CLOCK,
105 glob_opt.listen_port,
106 NULL, NULL, &http_cb_request, NULL,
107 MHD_OPTION_URI_LOG_CALLBACK, &http_log_cb, NULL,
108 MHD_OPTION_END);
109 if(NULL==daemon)
110 DIE("MHD_start_daemon failed");
111
112
113 do
114 {
115
116 timeout.tv_sec = 0;
117 timeout.tv_usec = 0;
118
119 if(NULL == glob_opt.spdy_connection && NULL != glob_opt.spdy2http_str)
120 {
121 glob_opt.spdy_connection = spdy_connect(spdy2http_uri, spdy2http_uri->port, strcmp("https", spdy2http_uri->scheme)==0);
122 if(NULL == glob_opt.spdy_connection && glob_opt.only_proxy)
123 PRINT_INFO("cannot connect to the proxy");
124 }
125
126 //PRINT_INFO("while1");
127 FD_ZERO(&rs);
128 FD_ZERO(&ws);
129 FD_ZERO(&es);
130
131 /*if(glob_opt.spdy_data_received)
132 {
133 timeout.tv_sec = 0;
134 timeout.tv_usec = 0;
135 glob_opt.spdy_data_received = false;
136}
137else{*/
138 /*if(glob_opt.responses_pending || glob_opt.streams_opened)// TODO only streams_opened true?
139 timeout.tv_usec = 0; //return immediately
140 else
141 {*/
142 ret = MHD_get_timeout(daemon, &timeoutlong);
143 if(MHD_NO == ret || timeoutlong > 5000)
144 timeout.tv_sec = 5;
145 else
146 {
147 timeout.tv_sec = timeoutlong / 1000;
148 timeout.tv_usec = (timeoutlong % 1000) * 1000;
149 }
150 //}
151//}
152 if(MHD_NO == MHD_get_fdset (daemon,
153 &rs,
154 &ws,
155 &es,
156 &maxfd))
157 {
158 PRINT_INFO("MHD_get_fdset error");
159 }
160 assert(-1 != maxfd);
161
162 maxfd_s = spdy_get_selectfdset(
163 &rs,
164 &ws,
165 &es,
166 connections, MAX_SPDY_CONNECTIONS, &spdy_npollfds);
167 if(maxfd_s > maxfd) maxfd = maxfd_s;
168
169 PRINT_INFO2("MHD timeout %i %i", timeout.tv_sec, timeout.tv_usec);
170 //TODO
171 //timeout.tv_sec = 0;
172 //timeout.tv_usec = 0;
173
174 glob_opt.spdy_data_received = false;
175
176 ret = select(maxfd+1, &rs, &ws, &es, &timeout);
177 PRINT_INFO2("timeout now %i %i", timeout.tv_sec, timeout.tv_usec);
178
179 switch(ret) {
180 case -1:
181 PRINT_INFO2("select error: %i", errno);
182 break;
183 case 0:
184 break;
185 default:
186 PRINT_INFO("run");
187 MHD_run_from_select(daemon,&rs, &ws, &es);
188 spdy_run_select(&rs, &ws, &es, connections, spdy_npollfds);
189 if(glob_opt.spdy_data_received)
190 {
191 PRINT_INFO("MHD run again");
192 MHD_run_from_select(daemon,&rs, &ws, &es);
193 }
194 break;
195 }
196
197 /*
198 //if(glob_opt.streams_opened) spdylay_timeout = 500;
199 //if(glob_opt.responses_pending || glob_opt.streams_opened) spdylay_timeout = 0;
200 //else spdylay_timeout = 0;
201 //else spdylay_timeout = 0;
202
203 spdy_get_pollfdset(spdy_pollfds, connections, MAX_SPDY_CONNECTIONS, &spdy_npollfds);
204
205 //TODO
206 //spdylay_timeout = 0;
207
208 PRINT_INFO2("spdylay timeout %i", spdylay_timeout);
209 ret = poll(spdy_pollfds, spdy_npollfds, spdylay_timeout);
210 if(ret == -1)
211 DIE("poll");
212 if(ret > 0){
213 PRINT_INFO("spdy_run");
214 spdy_run(spdy_pollfds, connections, spdy_npollfds);
215 }*/
216 }
217 while(run);
218
219 //TODO exit from loop and clean
220
221 MHD_stop_daemon (daemon);
222
223 //TODO SSL_free brakes
224 spdy_free_connection(glob_opt.spdy_connection);
225
226 connection = glob_opt.spdy_connections_head;
227 while(NULL != connection)
228 {
229 connection_for_delete = connection;
230 connection = connection_for_delete->next;
231 glob_opt.streams_opened -= connection_for_delete->streams_opened;
232 DLL_remove(glob_opt.spdy_connections_head, glob_opt.spdy_connections_tail, connection_for_delete);
233 spdy_free_connection(connection_for_delete);
234 }
235
236 free_uri(spdy2http_uri);
237
238 deinit_parse_uri(&glob_opt.uri_preg);
239
240 SSL_CTX_free(glob_opt.ssl_ctx);
241 ERR_free_strings();
242 EVP_cleanup();
243
244 PRINT_INFO2("spdy streams: %i; http requests: %i", glob_opt.streams_opened, glob_opt.responses_pending);
245 PRINT_INFO2("memory allocated %zu bytes", glob_opt.global_memory);
246
247 return 0;
248}
249
250void
251display_usage()
252{
253 printf(
254 "Usage: http2spdy [-vo] [-b <SPDY2HTTP-PROXY>] -p <PORT>\n"
255 "TODO\n"
256 );
257}
258
259
260int
261main (int argc,
262 char *const *argv)
263{
264 int getopt_ret;
265 int option_index;
266 struct option long_options[] = {
267 {"port", required_argument, 0, 'p'},
268 {"backend-proxy", required_argument, 0, 'b'},
269 {"verbose", no_argument, 0, 'v'},
270 {"only-proxy", no_argument, 0, 'o'},
271 {0, 0, 0, 0}
272 };
273
274 while (1)
275 {
276 getopt_ret = getopt_long( argc, argv, "p:b:vo", long_options, &option_index);
277 if (getopt_ret == -1)
278 break;
279
280 switch(getopt_ret)
281 {
282 case 'p':
283 glob_opt.listen_port = atoi(optarg);
284 break;
285
286 case 'b':
287 glob_opt.spdy2http_str = strdup(optarg);
288 if(NULL == glob_opt.spdy2http_str)
289 return 1;
290 break;
291
292 case 'v':
293 glob_opt.verbose = true;
294 break;
295
296 case 'o':
297 glob_opt.only_proxy = true;
298 break;
299
300 case 0:
301 PRINT_INFO("0 from getopt");
302 break;
303
304 case '?':
305 display_usage();
306 return 1;
307
308 default:
309 DIE("default from getopt");
310 }
311 }
312
313 if(
314 0 == glob_opt.listen_port
315 || (glob_opt.only_proxy && NULL == glob_opt.spdy2http_str)
316 )
317 {
318 display_usage();
319 return 1;
320 }
321
322 return run_everything();
323}