From f398b34414e3dbde31c0ec4b627aaa7ccf593ee0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 16 Jan 2015 14:04:02 +0100 Subject: [PATCH] adding logic to free buffers allocated for POST processing when connection dies without completion --- src/mint/taler-mint-httpd.c | 48 ++++++++++++--------------- src/mint/taler-mint-httpd_deposit.c | 2 +- src/mint/taler-mint-httpd_parsing.c | 29 +++++++++++++--- src/mint/taler-mint-httpd_parsing.h | 38 ++++++++++++++++----- src/mint/taler-mint-httpd_refresh.c | 6 ++-- src/mint/taler-mint-httpd_responses.h | 2 ++ 6 files changed, 80 insertions(+), 45 deletions(-) diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index 61d0bbdce..2c3b3d2e1 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -73,35 +73,29 @@ static uint16_t serve_port; /** - * Convert a string representing an EdDSA signature to an EdDSA - * signature. + * Function called whenever MHD is done with a request. If the + * request was a POST, we may have stored a `struct Buffer *` in the + * @a con_cls that might still need to be cleaned up. Call the + * respective function to free the memory. * - * FIXME: this should be in GNUnet. - * FIXME: why? this code is dead, even here! - * - * @param enc encoded EdDSA signature - * @param enclen number of bytes in @a enc (without 0-terminator) - * @param pub where to store the EdDSA signature - * @return #GNUNET_OK on success + * @param cls client-defined closure + * @param connection connection handle + * @param con_cls value as set by the last call to + * the #MHD_AccessHandlerCallback + * @param toe reason for request termination + * @see #MHD_OPTION_NOTIFY_COMPLETED + * @ingroup request */ -int -TALER_eddsa_signature_from_string (const char *enc, - size_t enclen, - struct GNUNET_CRYPTO_EddsaSignature *sig) +static void +handle_mhd_completion_callback (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) { - size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaSignature)) * 8; - - if (keylen % 5 > 0) - keylen += 5 - keylen % 5; - keylen /= 5; - if (enclen != keylen) - return GNUNET_SYSERR; - - if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, - sig, - sizeof (struct GNUNET_CRYPTO_EddsaSignature))) - return GNUNET_SYSERR; - return GNUNET_OK; + if (NULL == *con_cls) + return; + TALER_MINT_parse_post_cleanup_callback (*con_cls); + *con_cls = NULL; } @@ -225,7 +219,6 @@ handle_mhd_request (void *cls, } - /** * Load configuration parameters for the mint * server into the corresponding global variables. @@ -359,6 +352,7 @@ main (int argc, char *const *argv) serve_port, NULL, NULL, &handle_mhd_request, NULL, + MHD_OPTION_NOTIFY_COMPLETED, &handle_mhd_completion_callback, MHD_OPTION_END); if (NULL == mydaemon) diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index 8c040b691..f1df0ad89 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c @@ -88,7 +88,7 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh, PGconn *db_conn; int res; - res = process_post_json (connection, + res = TALER_MINT_parse_post_json (connection, connection_cls, upload_data, upload_data_size, &json); diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c index a976c0c06..9a3fc1d6b 100644 --- a/src/mint/taler-mint-httpd_parsing.c +++ b/src/mint/taler-mint-httpd_parsing.c @@ -156,11 +156,11 @@ buffer_append (struct Buffer *buf, * GNUNET_SYSERR on internal error */ int -process_post_json (struct MHD_Connection *connection, - void **con_cls, - const char *upload_data, - size_t *upload_data_size, - json_t **json) +TALER_MINT_parse_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; @@ -228,6 +228,23 @@ process_post_json (struct MHD_Connection *connection, } +/** + * Function called whenever we are done with a request + * to clean up our state. + * + * @param con_cls value as it was left by + * #TALER_MINT_parse_post_json(), to be cleaned up + */ +void +TALER_MINT_parse_post_cleanup_callback (void *con_cls) +{ + struct Buffer *r = con_cls; + + if (NULL != r) + buffer_deinit (r); +} + + /** * Navigate through a JSON tree. * @@ -451,3 +468,5 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection, ? GNUNET_SYSERR : GNUNET_NO; return GNUNET_OK; } + +/* end of taler-mint-httpd_parsing.c */ diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h index 2c6bb073c..d9516d486 100644 --- a/src/mint/taler-mint-httpd_parsing.h +++ b/src/mint/taler-mint-httpd_parsing.h @@ -68,25 +68,45 @@ enum /** - * Process a POST request containing a JSON object. + * 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 + * "connection_cls", which must be cleaned up using + * #TALER_MINT_parse_post_cleanup_callback(). * * @param connection the MHD connection - * @param con_cs the closure (contains a 'struct Buffer *') + * @param con_cs the closure (points to a `struct Buffer *`) * @param upload_data the POST data - * @param upload_data_size the POST data size + * @param upload_data_size number of bytes in @a upload_data * @param json the JSON object for a completed request * * @returns - * GNUNET_YES if json object was parsed + * GNUNET_YES if json object was parsed or at least + * may be parsed in the future (call again) * GNUNET_NO is request incomplete or invalid + * (error message was generated) * GNUNET_SYSERR on internal error + * (we could not even queue an error message, + * close HTTP session with MHD_NO) */ int -process_post_json (struct MHD_Connection *connection, - void **con_cls, - const char *upload_data, - size_t *upload_data_size, - json_t **json); +TALER_MINT_parse_post_json (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 + * #TALER_MINT_parse_post_json(), to be cleaned up + */ +void +TALER_MINT_parse_post_cleanup_callback (void *con_cls); /** diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 73b474194..83225fc15 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -606,7 +606,7 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, struct GNUNET_HashContext *hash_context; struct GNUNET_HashCode melt_hash; - res = process_post_json (connection, + res = TALER_MINT_parse_post_json (connection, connection_cls, upload_data, upload_data_size, &root); @@ -823,7 +823,7 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh, struct GNUNET_HashContext *hash_context; json_t *root; - res = process_post_json (connection, + res = TALER_MINT_parse_post_json (connection, connection_cls, upload_data, upload_data_size, &root); @@ -1159,7 +1159,7 @@ TALER_MINT_handler_refresh_reveal (struct RequestHandler *rh, int j; json_t *root; - res = process_post_json (connection, + res = TALER_MINT_parse_post_json (connection, connection_cls, upload_data, upload_data_size, &root); diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h index 0e48341fd..230904519 100644 --- a/src/mint/taler-mint-httpd_responses.h +++ b/src/mint/taler-mint-httpd_responses.h @@ -90,4 +90,6 @@ TALER_MINT_reply_arg_missing (struct MHD_Connection *connection, const char *param_name); + + #endif