summaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_parsing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_parsing.c')
-rw-r--r--src/exchange/taler-exchange-httpd_parsing.c202
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);
}