diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_parsing.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_parsing.c | 202 |
1 files changed, 27 insertions, 175 deletions
diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/exchange/taler-exchange-httpd_parsing.c index f6e367813..beac81a1c 100644 --- a/src/exchange/taler-exchange-httpd_parsing.c +++ b/src/exchange/taler-exchange-httpd_parsing.c @@ -24,122 +24,18 @@ #include "platform.h" #include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_json_lib.h> #include "taler_json_lib.h" #include "taler-exchange-httpd_parsing.h" #include "taler-exchange-httpd_responses.h" /** - * Initial size for POST request buffer. - */ -#define REQUEST_BUFFER_INITIAL (2*1024) - -/** * Maximum POST request size. */ #define REQUEST_BUFFER_MAX (1024*1024) -/** - * Buffer for POST requests. - */ -struct Buffer -{ - /** - * Allocated memory - */ - char *data; - - /** - * Number of valid bytes in buffer. - */ - size_t fill; - - /** - * Number of allocated bytes in buffer. - */ - size_t alloc; -}; - - -/** - * Initialize a buffer. - * - * @param buf the buffer to initialize - * @param data the initial data - * @param data_size size of the initial data - * @param alloc_size size of the buffer - * @param max_size maximum size that the buffer can grow to - * @return a GNUnet result code - */ -static int -buffer_init (struct Buffer *buf, - const void *data, - size_t data_size, - size_t alloc_size, - size_t max_size) -{ - if (data_size > max_size || alloc_size > max_size) - return GNUNET_SYSERR; - if (data_size > alloc_size) - alloc_size = data_size; - buf->data = GNUNET_malloc (alloc_size); - memcpy (buf->data, data, data_size); - return GNUNET_OK; -} - - -/** - * Free the data in a buffer. Does *not* free - * the buffer object itself. - * - * @param buf buffer to de-initialize - */ -static void -buffer_deinit (struct Buffer *buf) -{ - GNUNET_free (buf->data); - buf->data = NULL; -} - - -/** - * Append data to a buffer, growing the buffer if necessary. - * - * @param buf the buffer to append to - * @param data the data to append - * @param data_size the size of @a data - * @param max_size maximum size that the buffer can grow to - * @return #GNUNET_OK on success, - * #GNUNET_NO if the buffer can't accomodate for the new data - */ -static int -buffer_append (struct Buffer *buf, - const void *data, - size_t data_size, - size_t max_size) -{ - if (buf->fill + data_size > max_size) - return GNUNET_NO; - if (data_size + buf->fill > buf->alloc) - { - char *new_buf; - size_t new_size = buf->alloc; - while (new_size < buf->fill + data_size) - new_size += 2; - if (new_size > max_size) - return GNUNET_NO; - new_buf = GNUNET_malloc (new_size); - memcpy (new_buf, buf->data, buf->fill); - GNUNET_free (buf->data); - buf->data = new_buf; - buf->alloc = new_size; - } - memcpy (buf->data + buf->fill, data, data_size); - buf->fill += data_size; - return GNUNET_OK; -} - /** * Process a POST request containing a JSON object. This function @@ -171,75 +67,37 @@ TMH_PARSE_post_json (struct MHD_Connection *connection, size_t *upload_data_size, json_t **json) { - struct Buffer *r = *con_cls; - - *json = NULL; - if (NULL == *con_cls) - { - /* We are seeing a fresh POST request. */ - r = GNUNET_new (struct Buffer); - if (GNUNET_OK != - buffer_init (r, - upload_data, - *upload_data_size, - REQUEST_BUFFER_INITIAL, - REQUEST_BUFFER_MAX)) - { - *con_cls = NULL; - buffer_deinit (r); - GNUNET_free (r); - return (MHD_NO == - TMH_RESPONSE_reply_internal_error (connection, - "out of memory")) - ? GNUNET_SYSERR : GNUNET_NO; - } - /* everything OK, wait for more POST data */ - *upload_data_size = 0; - *con_cls = r; - return GNUNET_YES; - } - if (0 != *upload_data_size) + enum GNUNET_JSON_PostResult pr; + + pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, + con_cls, + upload_data, + upload_data_size, + json); + switch (pr) { - /* We are seeing an old request with more data available. */ - - if (GNUNET_OK != - buffer_append (r, - upload_data, - *upload_data_size, - REQUEST_BUFFER_MAX)) - { - /* Request too long */ - *con_cls = NULL; - buffer_deinit (r); - GNUNET_free (r); - return (MHD_NO == - TMH_RESPONSE_reply_request_too_large (connection)) - ? GNUNET_SYSERR : GNUNET_NO; - } - /* everything OK, wait for more POST data */ - *upload_data_size = 0; + case GNUNET_JSON_PR_OUT_OF_MEMORY: + return (MHD_NO == + TMH_RESPONSE_reply_internal_error (connection, + "out of memory")) + ? GNUNET_SYSERR : GNUNET_NO; + case GNUNET_JSON_PR_CONTINUE: return GNUNET_YES; - } - - /* We have seen the whole request. */ - - *json = json_loadb (r->data, - r->fill, - 0, - NULL); - if (NULL == *json) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to parse JSON request body\n"); + case GNUNET_JSON_PR_REQUEST_TOO_LARGE: + return (MHD_NO == + TMH_RESPONSE_reply_request_too_large (connection)) + ? GNUNET_SYSERR : GNUNET_NO; + case GNUNET_JSON_PR_JSON_INVALID: return (MHD_YES == TMH_RESPONSE_reply_invalid_json (connection)) ? GNUNET_NO : GNUNET_SYSERR; + case GNUNET_JSON_PR_SUCCESS: + GNUNET_break (NULL != *json); + return GNUNET_YES; } - buffer_deinit (r); - GNUNET_free (r); - *con_cls = NULL; - - return GNUNET_YES; + /* this should never happen */ + GNUNET_break (0); + return GNUNET_SYSERR; } @@ -253,13 +111,7 @@ TMH_PARSE_post_json (struct MHD_Connection *connection, void TMH_PARSE_post_cleanup_callback (void *con_cls) { - struct Buffer *r = con_cls; - - if (NULL != r) - { - buffer_deinit (r); - GNUNET_free (r); - } + GNUNET_JSON_post_parser_cleanup (con_cls); } |