adding logic to free buffers allocated for POST processing when connection dies without completion

This commit is contained in:
Christian Grothoff 2015-01-16 14:04:02 +01:00
parent f58fb4fc21
commit f398b34414
6 changed files with 80 additions and 45 deletions

View File

@ -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)

View File

@ -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);

View File

@ -156,7 +156,7 @@ buffer_append (struct Buffer *buf,
* GNUNET_SYSERR on internal error
*/
int
process_post_json (struct MHD_Connection *connection,
TALER_MINT_parse_post_json (struct MHD_Connection *connection,
void **con_cls,
const char *upload_data,
size_t *upload_data_size,
@ -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 */

View File

@ -68,27 +68,47 @@ 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,
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);
/**
* Navigate through a JSON tree.
*

View File

@ -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);

View File

@ -90,4 +90,6 @@ TALER_MINT_reply_arg_missing (struct MHD_Connection *connection,
const char *param_name);
#endif