aboutsummaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd.c')
-rw-r--r--src/backend/taler-merchant-httpd.c250
1 files changed, 248 insertions, 2 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 515cefc2..6ca70937 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -23,6 +23,8 @@
#include "platform.h"
#include <microhttpd.h>
#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_json_lib.h>
+
/**
* Shorthand for exit jumps.
@@ -59,6 +61,229 @@ static int dry;
*/
static int result;
+/** Beginning of JSON parse logic
+* Located here only for testing purposes since the service they provide is already
+* implemented in the mint's code; it just needs to be exported as a library. To be announced as a issue.
+*/
+
+/**
+ * Initial size for POST
+ * request buffer.
+ */
+#define REQUEST_BUFFER_INITIAL 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 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
+ * GNUNET_SYSERR on fatal error (out of memory?)
+ */
+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);
+ 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.
+ *
+ * @param connection the MHD connection
+ * @param con_cs the closure (contains a 'struct Buffer *')
+ * @param upload_data the POST data
+ * @param upload_data_size the POST data size
+ * @param json the JSON object for a completed request
+ *
+ * @returns
+ * GNUNET_YES if json object was parsed
+ * GNUNET_NO is request incomplete or invalid
+ * GNUNET_SYSERR on internal error
+ */
+static int
+process_post_json (struct MHD_Connection *connection,
+ void **con_cls,
+ const char *upload_data,
+ size_t *upload_data_size,
+ json_t **json)
+{
+ struct Buffer *r = *con_cls;
+
+ 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 GNUNET_SYSERR;
+ }
+ *upload_data_size = 0;
+ *con_cls = r;
+ return GNUNET_NO;
+ }
+ if (0 != *upload_data_size)
+ {
+ /* 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 or we're out of memory. */
+
+ *con_cls = NULL;
+ buffer_deinit (r);
+ GNUNET_free (r);
+ return GNUNET_SYSERR;
+ }
+ *upload_data_size = 0;
+ return GNUNET_NO;
+ }
+
+ /* We have seen the whole request. */
+
+ *json = json_loadb (r->data, r->fill, 0, NULL);
+ buffer_deinit (r);
+ GNUNET_free (r);
+ if (NULL == *json)
+ {
+ struct MHD_Response *resp;
+ int ret;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Can't parse JSON request body\n");
+ resp = MHD_create_response_from_buffer (strlen ("parse error"),
+ "parse error",
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_BAD_REQUEST,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ *con_cls = NULL;
+
+ return GNUNET_YES;
+}
+
+
+/* ************** END of JSON POST processing logic ************ */
+
+
+
+/**
+* Return the given message to the other end of connection
+* @msg (0-terminated) message to show
+* @param connection a MHD connection
+* @param resp where to store the response for the calling function
+* @return HTTP status code reflecting the operation outcome
+*
+*/
+
+static unsigned int
+generate_message (struct MHD_Response **resp, const char *msg) // this parameter was preceded by a '_' in its original file. Why?
+{
+
+ unsigned int ret;
+
+ *resp = MHD_create_response_from_buffer (strlen (msg), (void *) msg,
+ MHD_RESPMEM_PERSISTENT);
+ ret = 200;
+ return ret;
+
+
+}
+
/**
* Generate the 'hello world' response
* @param connection a MHD connection
@@ -195,8 +420,8 @@ url_handler (void *cls,
struct MHD_Response *resp;
- printf ("hi, just called web micro server with url %s\n", url);
#define URL_HELLO "/hello"
+ #define URL_CONTRACT "/contract"
no_destroy = 0;
resp = NULL;
status = 500;
@@ -207,7 +432,28 @@ url_handler (void *cls,
else
GNUNET_break (0);
}
- else status = 404;
+
+ // to be called by the frontend passing all the product's information
+ // which are relevant for the contract's generation
+ if (0 == strncasecmp (url, URL_CONTRACT, sizeof (URL_CONTRACT)))
+ {
+ if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
+ status = generate_message (&resp, "Sorry, only POST is allowed");
+ else
+
+ /*
+ 1. parse the json
+ 2. generate the contract
+ 3. pack the contract's json
+ 4. return it
+ */
+
+ GNUNET_break (0);
+
+
+ }
+
+
if (NULL != resp)
{