123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- /*
- This file is part of GNUnet
- Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- /**
- * @file gnunet_json_lib.h
- * @brief functions to parse JSON objects into GNUnet objects
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
- #ifndef GNUNET_JSON_LIB_H
- #define GNUNET_JSON_LIB_H
- #include "gnunet_util_lib.h"
- #include <jansson.h>
- #include <microhttpd.h>
- /* ****************** Generic parser interface ******************* */
- /**
- * @brief Entry in parser specification for #GNUNET_JSON_parse().
- */
- struct GNUNET_JSON_Specification;
- /**
- * Function called to parse JSON argument.
- *
- * @param cls closure
- * @param root JSON to parse
- * @param spec our specification entry with further details
- * @return #GNUNET_SYSERR on error,
- * #GNUNET_OK on success
- */
- typedef int
- (*GNUNET_JSON_Parser) (void *cls,
- json_t *root,
- struct GNUNET_JSON_Specification *spec);
- /**
- * Function called to clean up data from earlier parsing.
- *
- * @param cls closure
- * @param spec our specification entry with data to clean.
- */
- typedef void
- (*GNUNET_JSON_Cleaner) (void *cls,
- struct GNUNET_JSON_Specification *spec);
- /**
- * @brief Entry in parser specification for #GNUNET_JSON_parse().
- */
- struct GNUNET_JSON_Specification
- {
- /**
- * Function for how to parse this type of entry.
- */
- GNUNET_JSON_Parser parser;
- /**
- * Function for how to clean up this type of entry.
- */
- GNUNET_JSON_Cleaner cleaner;
- /**
- * Closure for @e parser and @e cleaner.
- */
- void *cls;
- /**
- * Name of the field to parse, use NULL to get the JSON
- * of the main object instead of the JSON of an individual field.
- */
- const char *field;
- /**
- * Pointer, details specific to the @e parser.
- */
- void *ptr;
- /**
- * Number of bytes available in @e ptr.
- */
- size_t ptr_size;
- /**
- * Where should we store the final size of @e ptr.
- */
- size_t *size_ptr;
- /**
- * Set to #GNUNET_YES if this component is optional.
- */
- int is_optional;
- };
- /**
- * Navigate and parse data in a JSON tree. Tries to parse the @a root
- * to find all of the values given in the @a spec. If one of the
- * entries in @a spec cannot be found or parsed, the name of the JSON
- * field is returned in @a error_json_name, and the offset of the
- * entry in @a spec is returned in @a error_line.
- *
- * @param root the JSON node to start the navigation at.
- * @param spec parse specification array
- * @param[out] error_json_name which JSON field was problematic
- * @param[out] which index into @a spec did we encounter an error
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
- enum GNUNET_GenericReturnValue
- GNUNET_JSON_parse (const json_t *root,
- struct GNUNET_JSON_Specification *spec,
- const char **error_json_name,
- unsigned int *error_line);
- /**
- * Frees all elements allocated during a #GNUNET_JSON_parse()
- * operation.
- *
- * @param spec specification of the parse operation
- */
- void
- GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec);
- /* ****************** Canonical parser specifications ******************* */
- /**
- * End of a parser specification.
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_end (void);
- /**
- * Set the "optional" flag for a parser specification entry.
- *
- * @param spec specification to modify
- * @return spec copy of @a spec with optional bit set
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec);
- /**
- * Variable size object (in network byte order, encoded using Crockford
- * Base32hex encoding).
- *
- * @param name name of the JSON field
- * @param[out] obj pointer where to write the data, must have @a size bytes
- * @param size number of bytes expected in @a obj
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_fixed (const char *name,
- void *obj,
- size_t size);
- /**
- * Fixed size object (in network byte order, encoded using Crockford
- * Base32hex encoding).
- *
- * @param name name of the JSON field
- * @param obj pointer where to write the data (type of `*obj` will determine size)
- */
- #define GNUNET_JSON_spec_fixed_auto(name, obj) \
- GNUNET_JSON_spec_fixed (name, obj, sizeof(*obj))
- /**
- * Variable size object (in network byte order, encoded using
- * Crockford Base32hex encoding).
- *
- * @param name name of the JSON field
- * @param[out] obj pointer where to write the data, will be allocated
- * @param[out] size where to store the number of bytes allocated for @a obj
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_varsize (const char *name,
- void **obj,
- size_t *size);
- /**
- * The expected field stores a string.
- *
- * @param name name of the JSON field
- * @param strptr where to store a pointer to the field
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_string (const char *name,
- const char **strptr);
- /**
- * JSON object.
- *
- * @param name name of the JSON field
- * @param[out] jsonp where to store the JSON found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_json (const char *name,
- json_t **jsonp);
- /**
- * boolean.
- *
- * @param name name of the JSON field
- * @param[out] b where to store the boolean found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_bool (const char *name,
- bool *b);
- /**
- * 8-bit integer.
- *
- * @param name name of the JSON field
- * @param[out] u8 where to store the integer found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_uint8 (const char *name,
- uint8_t *u8);
- /**
- * 16-bit integer.
- *
- * @param name name of the JSON field
- * @param[out] u16 where to store the integer found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_uint16 (const char *name,
- uint16_t *u16);
- /**
- * 32-bit integer.
- *
- * @param name name of the JSON field
- * @param[out] u32 where to store the integer found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_uint32 (const char *name,
- uint32_t *u32);
- /**
- * 64-bit integer.
- *
- * @param name name of the JSON field
- * @param[out] u64 where to store the integer found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_uint64 (const char *name,
- uint64_t *u64);
- /**
- * 64-bit signed integer.
- *
- * @param name name of the JSON field
- * @param[out] i64 where to store the integer found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_int64 (const char *name,
- int64_t *i64);
- /**
- * Boolean (true mapped to #GNUNET_YES, false mapped to #GNUNET_NO).
- *
- * @param name name of the JSON field
- * @param[out] boolean where to store the boolean found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_boolean (const char *name,
- int *boolean);
- /* ************ GNUnet-specific parser specifications ******************* */
- /**
- * Absolute time.
- *
- * @param name name of the JSON field
- * @param[out] at where to store the absolute time found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_absolute_time (const char *name,
- struct GNUNET_TIME_Absolute *at);
- /**
- * Absolute time in network byte order.
- *
- * @param name name of the JSON field
- * @param[out] at where to store the absolute time found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_absolute_time_nbo (const char *name,
- struct GNUNET_TIME_AbsoluteNBO *at);
- /**
- * Relative time.
- *
- * @param name name of the JSON field
- * @param[out] rt where to store the relative time found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_relative_time (const char *name,
- struct GNUNET_TIME_Relative *rt);
- /**
- * Specification for parsing an RSA public key.
- *
- * @param name name of the JSON field
- * @param pk where to store the RSA key found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_rsa_public_key (const char *name,
- struct GNUNET_CRYPTO_RsaPublicKey **pk);
- /**
- * Specification for parsing an RSA signature.
- *
- * @param name name of the JSON field
- * @param sig where to store the RSA signature found under @a name
- */
- struct GNUNET_JSON_Specification
- GNUNET_JSON_spec_rsa_signature (const char *name,
- struct GNUNET_CRYPTO_RsaSignature **sig);
- /* ****************** Generic generator interface ******************* */
- /**
- * Convert binary data to a JSON string with the base32crockford
- * encoding.
- *
- * @param data binary data
- * @param size size of @a data in bytes
- * @return json string that encodes @a data
- */
- json_t *
- GNUNET_JSON_from_data (const void *data, size_t size);
- /**
- * Convert binary data to a JSON string with the base32crockford
- * encoding.
- *
- * @param ptr binary data, sizeof (*ptr) must yield correct size
- * @return json string that encodes @a data
- */
- #define GNUNET_JSON_from_data_auto(ptr) \
- GNUNET_JSON_from_data (ptr, sizeof(*ptr))
- /**
- * Convert absolute timestamp to a json string.
- *
- * @param stamp the time stamp
- * @return a json string with the timestamp in @a stamp
- */
- json_t *
- GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp);
- /**
- * Convert absolute timestamp to a json string.
- *
- * @param stamp the time stamp
- * @return a json string with the timestamp in @a stamp
- */
- json_t *
- GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp);
- /**
- * Convert relative timestamp to a json string.
- *
- * @param stamp the time stamp
- * @return a json string with the timestamp in @a stamp
- */
- json_t *
- GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp);
- /**
- * Convert RSA public key to JSON.
- *
- * @param pk public key to convert
- * @return corresponding JSON encoding
- */
- json_t *
- GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk);
- /**
- * Convert RSA signature to JSON.
- *
- * @param sig signature to convert
- * @return corresponding JSON encoding
- */
- json_t *
- GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig);
- /* ******************* Helpers for MHD upload handling ******************* */
- /**
- * Return codes from #GNUNET_JSON_post_parser().
- */
- enum GNUNET_JSON_PostResult
- {
- /**
- * Parsing successful, JSON result is in `*json`.
- */
- GNUNET_JSON_PR_SUCCESS,
- /**
- * Parsing continues, call again soon!
- */
- GNUNET_JSON_PR_CONTINUE,
- /**
- * Sorry, memory allocation (malloc()) failed.
- */
- GNUNET_JSON_PR_OUT_OF_MEMORY,
- /**
- * Request size exceeded `buffer_max` argument.
- */
- GNUNET_JSON_PR_REQUEST_TOO_LARGE,
- /**
- * JSON parsing failed. This was not a JSON upload.
- */
- GNUNET_JSON_PR_JSON_INVALID
- };
- /**
- * Process a POST request containing a JSON object. This function
- * realizes an MHD POST processor that will (incrementally) process
- * JSON data uploaded to the HTTP server. It will store the required
- * state in the @a con_cls, which must be cleaned up using
- * #GNUNET_JSON_post_parser_callback().
- *
- * @param buffer_max maximum allowed size for the buffer
- * @param connection MHD connection handle (for meta data about the upload)
- * @param con_cls the closure (will point to a `struct Buffer *`)
- * @param upload_data the POST data
- * @param upload_data_size number of bytes in @a upload_data
- * @param json the JSON object for a completed request
- * @return result code indicating the status of the operation
- */
- enum GNUNET_JSON_PostResult
- GNUNET_JSON_post_parser (size_t buffer_max,
- struct MHD_Connection *connection,
- void **con_cls,
- const char *upload_data,
- size_t *upload_data_size,
- json_t **json);
- /**
- * Function called whenever we are done with a request
- * to clean up our state.
- *
- * @param con_cls value as it was left by
- * #GNUNET_JSON_post_parser(), to be cleaned up
- */
- void
- GNUNET_JSON_post_parser_cleanup (void *con_cls);
- /* ****************** GETOPT JSON helper ******************* */
- /**
- * Allow user to specify a JSON input value.
- *
- * @param shortName short name of the option
- * @param name long name of the option
- * @param argumentHelp help text for the option argument
- * @param description long help text for the option
- * @param[out] val set to the JSON specified at the command line
- */
- struct GNUNET_GETOPT_CommandLineOption
- GNUNET_JSON_getopt (char shortName,
- const char *name,
- const char *argumentHelp,
- const char *description,
- json_t **json);
- #endif
- /* end of gnunet_json_lib.h */
|