summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-13 09:59:43 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-13 09:59:43 +0000
commit74f9b73e5592424165236164fbb8e65d03399614 (patch)
treee2c293500d6dc565ee3635b43cf974a4a976c243
parent0bcb81843084f1b2cde5af408adcddebfb4c5875 (diff)
downloadgnunet-74f9b73e5592424165236164fbb8e65d03399614.tar.gz
gnunet-74f9b73e5592424165236164fbb8e65d03399614.zip
-bugfixes, change plugin call
-rw-r--r--src/gns/plugin_rest_gns.c11
-rw-r--r--src/identity/plugin_rest_identity.c171
-rw-r--r--src/include/gnunet_rest_plugin.h63
-rw-r--r--src/rest/gnunet-rest-server.c102
4 files changed, 217 insertions, 130 deletions
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index 75b0ff288..e837fe963 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -567,10 +567,7 @@ parse_json (const char *data, size_t data_size, struct LookupHandle *handle)
567 * @return GNUNET_OK if request accepted 567 * @return GNUNET_OK if request accepted
568 */ 568 */
569void 569void
570rest_gns_process_request(const char *method, 570rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
571 const char *url,
572 const char *data,
573 size_t data_size,
574 GNUNET_REST_ResultProcessor proc, 571 GNUNET_REST_ResultProcessor proc,
575 void *proc_cls) 572 void *proc_cls)
576{ 573{
@@ -578,7 +575,7 @@ rest_gns_process_request(const char *method,
578 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 575 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
579 576
580 //parse name and type from url 577 //parse name and type from url
581 if (GNUNET_OK != parse_url (url, handle)) 578 if (GNUNET_OK != parse_url (conndata_handle->url, handle))
582 { 579 {
583 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing url...\n"); 580 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing url...\n");
584 proc (proc_cls, NULL, 0, GNUNET_SYSERR); 581 proc (proc_cls, NULL, 0, GNUNET_SYSERR);
@@ -588,9 +585,9 @@ rest_gns_process_request(const char *method,
588 585
589 handle->proc_cls = proc_cls; 586 handle->proc_cls = proc_cls;
590 handle->proc = proc; 587 handle->proc = proc;
591 if (0 < data_size) 588 if (0 < conndata_handle->data_size)
592 { 589 {
593 if (GNUNET_OK != parse_json (data, data_size, handle)) 590 if (GNUNET_OK != parse_json (conndata_handle->data, conndata_handle->data_size, handle))
594 { 591 {
595 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing json...\n"); 592 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing json...\n");
596 proc (proc_cls, NULL, 0, GNUNET_SYSERR); 593 proc (proc_cls, NULL, 0, GNUNET_SYSERR);
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index aa68ae334..1d9c8305d 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -69,6 +69,11 @@ struct EgoEntry
69 * Ego Pkey 69 * Ego Pkey
70 */ 70 */
71 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 71 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
72
73 /**
74 * The Ego
75 */
76 struct GNUNET_IDENTITY_Ego *ego;
72}; 77};
73 78
74struct RequestHandle 79struct RequestHandle
@@ -129,14 +134,9 @@ struct RequestHandle
129 char *name; 134 char *name;
130 135
131 /** 136 /**
132 * The ego set from REST
133 */
134 char *set_ego;
135
136 /**
137 * The subsystem set from REST 137 * The subsystem set from REST
138 */ 138 */
139 char *set_subsystem; 139 char *subsys;
140 140
141 /** 141 /**
142 * The url 142 * The url
@@ -179,10 +179,8 @@ cleanup_handle (struct RequestHandle *handle)
179 GNUNET_SCHEDULER_cancel (handle->timeout_task); 179 GNUNET_SCHEDULER_cancel (handle->timeout_task);
180 if (NULL != handle->identity_handle) 180 if (NULL != handle->identity_handle)
181 GNUNET_IDENTITY_disconnect (handle->identity_handle); 181 GNUNET_IDENTITY_disconnect (handle->identity_handle);
182 if (NULL != handle->set_subsystem) 182 if (NULL != handle->subsys)
183 GNUNET_free (handle->set_subsystem); 183 GNUNET_free (handle->subsys);
184 if (NULL != handle->set_ego)
185 GNUNET_free (handle->set_ego);
186 for (ego_entry = handle->ego_head; 184 for (ego_entry = handle->ego_head;
187 NULL != ego_entry;) 185 NULL != ego_entry;)
188 { 186 {
@@ -263,21 +261,7 @@ ego_info_response (struct RequestHandle *handle)
263} 261}
264 262
265static void 263static void
266delete_finished (void *cls, const char *emsg) 264do_finished (void *cls, const char *emsg)
267{
268 struct RequestHandle *handle = cls;
269
270 handle->op = NULL;
271 if (NULL != emsg)
272 {
273 GNUNET_SCHEDULER_add_now (&do_error, handle);
274 }
275 handle->proc (handle->proc_cls, NULL, 0, GNUNET_OK);
276 cleanup_handle (handle);
277}
278
279static void
280create_finished (void *cls, const char *emsg)
281{ 265{
282 struct RequestHandle *handle = cls; 266 struct RequestHandle *handle = cls;
283 267
@@ -294,7 +278,7 @@ static void
294ego_create_cont (struct RequestHandle *handle) 278ego_create_cont (struct RequestHandle *handle)
295{ 279{
296 const char* egoname; 280 const char* egoname;
297 char term_data[handle->data_size]; 281 char term_data[handle->data_size+1];
298 json_t *egoname_json; 282 json_t *egoname_json;
299 json_t *root_json; 283 json_t *root_json;
300 json_error_t error; 284 json_error_t error;
@@ -353,13 +337,85 @@ ego_create_cont (struct RequestHandle *handle)
353 json_decref (root_json); 337 json_decref (root_json);
354 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, 338 handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
355 handle->name, 339 handle->name,
356 &create_finished, 340 &do_finished,
357 handle); 341 handle);
358} 342}
359 343
360void 344void
361subsys_set_cont (struct RequestHandle *handle) 345subsys_set_cont (struct RequestHandle *handle)
362{ 346{
347 const char *egoname;
348 const char *subsys;
349 char term_data[handle->data_size+1];
350 struct EgoEntry *ego_entry;
351 int ego_exists = GNUNET_NO;
352 json_t *root_json;
353 json_t *subsys_json;
354 json_error_t error;
355
356 if (strlen (API_NAMESPACE)+1 >= strlen (handle->url))
357 {
358 GNUNET_break(0);
359 handle->proc (handle->proc_cls, NULL, 0, GNUNET_SYSERR);
360 cleanup_handle (handle);
361 return;
362 }
363
364 egoname = &handle->url[strlen(API_NAMESPACE)+1];
365 for (ego_entry = handle->ego_head;
366 NULL != ego_entry;
367 ego_entry = ego_entry->next)
368 {
369 if (0 == strcasecmp (egoname, ego_entry->identifier))
370 {
371 ego_exists = GNUNET_YES;
372 break;
373 }
374 }
375 if (GNUNET_NO == ego_exists)
376 {
377 GNUNET_break(0);
378 handle->proc (handle->proc_cls, NULL, 0, GNUNET_SYSERR);
379 cleanup_handle (handle);
380 return;
381 }
382
383 if (0 >= handle->data_size)
384 {
385 GNUNET_break(0);
386 handle->proc (handle->proc_cls, NULL, 0, GNUNET_SYSERR);
387 cleanup_handle (handle);
388 return;
389 }
390
391 term_data[handle->data_size] = '\0';
392 memcpy (term_data, handle->data, handle->data_size);
393 root_json = json_loads (term_data, 0, &error);
394
395 if ((NULL == root_json) || !json_is_object (root_json))
396 {
397 GNUNET_break(0);
398 handle->proc (handle->proc_cls, NULL, 0, GNUNET_SYSERR);
399 cleanup_handle (handle);
400 return;
401 }
402 subsys_json = json_object_get (root_json, "subsystem");
403 if (!json_is_string (subsys_json))
404 {
405 GNUNET_break(0);
406 handle->proc (handle->proc_cls, NULL, 0, GNUNET_SYSERR);
407 cleanup_handle (handle);
408 return;
409 }
410 subsys = json_string_value (subsys_json);
411 GNUNET_asprintf (&handle->subsys, "%s", subsys);
412 json_decref (subsys_json);
413 json_decref (root_json);
414 handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
415 handle->subsys,
416 ego_entry->ego,
417 &do_finished,
418 handle);
363} 419}
364 420
365void 421void
@@ -397,7 +453,7 @@ ego_delete_cont (struct RequestHandle *handle)
397 } 453 }
398 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, 454 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
399 egoname, 455 egoname,
400 &delete_finished, 456 &do_finished,
401 handle); 457 handle);
402 458
403} 459}
@@ -466,41 +522,13 @@ list_ego (void *cls,
466 return; 522 return;
467 } 523 }
468 if (ID_REST_STATE_INIT == handle->state) { 524 if (ID_REST_STATE_INIT == handle->state) {
469 ego_entry = GNUNET_new (struct EgoEntry); 525 ego_entry = GNUNET_new (struct EgoEntry);
470 GNUNET_IDENTITY_ego_get_public_key (ego, &(ego_entry->pk)); 526 GNUNET_IDENTITY_ego_get_public_key (ego, &(ego_entry->pk));
527 ego_entry->ego = ego;
471 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); 528 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
472 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry); 529 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
473 } 530 }
474 531
475 if ( (NULL == handle->set_ego) &&
476 (NULL != ego) &&
477 (NULL != identifier) &&
478 (0 == strcmp (identifier,
479 handle->set_ego)) )
480 {
481 /*handle->set_op = GNUNET_IDENTITY_set (sh,
482 handle->set_subsystem,
483 ego,
484 &set_done,
485 handle);
486 GNUNET_free (handle->set_subsystem);
487 handle->set_subsystem = NULL;
488 GNUNET_free (handle->set_ego); //decref?
489 handle->set_ego = NULL;TODO*/
490 }
491 if ( (NULL == ego) &&
492 (NULL != handle->set_ego) )
493 {
494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
495 "Could not set ego to `%s' for subsystem `%s', ego not known\n",
496 handle->set_ego,
497 handle->set_subsystem);
498 GNUNET_free (handle->set_subsystem);
499 handle->set_subsystem = NULL;
500 GNUNET_free (handle->set_ego); //decref?
501 handle->set_ego = NULL;
502 }
503
504} 532}
505 533
506/** 534/**
@@ -515,12 +543,9 @@ list_ego (void *cls,
515 * @return GNUNET_OK if request accepted 543 * @return GNUNET_OK if request accepted
516 */ 544 */
517void 545void
518rest_identity_process_request(const char *method, 546rest_identity_process_request(struct RestConnectionDataHandle *conndata_handle,
519 const char *url, 547 GNUNET_REST_ResultProcessor proc,
520 const char *data, 548 void *proc_cls)
521 size_t data_size,
522 GNUNET_REST_ResultProcessor proc,
523 void *proc_cls)
524{ 549{
525 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 550 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
526 551
@@ -533,15 +558,19 @@ rest_identity_process_request(const char *method,
533 handle->state = ID_REST_STATE_INIT; 558 handle->state = ID_REST_STATE_INIT;
534 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 559 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
535 "Connecting...\n"); 560 "Connecting...\n");
536 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); 561 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
537 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, 562 &list_ego,
538 &do_error, handle); 563 handle);
539 handle->data = data; 564 handle->timeout_task =
540 handle->data_size = data_size; 565 GNUNET_SCHEDULER_add_delayed (handle->timeout,
541 handle->url = url; 566 &do_error,
567 handle);
568 handle->data = conndata_handle->data;
569 handle->data_size = conndata_handle->data_size;
570 handle->url = conndata_handle->url;
542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
543 "Connected\n"); 572 "Connected\n");
544 handle->method = method; 573 handle->method = conndata_handle->method;
545} 574}
546 575
547/** 576/**
diff --git a/src/include/gnunet_rest_plugin.h b/src/include/gnunet_rest_plugin.h
index d690343ba..a7318e628 100644
--- a/src/include/gnunet_rest_plugin.h
+++ b/src/include/gnunet_rest_plugin.h
@@ -1,22 +1,22 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors) 3 Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 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 7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version. 8 option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 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 16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19 */
20/** 20/**
21 * @author Martin Schanzenbach 21 * @author Martin Schanzenbach
22 * @file include/gnunet_rest_plugin.h 22 * @file include/gnunet_rest_plugin.h
@@ -45,9 +45,19 @@ extern "C"
45 * @param status status code (HTTP) 45 * @param status status code (HTTP)
46 */ 46 */
47typedef void (*GNUNET_REST_ResultProcessor) (void *cls, 47typedef void (*GNUNET_REST_ResultProcessor) (void *cls,
48 const char *data, 48 const char *data,
49 size_t data_len, 49 size_t data_len,
50 int status); 50 int status);
51
52struct RestConnectionDataHandle
53{
54 struct GNUNET_CONTAINER_MultiHashMap *url_param_map;
55 const char *method;
56 const char *url;
57 const char *data;
58 size_t data_size;
59
60};
51 61
52/** 62/**
53 * @brief struct returned by the initialization function of the plugin 63 * @brief struct returned by the initialization function of the plugin
@@ -61,7 +71,7 @@ struct GNUNET_REST_Plugin
61 * 71 *
62 */ 72 */
63 void *cls; 73 void *cls;
64 74
65 /** 75 /**
66 * Plugin name. Used as the namespace for the API. 76 * Plugin name. Used as the namespace for the API.
67 * e.g. http://hostname:port/<name> 77 * e.g. http://hostname:port/<name>
@@ -78,12 +88,9 @@ struct GNUNET_REST_Plugin
78 * @param proc the callback for result 88 * @param proc the callback for result
79 * @param proc_cls closure for callback 89 * @param proc_cls closure for callback
80 */ 90 */
81 void (*process_request) (const char *method, 91 void (*process_request) (struct RestConnectionDataHandle *handle,
82 const char *url, 92 GNUNET_REST_ResultProcessor proc,
83 const char *data, 93 void *proc_cls);
84 size_t data_size,
85 GNUNET_REST_ResultProcessor proc,
86 void *proc_cls);
87 94
88}; 95};
89 96
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index e2f1f5c57..4af7c458b 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -56,8 +56,7 @@
56#define MHD_CACHE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 56#define MHD_CACHE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
57 57
58#define GN_REST_STATE_INIT 0 58#define GN_REST_STATE_INIT 0
59#define GN_REST_STATE_UPLOAD 1 59#define GN_REST_STATE_PROCESSING 1
60#define GN_REST_STATE_RECV 2
61 60
62/** 61/**
63 * The task ID 62 * The task ID
@@ -125,6 +124,8 @@ struct MhdConnectionHandle
125 124
126 struct GNUNET_REST_Plugin *plugin; 125 struct GNUNET_REST_Plugin *plugin;
127 126
127 struct RestConnectionDataHandle *data_handle;
128
128 int status; 129 int status;
129 130
130 int state; 131 int state;
@@ -181,6 +182,64 @@ plugin_callback (void *cls,
181 run_mhd_now(); 182 run_mhd_now();
182} 183}
183 184
185int
186cleanup_url_map (void *cls,
187 const struct GNUNET_HashCode *key,
188 void *value)
189{
190 GNUNET_free_non_null (value);
191 return GNUNET_YES;
192}
193
194void
195cleanup_handle (struct MhdConnectionHandle *handle)
196{
197 if (NULL != handle->response)
198 MHD_destroy_response (handle->response);
199 if (NULL != handle->data_handle)
200 {
201 if (NULL != handle->data_handle->url_param_map)
202 {
203 GNUNET_CONTAINER_multihashmap_iterate (handle->data_handle->url_param_map,
204 &cleanup_url_map,
205 NULL);
206 GNUNET_CONTAINER_multihashmap_destroy (handle->data_handle->url_param_map);
207 }
208 GNUNET_free (handle->data_handle);
209 }
210 GNUNET_free (handle);
211
212}
213
214int
215url_iterator (void *cls,
216 enum MHD_ValueKind kind,
217 const char *key,
218 const char *value)
219{
220 struct RestConnectionDataHandle *handle = cls;
221 struct GNUNET_HashCode hkey;
222 char *val;
223 if (NULL == handle->url_param_map)
224 {
225 handle->url_param_map = GNUNET_CONTAINER_multihashmap_create (16,
226 GNUNET_NO);
227 }
228 GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
229 GNUNET_asprintf (&val, "%s", value);
230 if (GNUNET_OK !=
231 GNUNET_CONTAINER_multihashmap_put (handle->url_param_map,
232 &hkey,
233 val,
234 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
235 {
236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
237 "Could not load add url param `%s'=%s\n",
238 key, value);
239 }
240 return MHD_YES;
241}
242
184/* ********************************* MHD response generation ******************* */ 243/* ********************************* MHD response generation ******************* */
185 244
186/** 245/**
@@ -219,6 +278,7 @@ create_response (void *cls,
219 char *plugin_name; 278 char *plugin_name;
220 struct GNUNET_HashCode key; 279 struct GNUNET_HashCode key;
221 struct MhdConnectionHandle *con_handle; 280 struct MhdConnectionHandle *con_handle;
281 struct RestConnectionDataHandle *rest_conndata_handle;
222 282
223 con_handle = *con_cls; 283 con_handle = *con_cls;
224 284
@@ -258,29 +318,22 @@ create_response (void *cls,
258 } 318 }
259 if (GN_REST_STATE_INIT == con_handle->state) 319 if (GN_REST_STATE_INIT == con_handle->state)
260 { 320 {
261 if (0 != *upload_data_size) 321 rest_conndata_handle = GNUNET_new (struct RestConnectionDataHandle);
262 { 322 rest_conndata_handle->method = meth;
263 con_handle->state = GN_REST_STATE_UPLOAD; 323 rest_conndata_handle->url = url;
264 324 rest_conndata_handle->data = upload_data;
265 con_handle->plugin->process_request (meth, 325 rest_conndata_handle->data_size = *upload_data_size;
266 url, 326 con_handle->data_handle = rest_conndata_handle;
267 upload_data, 327 MHD_get_connection_values (con,
268 *upload_data_size, 328 MHD_GET_ARGUMENT_KIND,
269 &plugin_callback, 329 &url_iterator,
270 con_handle); 330 rest_conndata_handle);
271 *upload_data_size = 0; 331 con_handle->state = GN_REST_STATE_PROCESSING;
332 con_handle->plugin->process_request (rest_conndata_handle,
333 &plugin_callback,
334 con_handle);
335 *upload_data_size = 0;
272 336
273 }
274 else
275 {
276 con_handle->state = GN_REST_STATE_RECV;
277 con_handle->plugin->process_request (meth,
278 url,
279 NULL,
280 0,
281 &plugin_callback,
282 con_handle);
283 }
284 } 337 }
285 if (NULL != con_handle->response) 338 if (NULL != con_handle->response)
286 { 339 {
@@ -296,6 +349,7 @@ create_response (void *cls,
296 MHD_HTTP_BAD_REQUEST, 349 MHD_HTTP_BAD_REQUEST,
297 con_handle->response); 350 con_handle->response);
298 } 351 }
352 cleanup_handle (con_handle);
299 } 353 }
300 return MHD_YES; 354 return MHD_YES;
301} 355}