diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-04-30 15:56:16 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-04-30 15:56:16 +0200 |
commit | 342619bf17d389e4305c9ee72b609059706a8023 (patch) | |
tree | 391ff802b3d7389a08947dfb2e2fc816f4013752 | |
parent | 57636ddf7839aaeedd14c90afcd28b375ec516a6 (diff) | |
download | gnunet-342619bf17d389e4305c9ee72b609059706a8023.tar.gz gnunet-342619bf17d389e4305c9ee72b609059706a8023.zip |
REST/NAMESTORE: rework API
-rw-r--r-- | src/include/gnunet_json_lib.h | 11 | ||||
-rw-r--r-- | src/json/json_generator.c | 78 | ||||
-rw-r--r-- | src/json/json_gnsrecord.c | 232 | ||||
-rw-r--r-- | src/namestore/plugin_rest_namestore.c | 228 |
4 files changed, 222 insertions, 327 deletions
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index 640ffa35a..c8f09d4e4 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -11,7 +11,7 @@ | |||
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 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -329,7 +329,9 @@ GNUNET_JSON_spec_rsa_signature (const char *name, | |||
329 | * @return JSON Specification | 329 | * @return JSON Specification |
330 | */ | 330 | */ |
331 | struct GNUNET_JSON_Specification | 331 | struct GNUNET_JSON_Specification |
332 | GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data **gnsrecord_object); | 332 | GNUNET_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, |
333 | unsigned int *rd_count, | ||
334 | char **name); | ||
333 | 335 | ||
334 | 336 | ||
335 | /* ****************** Generic generator interface ******************* */ | 337 | /* ****************** Generic generator interface ******************* */ |
@@ -415,8 +417,9 @@ GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig); | |||
415 | * @return corresponding JSON encoding | 417 | * @return corresponding JSON encoding |
416 | */ | 418 | */ |
417 | json_t * | 419 | json_t * |
418 | GNUNET_JSON_from_gns_record (const char* rname, | 420 | GNUNET_JSON_from_gnsrecord (const char* rname, |
419 | const struct GNUNET_GNSRECORD_Data *rd); | 421 | const struct GNUNET_GNSRECORD_Data *rd, |
422 | unsigned int rd_count); | ||
420 | 423 | ||
421 | /* ******************* Helpers for MHD upload handling ******************* */ | 424 | /* ******************* Helpers for MHD upload handling ******************* */ |
422 | 425 | ||
diff --git a/src/json/json_generator.c b/src/json/json_generator.c index 0b25013e3..de6898da6 100644 --- a/src/json/json_generator.c +++ b/src/json/json_generator.c | |||
@@ -11,7 +11,7 @@ | |||
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 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -160,58 +160,56 @@ GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | /** | 162 | /** |
163 | * Convert Gns record to JSON. | 163 | * Convert GNS record to JSON. |
164 | * | 164 | * |
165 | * @param rname name of record | 165 | * @param rname name of record |
166 | * @param rd record data | 166 | * @param rd record data |
167 | * @return corresponding JSON encoding | 167 | * @return corresponding JSON encoding |
168 | */ | 168 | */ |
169 | json_t * | 169 | json_t * |
170 | GNUNET_JSON_from_gns_record (const char* rname, | 170 | GNUNET_JSON_from_gnsrecord (const char* rname, |
171 | const struct GNUNET_GNSRECORD_Data *rd) | 171 | const struct GNUNET_GNSRECORD_Data *rd, |
172 | unsigned int rd_count) | ||
172 | { | 173 | { |
173 | struct GNUNET_TIME_Absolute expiration_time; | 174 | struct GNUNET_TIME_Absolute expiration_time; |
174 | const char *expiration_time_str; | 175 | const char *expiration_time_str; |
175 | const char *record_type_str; | 176 | const char *record_type_str; |
176 | char *value_str; | 177 | char *value_str; |
177 | json_t *ret; | 178 | json_t *data; |
178 | int flags; | 179 | json_t *record; |
179 | 180 | json_t *records; | |
180 | value_str = GNUNET_GNSRECORD_value_to_string(rd->record_type,rd->data,rd->data_size); | 181 | |
181 | expiration_time = GNUNET_GNSRECORD_record_get_expiration_time(1, rd); | 182 | data = json_object (); |
182 | expiration_time_str = GNUNET_STRINGS_absolute_time_to_string(expiration_time); | 183 | json_object_set_new (data, |
183 | flags = (int)rd->flags; //maybe necessary | 184 | "record_name", |
184 | record_type_str = GNUNET_GNSRECORD_number_to_typename(rd->record_type); | 185 | json_string (rname)); |
185 | 186 | records = json_array (); | |
186 | // ? for possible NULL values | 187 | for (int i = 0; i < rd_count; i++) |
187 | if (NULL != rname) | ||
188 | { | 188 | { |
189 | ret = json_pack ("{s:s?,s:s?,s:s?,s:i,s:s?}", | 189 | value_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, |
190 | "value", | 190 | rd[i].data, |
191 | value_str, | 191 | rd[i].data_size); |
192 | "record_type", | 192 | expiration_time = GNUNET_GNSRECORD_record_get_expiration_time(1, &rd[i]); |
193 | record_type_str, | 193 | expiration_time_str = GNUNET_STRINGS_absolute_time_to_string (expiration_time); |
194 | "expiration_time", | 194 | record_type_str = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); |
195 | expiration_time_str, | 195 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
196 | "flag", | 196 | "Packing %s %s %s %d\n", |
197 | flags, | 197 | value_str, record_type_str, expiration_time_str, rd[i].flags); |
198 | "record_name", | 198 | record = json_pack ("{s:s,s:s,s:s,s:i}", |
199 | rname); | 199 | "value", |
200 | value_str, | ||
201 | "record_type", | ||
202 | record_type_str, | ||
203 | "expiration_time", | ||
204 | expiration_time_str, | ||
205 | "flag", | ||
206 | rd[i].flags); | ||
207 | GNUNET_assert (NULL != record); | ||
208 | GNUNET_free (value_str); | ||
209 | json_array_append_new (records, record); | ||
200 | } | 210 | } |
201 | else | 211 | json_object_set_new (data, "data", records); |
202 | { | 212 | return data; |
203 | ret = json_pack ("{s:s?,s:s?,s:s?,s:i}", | ||
204 | "value", | ||
205 | value_str, | ||
206 | "record_type", | ||
207 | record_type_str, | ||
208 | "expiration_time", | ||
209 | expiration_time_str, | ||
210 | "flag", | ||
211 | flags); | ||
212 | } | ||
213 | GNUNET_free_non_null(value_str); | ||
214 | return ret; | ||
215 | } | 213 | } |
216 | 214 | ||
217 | 215 | ||
diff --git a/src/json/json_gnsrecord.c b/src/json/json_gnsrecord.c index cbdc0ff91..eef9e0e79 100644 --- a/src/json/json_gnsrecord.c +++ b/src/json/json_gnsrecord.c | |||
@@ -28,12 +28,46 @@ | |||
28 | #include "gnunet_json_lib.h" | 28 | #include "gnunet_json_lib.h" |
29 | 29 | ||
30 | #define GNUNET_JSON_GNSRECORD_VALUE "value" | 30 | #define GNUNET_JSON_GNSRECORD_VALUE "value" |
31 | #define GNUNET_JSON_GNSRECORD_RECORD_DATA "data" | ||
31 | #define GNUNET_JSON_GNSRECORD_TYPE "record_type" | 32 | #define GNUNET_JSON_GNSRECORD_TYPE "record_type" |
32 | #define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time" | 33 | #define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time" |
33 | #define GNUNET_JSON_GNSRECORD_FLAG "flag" | 34 | #define GNUNET_JSON_GNSRECORD_FLAG "flag" |
34 | #define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name" | 35 | #define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name" |
35 | #define GNUNET_JSON_GNSRECORD_NEVER "never" | 36 | #define GNUNET_JSON_GNSRECORD_NEVER "never" |
36 | 37 | ||
38 | struct GnsRecordInfo | ||
39 | { | ||
40 | char **name; | ||
41 | |||
42 | unsigned int *rd_count; | ||
43 | |||
44 | struct GNUNET_GNSRECORD_Data **rd; | ||
45 | }; | ||
46 | |||
47 | |||
48 | static void | ||
49 | cleanup_recordinfo (struct GnsRecordInfo *gnsrecord_info) | ||
50 | { | ||
51 | if (NULL != gnsrecord_info) | ||
52 | { | ||
53 | if (NULL != *(gnsrecord_info->rd)) | ||
54 | { | ||
55 | for (int i = 0; i < *(gnsrecord_info->rd_count); i++) | ||
56 | { | ||
57 | if (NULL != (*(gnsrecord_info->rd))[i].data) | ||
58 | GNUNET_free ((char *) (*(gnsrecord_info->rd))[i].data); | ||
59 | } | ||
60 | GNUNET_free (*(gnsrecord_info->rd)); | ||
61 | *(gnsrecord_info->rd) = NULL; | ||
62 | } | ||
63 | if (NULL != *(gnsrecord_info->name)) | ||
64 | GNUNET_free (*(gnsrecord_info->name)); | ||
65 | *(gnsrecord_info->name) = NULL; | ||
66 | GNUNET_free (gnsrecord_info); | ||
67 | } | ||
68 | |||
69 | } | ||
70 | |||
37 | 71 | ||
38 | /** | 72 | /** |
39 | * Parse given JSON object to gns record | 73 | * Parse given JSON object to gns record |
@@ -44,114 +78,156 @@ | |||
44 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 78 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
45 | */ | 79 | */ |
46 | static int | 80 | static int |
47 | parse_gnsrecordobject (void *cls, | 81 | parse_record (json_t *data, struct GNUNET_GNSRECORD_Data *rd) |
48 | json_t *root, | ||
49 | struct GNUNET_JSON_Specification *spec) | ||
50 | { | 82 | { |
51 | struct GNUNET_GNSRECORD_Data *gnsrecord_object; | ||
52 | struct GNUNET_TIME_Absolute abs_expiration_time; | 83 | struct GNUNET_TIME_Absolute abs_expiration_time; |
53 | struct GNUNET_TIME_Relative rel_expiration_time; | 84 | struct GNUNET_TIME_Relative rel_expiration_time; |
54 | int unpack_state=0; | ||
55 | const char *value; | 85 | const char *value; |
56 | const char *expiration_time; | ||
57 | const char *record_type; | 86 | const char *record_type; |
58 | const char *name; | 87 | const char *expiration_time; |
59 | int flag; | 88 | int flag; |
60 | void *rdata = NULL; | 89 | int unpack_state = 0; |
61 | size_t rdata_size; | ||
62 | 90 | ||
63 | GNUNET_assert(NULL != root); | ||
64 | if(!json_is_object(root)) | ||
65 | { | ||
66 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
67 | "Error json is not array nor object!\n"); | ||
68 | return GNUNET_SYSERR; | ||
69 | } | ||
70 | //interpret single gns record | 91 | //interpret single gns record |
71 | unpack_state = json_unpack(root, | 92 | unpack_state = json_unpack (data, |
72 | "{s:s, s:s, s:s, s?:i, s:s!}", | 93 | "{s:s, s:s, s:s, s?:i!}", |
73 | GNUNET_JSON_GNSRECORD_VALUE, &value, | 94 | GNUNET_JSON_GNSRECORD_VALUE, |
74 | GNUNET_JSON_GNSRECORD_TYPE, &record_type, | 95 | &value, |
75 | GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, &expiration_time, | 96 | GNUNET_JSON_GNSRECORD_TYPE, |
76 | GNUNET_JSON_GNSRECORD_FLAG, &flag, | 97 | &record_type, |
77 | GNUNET_JSON_GNSRECORD_RECORD_NAME, &name); | 98 | GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, |
99 | &expiration_time, | ||
100 | GNUNET_JSON_GNSRECORD_FLAG, | ||
101 | &flag); | ||
78 | if (0 != unpack_state) | 102 | if (0 != unpack_state) |
79 | { | 103 | { |
80 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 104 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
81 | "Error json object has a wrong format!\n"); | 105 | "Error gnsdata object has a wrong format!\n"); |
82 | return GNUNET_SYSERR; | 106 | return GNUNET_SYSERR; |
83 | } | 107 | } |
84 | gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data); | 108 | rd->record_type = GNUNET_GNSRECORD_typename_to_number (record_type); |
85 | gnsrecord_object->record_type = GNUNET_GNSRECORD_typename_to_number(record_type); | 109 | if (UINT32_MAX == rd->record_type) |
86 | if (UINT32_MAX == gnsrecord_object->record_type) | ||
87 | { | 110 | { |
88 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Unsupported type\n"); | 111 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n"); |
89 | GNUNET_free(gnsrecord_object); | ||
90 | return GNUNET_SYSERR; | 112 | return GNUNET_SYSERR; |
91 | } | 113 | } |
92 | if (GNUNET_OK | 114 | if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (rd->record_type, |
93 | != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type, | 115 | value, |
94 | value, | 116 | (void**)&rd->data, |
95 | &rdata, | 117 | &rd->data_size)) |
96 | &rdata_size)) | ||
97 | { | 118 | { |
98 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Value invalid for record type\n"); | 119 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n"); |
99 | GNUNET_free(gnsrecord_object); | ||
100 | return GNUNET_SYSERR; | 120 | return GNUNET_SYSERR; |
101 | } | 121 | } |
102 | 122 | ||
103 | gnsrecord_object->data = rdata; | ||
104 | gnsrecord_object->data_size = rdata_size; | ||
105 | |||
106 | if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER)) | 123 | if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER)) |
107 | { | 124 | { |
108 | gnsrecord_object->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | 125 | rd->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; |
109 | } | 126 | } |
110 | else if (GNUNET_OK | 127 | else if (GNUNET_OK == |
111 | == GNUNET_STRINGS_fancy_time_to_absolute (expiration_time, | 128 | GNUNET_STRINGS_fancy_time_to_absolute (expiration_time, |
112 | &abs_expiration_time)) | 129 | &abs_expiration_time)) |
113 | { | 130 | { |
114 | gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us; | 131 | rd->expiration_time = abs_expiration_time.abs_value_us; |
115 | } | 132 | } |
116 | else if (GNUNET_OK | 133 | else if (GNUNET_OK == |
117 | == GNUNET_STRINGS_fancy_time_to_relative (expiration_time, | 134 | GNUNET_STRINGS_fancy_time_to_relative (expiration_time, |
118 | &rel_expiration_time)) | 135 | &rel_expiration_time)) |
119 | { | 136 | { |
120 | gnsrecord_object->expiration_time = rel_expiration_time.rel_value_us; | 137 | rd->expiration_time = rel_expiration_time.rel_value_us; |
121 | } | 138 | } |
122 | else | 139 | else |
123 | { | 140 | { |
124 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expiration time invalid\n"); | 141 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expiration time invalid\n"); |
125 | GNUNET_free_non_null(rdata); | ||
126 | GNUNET_free(gnsrecord_object); | ||
127 | return GNUNET_SYSERR; | 142 | return GNUNET_SYSERR; |
128 | } | 143 | } |
129 | gnsrecord_object->flags = (enum GNUNET_GNSRECORD_Flags)flag; | 144 | rd->flags = (enum GNUNET_GNSRECORD_Flags) flag; |
130 | *(struct GNUNET_GNSRECORD_Data **) spec->ptr = gnsrecord_object; | ||
131 | return GNUNET_OK; | 145 | return GNUNET_OK; |
132 | } | 146 | } |
133 | 147 | ||
148 | |||
134 | /** | 149 | /** |
135 | * Cleanup data left from parsing RSA public key. | 150 | * Parse given JSON object to gns record |
136 | * | 151 | * |
137 | * @param cls closure, NULL | 152 | * @param cls closure, NULL |
138 | * @param[out] spec where to free the data | 153 | * @param root the json object representing data |
154 | * @param spec where to write the data | ||
155 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | ||
139 | */ | 156 | */ |
140 | static void | 157 | static int |
141 | clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) | 158 | parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data) |
142 | { | 159 | { |
143 | struct GNUNET_GNSRECORD_Data **gnsrecord_object; | 160 | GNUNET_assert (NULL != data); |
144 | gnsrecord_object = (struct GNUNET_GNSRECORD_Data **) spec->ptr; | 161 | if (! json_is_array (data)) |
145 | if (NULL != *gnsrecord_object) | ||
146 | { | 162 | { |
147 | if (NULL != (*gnsrecord_object)->data) | 163 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
148 | GNUNET_free((char*)(*gnsrecord_object)->data); | 164 | "Error gns record data JSON is not an array!\n"); |
165 | return GNUNET_SYSERR; | ||
166 | } | ||
167 | *(gnsrecord_info->rd_count) = json_array_size (data); | ||
168 | *(gnsrecord_info->rd) = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * | ||
169 | json_array_size (data)); | ||
170 | size_t index; | ||
171 | json_t *value; | ||
172 | json_array_foreach (data, index, value) | ||
173 | { | ||
174 | if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index])) | ||
175 | return GNUNET_SYSERR; | ||
176 | } | ||
177 | return GNUNET_OK; | ||
178 | } | ||
149 | 179 | ||
150 | GNUNET_free(*gnsrecord_object); | 180 | |
151 | *gnsrecord_object = NULL; | 181 | static int |
182 | parse_gnsrecordobject (void *cls, | ||
183 | json_t *root, | ||
184 | struct GNUNET_JSON_Specification *spec) | ||
185 | { | ||
186 | struct GnsRecordInfo *gnsrecord_info; | ||
187 | int unpack_state = 0; | ||
188 | const char *name; | ||
189 | json_t *data; | ||
190 | |||
191 | GNUNET_assert (NULL != root); | ||
192 | if (! json_is_object (root)) | ||
193 | { | ||
194 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
195 | "Error record JSON is not an object!\n"); | ||
196 | return GNUNET_SYSERR; | ||
197 | } | ||
198 | //interpret single gns record | ||
199 | unpack_state = json_unpack (root, | ||
200 | "{s:s, s:o!}", | ||
201 | GNUNET_JSON_GNSRECORD_RECORD_NAME, | ||
202 | &name, | ||
203 | GNUNET_JSON_GNSRECORD_RECORD_DATA, | ||
204 | &data); | ||
205 | if (0 != unpack_state) | ||
206 | { | ||
207 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
208 | "Error namestore records object has a wrong format!\n"); | ||
209 | return GNUNET_SYSERR; | ||
152 | } | 210 | } |
211 | gnsrecord_info = (struct GnsRecordInfo *) spec->ptr; | ||
212 | *(gnsrecord_info->name) = GNUNET_strdup (name); | ||
213 | return parse_record_data (gnsrecord_info, data); | ||
153 | } | 214 | } |
154 | 215 | ||
216 | |||
217 | /** | ||
218 | * Cleanup data left from parsing the record. | ||
219 | * | ||
220 | * @param cls closure, NULL | ||
221 | * @param[out] spec where to free the data | ||
222 | */ | ||
223 | static void | ||
224 | clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) | ||
225 | { | ||
226 | struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr; | ||
227 | cleanup_recordinfo (gnsrecord_info); | ||
228 | } | ||
229 | |||
230 | |||
155 | /** | 231 | /** |
156 | * JSON Specification for GNS Records. | 232 | * JSON Specification for GNS Records. |
157 | * | 233 | * |
@@ -159,17 +235,21 @@ clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) | |||
159 | * @return JSON Specification | 235 | * @return JSON Specification |
160 | */ | 236 | */ |
161 | struct GNUNET_JSON_Specification | 237 | struct GNUNET_JSON_Specification |
162 | GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data **gnsrecord_object) | 238 | GNUNET_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, |
239 | unsigned int *rd_count, | ||
240 | char **name) | ||
163 | { | 241 | { |
164 | struct GNUNET_JSON_Specification ret = { | 242 | struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo); |
165 | .parser = &parse_gnsrecordobject, | 243 | gnsrecord_info->rd = rd; |
166 | .cleaner = &clean_gnsrecordobject, | 244 | gnsrecord_info->name = name; |
167 | .cls = NULL, | 245 | gnsrecord_info->rd_count = rd_count; |
168 | .field = NULL, | 246 | struct GNUNET_JSON_Specification ret = {.parser = &parse_gnsrecordobject, |
169 | .ptr = gnsrecord_object, | 247 | .cleaner = &clean_gnsrecordobject, |
170 | .ptr_size = 0, | 248 | .cls = NULL, |
171 | .size_ptr = NULL | 249 | .field = NULL, |
172 | }; | 250 | .ptr = (struct GnsRecordInfo *) |
173 | *gnsrecord_object = NULL; | 251 | gnsrecord_info, |
252 | .ptr_size = 0, | ||
253 | .size_ptr = NULL}; | ||
174 | return ret; | 254 | return ret; |
175 | } | 255 | } |
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index 46e5a590f..39b21c233 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c | |||
@@ -49,10 +49,6 @@ | |||
49 | */ | 49 | */ |
50 | #define GNUNET_REST_IDENTITY_NOT_FOUND "No identity found" | 50 | #define GNUNET_REST_IDENTITY_NOT_FOUND "No identity found" |
51 | 51 | ||
52 | /** | ||
53 | * Error message No default zone specified | ||
54 | */ | ||
55 | #define GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE "No default zone specified" | ||
56 | 52 | ||
57 | /** | 53 | /** |
58 | * Error message Failed request | 54 | * Error message Failed request |
@@ -143,6 +139,11 @@ struct RequestHandle | |||
143 | struct GNUNET_GNSRECORD_Data *rd; | 139 | struct GNUNET_GNSRECORD_Data *rd; |
144 | 140 | ||
145 | /** | 141 | /** |
142 | * Number of records in rd | ||
143 | */ | ||
144 | unsigned int rd_count; | ||
145 | |||
146 | /** | ||
146 | * NAMESTORE Operation | 147 | * NAMESTORE Operation |
147 | */ | 148 | */ |
148 | struct GNUNET_NAMESTORE_QueueEntry *add_qe; | 149 | struct GNUNET_NAMESTORE_QueueEntry *add_qe; |
@@ -263,8 +264,11 @@ cleanup_handle (void *cls) | |||
263 | GNUNET_free (handle->emsg); | 264 | GNUNET_free (handle->emsg); |
264 | if (NULL != handle->rd) | 265 | if (NULL != handle->rd) |
265 | { | 266 | { |
266 | if (NULL != handle->rd->data) | 267 | for (int i = 0; i < handle->rd_count; i++) |
267 | GNUNET_free ((void *) handle->rd->data); | 268 | { |
269 | if (NULL != handle->rd[i].data) | ||
270 | GNUNET_free ((void *) handle->rd[i].data); | ||
271 | } | ||
268 | GNUNET_free (handle->rd); | 272 | GNUNET_free (handle->rd); |
269 | } | 273 | } |
270 | if (NULL != handle->timeout_task) | 274 | if (NULL != handle->timeout_task) |
@@ -484,68 +488,13 @@ namestore_list_iteration (void *cls, | |||
484 | 488 | ||
485 | if (NULL == handle->resp_object) | 489 | if (NULL == handle->resp_object) |
486 | handle->resp_object = json_array (); | 490 | handle->resp_object = json_array (); |
487 | 491 | record_obj = GNUNET_JSON_from_gnsrecord (rname, | |
488 | for (unsigned int i = 0; i < rd_len; i++) | 492 | rd, |
489 | { | 493 | rd_len); |
490 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && | 494 | json_array_append_new (handle->resp_object, record_obj); |
491 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) | ||
492 | continue; | ||
493 | |||
494 | record_obj = GNUNET_JSON_from_gns_record (rname, &rd[i]); | ||
495 | |||
496 | if (NULL == record_obj) | ||
497 | continue; | ||
498 | |||
499 | json_array_append (handle->resp_object, record_obj); | ||
500 | json_decref (record_obj); | ||
501 | } | ||
502 | |||
503 | GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1); | 495 | GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1); |
504 | } | 496 | } |
505 | 497 | ||
506 | /** | ||
507 | * @param cls closure | ||
508 | * @param ego ego handle | ||
509 | * @param ctx context for application to store data for this ego | ||
510 | * (during the lifetime of this process, initially NULL) | ||
511 | * @param identifier identifier assigned by the user for this ego, | ||
512 | * NULL if the user just deleted the ego and it | ||
513 | * must thus no longer be used | ||
514 | */ | ||
515 | static void | ||
516 | default_ego_get (void *cls, | ||
517 | struct GNUNET_IDENTITY_Ego *ego, | ||
518 | void **ctx, | ||
519 | const char *identifier) | ||
520 | { | ||
521 | struct RequestHandle *handle = cls; | ||
522 | handle->op = NULL; | ||
523 | |||
524 | if (ego == NULL) | ||
525 | { | ||
526 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE); | ||
527 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
528 | return; | ||
529 | } | ||
530 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
531 | |||
532 | handle->list_it = | ||
533 | GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, | ||
534 | handle->zone_pkey, | ||
535 | &namestore_iteration_error, | ||
536 | handle, | ||
537 | &namestore_list_iteration, | ||
538 | handle, | ||
539 | &namestore_list_finished, | ||
540 | handle); | ||
541 | if (NULL == handle->list_it) | ||
542 | { | ||
543 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED); | ||
544 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
545 | return; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | 498 | ||
550 | /** | 499 | /** |
551 | * Handle namestore GET request | 500 | * Handle namestore GET request |
@@ -581,18 +530,8 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, | |||
581 | } | 530 | } |
582 | } | 531 | } |
583 | if (NULL != ego_entry) | 532 | if (NULL != ego_entry) |
584 | { | ||
585 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 533 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
586 | } | ||
587 | 534 | ||
588 | if (NULL == handle->zone_pkey) | ||
589 | { | ||
590 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | ||
591 | "namestore", | ||
592 | &default_ego_get, | ||
593 | handle); | ||
594 | return; | ||
595 | } | ||
596 | handle->list_it = | 535 | handle->list_it = |
597 | GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, | 536 | GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, |
598 | handle->zone_pkey, | 537 | handle->zone_pkey, |
@@ -611,48 +550,6 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, | |||
611 | } | 550 | } |
612 | 551 | ||
613 | 552 | ||
614 | /** | ||
615 | * @param cls closure | ||
616 | * @param ego ego handle | ||
617 | * @param ctx context for application to store data for this ego | ||
618 | * (during the lifetime of this process, initially NULL) | ||
619 | * @param identifier identifier assigned by the user for this ego, | ||
620 | * NULL if the user just deleted the ego and it | ||
621 | * must thus no longer be used | ||
622 | */ | ||
623 | static void | ||
624 | default_ego_post (void *cls, | ||
625 | struct GNUNET_IDENTITY_Ego *ego, | ||
626 | void **ctx, | ||
627 | const char *identifier) | ||
628 | { | ||
629 | struct RequestHandle *handle = cls; | ||
630 | handle->op = NULL; | ||
631 | |||
632 | if (ego == NULL) | ||
633 | { | ||
634 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE); | ||
635 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
636 | return; | ||
637 | } | ||
638 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
639 | |||
640 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | ||
641 | handle->zone_pkey, | ||
642 | handle->record_name, | ||
643 | 1, | ||
644 | handle->rd, | ||
645 | &create_finished, | ||
646 | handle); | ||
647 | if (NULL == handle->add_qe) | ||
648 | { | ||
649 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED); | ||
650 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
651 | return; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | |||
656 | static void | 553 | static void |
657 | ns_lookup_error_cb (void *cls) | 554 | ns_lookup_error_cb (void *cls) |
658 | { | 555 | { |
@@ -670,14 +567,15 @@ ns_lookup_cb (void *cls, | |||
670 | const struct GNUNET_GNSRECORD_Data *rd) | 567 | const struct GNUNET_GNSRECORD_Data *rd) |
671 | { | 568 | { |
672 | struct RequestHandle *handle = cls; | 569 | struct RequestHandle *handle = cls; |
673 | struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1]; | 570 | struct GNUNET_GNSRECORD_Data rd_new[rd_count + handle->rd_count]; |
674 | for (int i = 0; i < rd_count; i++) | 571 | for (int i = 0; i < rd_count; i++) |
675 | rd_new[i] = rd[i]; | 572 | rd_new[i] = rd[i]; |
676 | rd_new[rd_count] = *handle->rd; | 573 | for (int j = 0; j < handle->rd_count; j++) |
574 | rd_new[rd_count + j] = handle->rd[j]; | ||
677 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | 575 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, |
678 | handle->zone_pkey, | 576 | handle->zone_pkey, |
679 | handle->record_name, | 577 | handle->record_name, |
680 | rd_count + 1, | 578 | rd_count + handle->rd_count, |
681 | rd_new, | 579 | rd_new, |
682 | &create_finished, | 580 | &create_finished, |
683 | handle); | 581 | handle); |
@@ -703,16 +601,12 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle, | |||
703 | void *cls) | 601 | void *cls) |
704 | { | 602 | { |
705 | struct RequestHandle *handle = cls; | 603 | struct RequestHandle *handle = cls; |
706 | struct GNUNET_GNSRECORD_Data *gns_record; | ||
707 | struct EgoEntry *ego_entry; | 604 | struct EgoEntry *ego_entry; |
708 | char *egoname; | 605 | char *egoname; |
709 | json_t *data_js; | 606 | json_t *data_js; |
710 | json_t *name_json; | ||
711 | json_error_t err; | 607 | json_error_t err; |
712 | char term_data[handle->rest_handle->data_size + 1]; | ||
713 | 608 | ||
714 | struct GNUNET_JSON_Specification gnsspec[] = | 609 | char term_data[handle->rest_handle->data_size + 1]; |
715 | {GNUNET_JSON_spec_gnsrecord_data (&gns_record), GNUNET_JSON_spec_end ()}; | ||
716 | 610 | ||
717 | if (0 >= handle->rest_handle->data_size) | 611 | if (0 >= handle->rest_handle->data_size) |
718 | { | 612 | { |
@@ -725,29 +619,12 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle, | |||
725 | handle->rest_handle->data, | 619 | handle->rest_handle->data, |
726 | handle->rest_handle->data_size); | 620 | handle->rest_handle->data_size); |
727 | data_js = json_loads (term_data, JSON_DECODE_ANY, &err); | 621 | data_js = json_loads (term_data, JSON_DECODE_ANY, &err); |
622 | struct GNUNET_JSON_Specification gnsspec[] = | ||
623 | {GNUNET_JSON_spec_gnsrecord (&handle->rd, &handle->rd_count, &handle->record_name), GNUNET_JSON_spec_end ()}; | ||
728 | if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL)) | 624 | if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL)) |
729 | { | 625 | { |
730 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA); | 626 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA); |
731 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 627 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
732 | GNUNET_JSON_parse_free (gnsspec); | ||
733 | json_decref (data_js); | ||
734 | return; | ||
735 | } | ||
736 | handle->rd = gns_record; | ||
737 | |||
738 | name_json = json_object_get (data_js, "record_name"); | ||
739 | if (! json_is_string (name_json)) | ||
740 | { | ||
741 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA); | ||
742 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
743 | json_decref (data_js); | ||
744 | return; | ||
745 | } | ||
746 | handle->record_name = GNUNET_strdup (json_string_value (name_json)); | ||
747 | if (NULL == handle->record_name) | ||
748 | { | ||
749 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA); | ||
750 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
751 | json_decref (data_js); | 628 | json_decref (data_js); |
752 | return; | 629 | return; |
753 | } | 630 | } |
@@ -778,17 +655,7 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle, | |||
778 | } | 655 | } |
779 | } | 656 | } |
780 | if (NULL != ego_entry) | 657 | if (NULL != ego_entry) |
781 | { | ||
782 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 658 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
783 | } | ||
784 | if (NULL == handle->zone_pkey) | ||
785 | { | ||
786 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | ||
787 | "namestore", | ||
788 | &default_ego_post, | ||
789 | handle); | ||
790 | return; | ||
791 | } | ||
792 | handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, | 659 | handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, |
793 | handle->zone_pkey, | 660 | handle->zone_pkey, |
794 | handle->record_name, | 661 | handle->record_name, |
@@ -806,48 +673,6 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle, | |||
806 | 673 | ||
807 | 674 | ||
808 | /** | 675 | /** |
809 | * @param cls closure | ||
810 | * @param ego ego handle | ||
811 | * @param ctx context for application to store data for this ego | ||
812 | * (during the lifetime of this process, initially NULL) | ||
813 | * @param identifier identifier assigned by the user for this ego, | ||
814 | * NULL if the user just deleted the ego and it | ||
815 | * must thus no longer be used | ||
816 | */ | ||
817 | static void | ||
818 | default_ego_delete (void *cls, | ||
819 | struct GNUNET_IDENTITY_Ego *ego, | ||
820 | void **ctx, | ||
821 | const char *identifier) | ||
822 | { | ||
823 | struct RequestHandle *handle = cls; | ||
824 | handle->op = NULL; | ||
825 | |||
826 | if (ego == NULL) | ||
827 | { | ||
828 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE); | ||
829 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
830 | return; | ||
831 | } | ||
832 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
833 | |||
834 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | ||
835 | handle->zone_pkey, | ||
836 | handle->record_name, | ||
837 | 0, | ||
838 | NULL, | ||
839 | &del_finished, | ||
840 | handle); | ||
841 | if (NULL == handle->add_qe) | ||
842 | { | ||
843 | handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED); | ||
844 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
845 | return; | ||
846 | } | ||
847 | } | ||
848 | |||
849 | |||
850 | /** | ||
851 | * Handle namestore DELETE request | 676 | * Handle namestore DELETE request |
852 | * | 677 | * |
853 | * @param con_handle the connection handle | 678 | * @param con_handle the connection handle |
@@ -882,9 +707,7 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle, | |||
882 | } | 707 | } |
883 | } | 708 | } |
884 | if (NULL != ego_entry) | 709 | if (NULL != ego_entry) |
885 | { | ||
886 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | 710 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
887 | } | ||
888 | 711 | ||
889 | GNUNET_CRYPTO_hash ("record_name", strlen ("record_name"), &key); | 712 | GNUNET_CRYPTO_hash ("record_name", strlen ("record_name"), &key); |
890 | if (GNUNET_NO == | 713 | if (GNUNET_NO == |
@@ -897,15 +720,6 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle, | |||
897 | handle->record_name = GNUNET_strdup ( | 720 | handle->record_name = GNUNET_strdup ( |
898 | GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key)); | 721 | GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key)); |
899 | 722 | ||
900 | if (NULL == handle->zone_pkey) | ||
901 | { | ||
902 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | ||
903 | "namestore", | ||
904 | &default_ego_delete, | ||
905 | handle); | ||
906 | return; | ||
907 | } | ||
908 | |||
909 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | 723 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, |
910 | handle->zone_pkey, | 724 | handle->zone_pkey, |
911 | handle->record_name, | 725 | handle->record_name, |