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 /src/json | |
parent | 57636ddf7839aaeedd14c90afcd28b375ec516a6 (diff) | |
download | gnunet-342619bf17d389e4305c9ee72b609059706a8023.tar.gz gnunet-342619bf17d389e4305c9ee72b609059706a8023.zip |
REST/NAMESTORE: rework API
Diffstat (limited to 'src/json')
-rw-r--r-- | src/json/json_generator.c | 78 | ||||
-rw-r--r-- | src/json/json_gnsrecord.c | 232 |
2 files changed, 194 insertions, 116 deletions
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 | } |