aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_server.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-09-14 16:46:38 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-09-14 16:46:38 +0000
commitf078bf6f9b737e52d3fb7f944be0d0b600686e64 (patch)
treef542e1eff8408c77ec13cea499314b769c8748a1 /src/transport/plugin_transport_http_server.c
parenta86d442e62e83ef0a9744ea32ad8e09251096675 (diff)
downloadgnunet-f078bf6f9b737e52d3fb7f944be0d0b600686e64.tar.gz
gnunet-f078bf6f9b737e52d3fb7f944be0d0b600686e64.zip
http plugin revisited
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r--src/transport/plugin_transport_http_server.c374
1 files changed, 374 insertions, 0 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
new file mode 100644
index 000000000..96d3e27ae
--- /dev/null
+++ b/src/transport/plugin_transport_http_server.c
@@ -0,0 +1,374 @@
1/*
2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file transport/plugin_transport_http.c
23 * @brief http transport service plugin
24 * @author Matthias Wachs
25 */
26
27#include "plugin_transport_http.h"
28
29static void
30server_log (void *arg, const char *fmt, va_list ap)
31{
32 char text[1024];
33
34 vsnprintf (text, sizeof (text), fmt, ap);
35 va_end (ap);
36 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: %s\n", text);
37}
38
39/**
40 * Check if incoming connection is accepted.
41 * NOTE: Here every connection is accepted
42 * @param cls plugin as closure
43 * @param addr address of incoming connection
44 * @param addr_len address length of incoming connection
45 * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected
46 *
47 */
48static int
49server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len)
50{
51 return 0;
52}
53
54
55/**
56 * Callback called by MHD when it needs data to send
57 * @param cls current session
58 * @param pos position in buffer
59 * @param buf the buffer to write data to
60 * @param max max number of bytes available in buffer
61 * @return bytes written to buffer
62 */
63#if 0
64static ssize_t
65server_send_cb (void *cls, uint64_t pos, char *buf, size_t max)
66{
67
68 return 0;
69}
70#endif
71
72
73#if BUILD_HTTPS
74static char *
75server_load_file (const char *file)
76{
77 struct GNUNET_DISK_FileHandle *gn_file;
78 struct stat fstat;
79 char *text = NULL;
80
81 if (0 != STAT (file, &fstat))
82 return NULL;
83 text = GNUNET_malloc (fstat.st_size + 1);
84 gn_file =
85 GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ,
86 GNUNET_DISK_PERM_USER_READ);
87 if (gn_file == NULL)
88 {
89 GNUNET_free (text);
90 return NULL;
91 }
92 if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fstat.st_size))
93 {
94 GNUNET_free (text);
95 GNUNET_DISK_file_close (gn_file);
96 return NULL;
97 }
98 text[fstat.st_size] = '\0';
99 GNUNET_DISK_file_close (gn_file);
100 return text;
101}
102#endif
103
104
105#if BUILD_HTTPS
106
107static int
108server_load_certificate (struct Plugin *plugin)
109{
110 int res = GNUNET_OK;
111
112 char *key_file;
113 char *cert_file;
114
115 /* Get crypto init string from config
116 * If not present just use default values */
117 GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name,
118 "CRYPTO_INIT", &plugin->crypto_init);
119
120 if (GNUNET_OK !=
121 GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name,
122 "KEY_FILE", &key_file))
123 {
124 key_file = "https_key.key";
125 }
126
127 if (GNUNET_OK !=
128 GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name,
129 "CERT_FILE", &cert_file))
130 {
131 cert_file = "https_cert.crt";
132 }
133
134 /* read key & certificates from file */
135#if VERBOSE_SERVER
136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
137 "Loading TLS certificate from key-file `%s' cert-file`%s'\n",
138 key_file, cert_file);
139#endif
140
141 plugin->key = server_load_file (key_file);
142 plugin->cert = server_load_file (cert_file);
143
144 if ((plugin->key == NULL) || (plugin->cert == NULL))
145 {
146 struct GNUNET_OS_Process *cert_creation;
147
148 GNUNET_free_non_null (plugin->key);
149 plugin->key = NULL;
150 GNUNET_free_non_null (plugin->cert);
151 plugin->cert = NULL;
152
153#if VERBOSE_SERVER
154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
155 "No usable TLS certificate found, creating certificate\n");
156#endif
157 errno = 0;
158 cert_creation =
159 GNUNET_OS_start_process (NULL, NULL,
160 "gnunet-transport-certificate-creation",
161 "gnunet-transport-certificate-creation",
162 key_file, cert_file, NULL);
163 if (cert_creation == NULL)
164 {
165 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
166 _
167 ("Could not create a new TLS certificate, program `gnunet-transport-certificate-creation' could not be started!\n"));
168 GNUNET_free (key_file);
169 GNUNET_free (cert_file);
170
171 GNUNET_free_non_null (plugin->key);
172 GNUNET_free_non_null (plugin->cert);
173 GNUNET_free_non_null (plugin->crypto_init);
174
175 return GNUNET_SYSERR;
176 }
177 GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (cert_creation));
178 GNUNET_OS_process_close (cert_creation);
179
180 plugin->key = server_load_file (key_file);
181 plugin->cert = server_load_file (cert_file);
182 }
183
184 if ((plugin->key == NULL) || (plugin->cert == NULL))
185 {
186 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
187 _
188 ("No usable TLS certificate found and creating one failed!\n"),
189 "transport-https");
190 GNUNET_free (key_file);
191 GNUNET_free (cert_file);
192
193 GNUNET_free_non_null (plugin->key);
194 GNUNET_free_non_null (plugin->cert);
195 GNUNET_free_non_null (plugin->crypto_init);
196
197 return GNUNET_SYSERR;
198 }
199 GNUNET_free (key_file);
200 GNUNET_free (cert_file);
201#if DEBUG_HTTP
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n");
203#endif
204
205 return res;
206}
207#endif
208
209
210/**
211 * Process GET or PUT request received via MHD. For
212 * GET, queue response that will send back our pending
213 * messages. For PUT, process incoming data and send
214 * to GNUnet core. In either case, check if a session
215 * already exists and create a new one if not.
216 */
217static int
218server_access_cb (void *cls, struct MHD_Connection *mhd_connection,
219 const char *url, const char *method, const char *version,
220 const char *upload_data, size_t * upload_data_size,
221 void **httpSessionCache)
222{
223 return 0;
224}
225
226static void
227server_disconnect_cb (void *cls, struct MHD_Connection *connection,
228 void **httpSessionCache)
229{
230}
231
232int
233server_disconnect (struct Session *s)
234{
235 return GNUNET_OK;
236}
237
238int
239server_send (struct Session *s, const char *msgbuf, size_t msgbuf_size)
240{
241 return GNUNET_OK;
242}
243
244int
245server_start (struct Plugin *plugin)
246{
247 int res = GNUNET_OK;
248
249#if BUILD_HTTPS
250 res = server_load_certificate (plugin);
251 if (res == GNUNET_SYSERR)
252 {
253 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TABORT\n");
254 return res;
255 }
256#endif
257
258 plugin->server_v4 = NULL;
259 if (plugin->ipv4 == GNUNET_YES)
260 {
261 plugin->server_v4 = MHD_start_daemon (
262#if VERBOSE_SERVER
263 MHD_USE_DEBUG |
264#endif
265#if BUILD_HTTPS
266 MHD_USE_SSL |
267#endif
268 MHD_NO_FLAG, plugin->port,
269 &server_accept_cb, plugin,
270 &server_access_cb, plugin,
271 //MHD_OPTION_SOCK_ADDR,
272 //(struct sockaddr_in *)
273 //plugin->bind4_address,
274 MHD_OPTION_CONNECTION_LIMIT,
275 (unsigned int)
276 plugin->max_connections,
277#if BUILD_HTTPS
278 MHD_OPTION_HTTPS_PRIORITIES,
279 plugin->crypto_init,
280 MHD_OPTION_HTTPS_MEM_KEY,
281 plugin->key,
282 MHD_OPTION_HTTPS_MEM_CERT,
283 plugin->cert,
284#endif
285 MHD_OPTION_CONNECTION_TIMEOUT,
286 (unsigned int) 3,
287 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
288 (size_t) (2 *
289 GNUNET_SERVER_MAX_MESSAGE_SIZE),
290 MHD_OPTION_NOTIFY_COMPLETED,
291 &server_disconnect_cb, plugin,
292 MHD_OPTION_EXTERNAL_LOGGER,
293 server_log, NULL, MHD_OPTION_END);
294 if (plugin->server_v4 == NULL)
295 res = GNUNET_SYSERR;
296 }
297 plugin->server_v6 = NULL;
298 if (plugin->ipv6 == GNUNET_YES)
299 {
300 plugin->server_v6 = MHD_start_daemon (
301#if VERBOSE_SERVER
302 MHD_USE_DEBUG |
303#endif
304#if BUILD_HTTPS
305 MHD_USE_SSL |
306#endif
307 MHD_USE_IPv6, plugin->port,
308 &server_accept_cb, plugin,
309 &server_access_cb, plugin,
310 //MHD_OPTION_SOCK_ADDR,
311 //tmp,
312 MHD_OPTION_CONNECTION_LIMIT,
313 (unsigned int)
314 plugin->max_connections,
315#if BUILD_HTTPS
316 MHD_OPTION_HTTPS_PRIORITIES,
317 plugin->crypto_init,
318 MHD_OPTION_HTTPS_MEM_KEY,
319 plugin->key,
320 MHD_OPTION_HTTPS_MEM_CERT,
321 plugin->cert,
322#endif
323 MHD_OPTION_CONNECTION_TIMEOUT,
324 (unsigned int) 3,
325 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
326 (size_t) (2 *
327 GNUNET_SERVER_MAX_MESSAGE_SIZE),
328 MHD_OPTION_NOTIFY_COMPLETED,
329 &server_disconnect_cb, plugin,
330 MHD_OPTION_EXTERNAL_LOGGER,
331 server_log, NULL, MHD_OPTION_END);
332
333 if (plugin->server_v6 == NULL)
334 res = GNUNET_SYSERR;
335 }
336
337#if DEBUG_HTTP
338 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
339 "%s server component started on port %u\n", plugin->name,
340 plugin->port);
341#endif
342 return res;
343}
344
345void
346server_stop (struct Plugin *plugin)
347{
348
349 if (plugin->server_v4 != NULL)
350 {
351 MHD_stop_daemon (plugin->server_v4);
352 plugin->server_v4 = NULL;
353 }
354 if (plugin->server_v6 != NULL)
355 {
356 MHD_stop_daemon (plugin->server_v6);
357 plugin->server_v6 = NULL;
358 }
359
360#if BUILD_HTTPS
361 GNUNET_free_non_null (plugin->crypto_init);
362 GNUNET_free_non_null (plugin->cert);
363 GNUNET_free_non_null (plugin->key);
364#endif
365
366#if DEBUG_HTTP
367 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
368 "%s server component stopped\n", plugin->name);
369#endif
370}
371
372
373
374/* end of plugin_transport_http.c */