aboutsummaryrefslogtreecommitdiff
path: root/src/json
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-30 15:56:16 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-30 15:56:16 +0200
commit342619bf17d389e4305c9ee72b609059706a8023 (patch)
tree391ff802b3d7389a08947dfb2e2fc816f4013752 /src/json
parent57636ddf7839aaeedd14c90afcd28b375ec516a6 (diff)
downloadgnunet-342619bf17d389e4305c9ee72b609059706a8023.tar.gz
gnunet-342619bf17d389e4305c9ee72b609059706a8023.zip
REST/NAMESTORE: rework API
Diffstat (limited to 'src/json')
-rw-r--r--src/json/json_generator.c78
-rw-r--r--src/json/json_gnsrecord.c232
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 */
169json_t * 169json_t *
170GNUNET_JSON_from_gns_record (const char* rname, 170GNUNET_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
38struct GnsRecordInfo
39{
40 char **name;
41
42 unsigned int *rd_count;
43
44 struct GNUNET_GNSRECORD_Data **rd;
45};
46
47
48static void
49cleanup_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 */
46static int 80static int
47parse_gnsrecordobject (void *cls, 81parse_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 */
140static void 157static int
141clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) 158parse_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; 181static int
182parse_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 */
223static void
224clean_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 */
161struct GNUNET_JSON_Specification 237struct GNUNET_JSON_Specification
162GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data **gnsrecord_object) 238GNUNET_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}