2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
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 Affero General Public License for more details.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file gnunet_json_lib.h
22 * @brief functions to parse JSON objects into GNUnet objects
23 * @author Florian Dold
24 * @author Benedikt Mueller
25 * @author Christian Grothoff
27 #ifndef GNUNET_JSON_LIB_H
28 #define GNUNET_JSON_LIB_H
30 #include "gnunet_util_lib.h"
31 #include "gnunet_gnsrecord_lib.h"
33 #include <microhttpd.h>
35 /* ****************** Generic parser interface ******************* */
38 * @brief Entry in parser specification for #GNUNET_JSON_parse().
40 struct GNUNET_JSON_Specification;
44 * Function called to parse JSON argument.
47 * @param root JSON to parse
48 * @param spec our specification entry with further details
49 * @return #GNUNET_SYSERR on error,
50 * #GNUNET_OK on success
52 typedef int (*GNUNET_JSON_Parser) (void *cls,
54 struct GNUNET_JSON_Specification *spec);
58 * Function called to clean up data from earlier parsing.
61 * @param spec our specification entry with data to clean.
63 typedef void (*GNUNET_JSON_Cleaner) (void *cls,
64 struct GNUNET_JSON_Specification *spec);
68 * @brief Entry in parser specification for #GNUNET_JSON_parse().
70 struct GNUNET_JSON_Specification
73 * Function for how to parse this type of entry.
75 GNUNET_JSON_Parser parser;
78 * Function for how to clean up this type of entry.
80 GNUNET_JSON_Cleaner cleaner;
83 * Closure for @e parser and @e cleaner.
88 * Name of the field to parse, use NULL to get the JSON
89 * of the main object instead of the JSON of an individual field.
94 * Pointer, details specific to the @e parser.
99 * Number of bytes available in @e ptr.
104 * Where should we store the final size of @e ptr.
109 * Set to #GNUNET_YES if this component is optional.
116 * Navigate and parse data in a JSON tree. Tries to parse the @a root
117 * to find all of the values given in the @a spec. If one of the
118 * entries in @a spec cannot be found or parsed, the name of the JSON
119 * field is returned in @a error_json_name, and the offset of the
120 * entry in @a spec is returned in @a error_line.
122 * @param root the JSON node to start the navigation at.
123 * @param spec parse specification array
124 * @param[out] error_json_name which JSON field was problematic
125 * @param[out] which index into @a spec did we encounter an error
126 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
129 GNUNET_JSON_parse (const json_t *root,
130 struct GNUNET_JSON_Specification *spec,
131 const char **error_json_name,
132 unsigned int *error_line);
136 * Frees all elements allocated during a #GNUNET_JSON_parse()
139 * @param spec specification of the parse operation
142 GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec);
145 /* ****************** Canonical parser specifications ******************* */
149 * End of a parser specification.
151 struct GNUNET_JSON_Specification
152 GNUNET_JSON_spec_end (void);
156 * Set the "optional" flag for a parser specification entry.
158 * @param spec specification to modify
159 * @return spec copy of @a spec with optional bit set
161 struct GNUNET_JSON_Specification
162 GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec);
166 * Variable size object (in network byte order, encoded using Crockford
167 * Base32hex encoding).
169 * @param name name of the JSON field
170 * @param[out] obj pointer where to write the data, must have @a size bytes
171 * @param size number of bytes expected in @a obj
173 struct GNUNET_JSON_Specification
174 GNUNET_JSON_spec_fixed (const char *name, void *obj, size_t size);
178 * Fixed size object (in network byte order, encoded using Crockford
179 * Base32hex encoding).
181 * @param name name of the JSON field
182 * @param obj pointer where to write the data (type of `*obj` will determine size)
184 #define GNUNET_JSON_spec_fixed_auto(name, obj) \
185 GNUNET_JSON_spec_fixed (name, obj, sizeof(*obj))
189 * Variable size object (in network byte order, encoded using
190 * Crockford Base32hex encoding).
192 * @param name name of the JSON field
193 * @param[out] obj pointer where to write the data, will be allocated
194 * @param[out] size where to store the number of bytes allocated for @a obj
196 struct GNUNET_JSON_Specification
197 GNUNET_JSON_spec_varsize (const char *name, void **obj, size_t *size);
201 * The expected field stores a string.
203 * @param name name of the JSON field
204 * @param strptr where to store a pointer to the field
206 struct GNUNET_JSON_Specification
207 GNUNET_JSON_spec_string (const char *name, const char **strptr);
212 * @param name name of the JSON field
213 * @param[out] jsonp where to store the JSON found under @a name
215 struct GNUNET_JSON_Specification
216 GNUNET_JSON_spec_json (const char *name, json_t **jsonp);
222 * @param name name of the JSON field
223 * @param[out] u8 where to store the integer found under @a name
225 struct GNUNET_JSON_Specification
226 GNUNET_JSON_spec_uint8 (const char *name, uint8_t *u8);
232 * @param name name of the JSON field
233 * @param[out] u16 where to store the integer found under @a name
235 struct GNUNET_JSON_Specification
236 GNUNET_JSON_spec_uint16 (const char *name, uint16_t *u16);
242 * @param name name of the JSON field
243 * @param[out] u32 where to store the integer found under @a name
245 struct GNUNET_JSON_Specification
246 GNUNET_JSON_spec_uint32 (const char *name, uint32_t *u32);
252 * @param name name of the JSON field
253 * @param[out] u64 where to store the integer found under @a name
255 struct GNUNET_JSON_Specification
256 GNUNET_JSON_spec_uint64 (const char *name, uint64_t *u64);
260 * Boolean (true mapped to #GNUNET_YES, false mapped to #GNUNET_NO).
262 * @param name name of the JSON field
263 * @param[out] boolean where to store the boolean found under @a name
265 struct GNUNET_JSON_Specification
266 GNUNET_JSON_spec_boolean (const char *name, int *boolean);
269 /* ************ GNUnet-specific parser specifications ******************* */
274 * @param name name of the JSON field
275 * @param[out] at where to store the absolute time found under @a name
277 struct GNUNET_JSON_Specification
278 GNUNET_JSON_spec_absolute_time (const char *name,
279 struct GNUNET_TIME_Absolute *at);
283 * Absolute time in network byte order.
285 * @param name name of the JSON field
286 * @param[out] at where to store the absolute time found under @a name
288 struct GNUNET_JSON_Specification
289 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
290 struct GNUNET_TIME_AbsoluteNBO *at);
296 * @param name name of the JSON field
297 * @param[out] rt where to store the relative time found under @a name
299 struct GNUNET_JSON_Specification
300 GNUNET_JSON_spec_relative_time (const char *name,
301 struct GNUNET_TIME_Relative *rt);
305 * Specification for parsing an RSA public key.
307 * @param name name of the JSON field
308 * @param pk where to store the RSA key found under @a name
310 struct GNUNET_JSON_Specification
311 GNUNET_JSON_spec_rsa_public_key (const char *name,
312 struct GNUNET_CRYPTO_RsaPublicKey **pk);
316 * Specification for parsing an RSA signature.
318 * @param name name of the JSON field
319 * @param sig where to store the RSA signature found under @a name
321 struct GNUNET_JSON_Specification
322 GNUNET_JSON_spec_rsa_signature (const char *name,
323 struct GNUNET_CRYPTO_RsaSignature **sig);
327 * JSON Specification for GNS Records.
329 * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill
330 * @return JSON Specification
332 struct GNUNET_JSON_Specification
333 GNUNET_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd,
334 unsigned int *rd_count,
338 /* ****************** Generic generator interface ******************* */
342 * Convert binary data to a JSON string with the base32crockford
345 * @param data binary data
346 * @param size size of @a data in bytes
347 * @return json string that encodes @a data
350 GNUNET_JSON_from_data (const void *data, size_t size);
354 * Convert binary data to a JSON string with the base32crockford
357 * @param ptr binary data, sizeof (*ptr) must yield correct size
358 * @return json string that encodes @a data
360 #define GNUNET_JSON_from_data_auto(ptr) \
361 GNUNET_JSON_from_data (ptr, sizeof(*ptr))
365 * Convert absolute timestamp to a json string.
367 * @param stamp the time stamp
368 * @return a json string with the timestamp in @a stamp
371 GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp);
375 * Convert absolute timestamp to a json string.
377 * @param stamp the time stamp
378 * @return a json string with the timestamp in @a stamp
381 GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp);
385 * Convert relative timestamp to a json string.
387 * @param stamp the time stamp
388 * @return a json string with the timestamp in @a stamp
391 GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp);
395 * Convert RSA public key to JSON.
397 * @param pk public key to convert
398 * @return corresponding JSON encoding
401 GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk);
405 * Convert RSA signature to JSON.
407 * @param sig signature to convert
408 * @return corresponding JSON encoding
411 GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig);
414 * Convert Gns record to JSON.
416 * @param rname name of record
417 * @param rd record data
418 * @return corresponding JSON encoding
421 GNUNET_JSON_from_gnsrecord (const char *rname,
422 const struct GNUNET_GNSRECORD_Data *rd,
423 unsigned int rd_count);
425 /* ******************* Helpers for MHD upload handling ******************* */
428 * Return codes from #GNUNET_JSON_post_parser().
430 enum GNUNET_JSON_PostResult
433 * Parsing successful, JSON result is in `*json`.
435 GNUNET_JSON_PR_SUCCESS,
438 * Parsing continues, call again soon!
440 GNUNET_JSON_PR_CONTINUE,
443 * Sorry, memory allocation (malloc()) failed.
445 GNUNET_JSON_PR_OUT_OF_MEMORY,
448 * Request size exceeded `buffer_max` argument.
450 GNUNET_JSON_PR_REQUEST_TOO_LARGE,
453 * JSON parsing failed. This was not a JSON upload.
455 GNUNET_JSON_PR_JSON_INVALID
460 * Process a POST request containing a JSON object. This function
461 * realizes an MHD POST processor that will (incrementally) process
462 * JSON data uploaded to the HTTP server. It will store the required
463 * state in the @a con_cls, which must be cleaned up using
464 * #GNUNET_JSON_post_parser_callback().
466 * @param buffer_max maximum allowed size for the buffer
467 * @param connection MHD connection handle (for meta data about the upload)
468 * @param con_cls the closure (will point to a `struct Buffer *`)
469 * @param upload_data the POST data
470 * @param upload_data_size number of bytes in @a upload_data
471 * @param json the JSON object for a completed request
472 * @return result code indicating the status of the operation
474 enum GNUNET_JSON_PostResult
475 GNUNET_JSON_post_parser (size_t buffer_max,
476 struct MHD_Connection *connection,
478 const char *upload_data,
479 size_t *upload_data_size,
484 * Function called whenever we are done with a request
485 * to clean up our state.
487 * @param con_cls value as it was left by
488 * #GNUNET_JSON_post_parser(), to be cleaned up
491 GNUNET_JSON_post_parser_cleanup (void *con_cls);
494 /* ****************** GETOPT JSON helper ******************* */
498 * Allow user to specify a JSON input value.
500 * @param shortName short name of the option
501 * @param name long name of the option
502 * @param argumentHelp help text for the option argument
503 * @param description long help text for the option
504 * @param[out] val set to the JSON specified at the command line
506 struct GNUNET_GETOPT_CommandLineOption
507 GNUNET_JSON_getopt (char shortName,
509 const char *argumentHelp,
510 const char *description,
515 /* end of gnunet_json_lib.h */