diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/Makefile.am | 2 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_config.c | 111 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_policy-upload.c | 117 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_policy.c | 24 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_truth-challenge.c | 27 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_truth-solve.c | 62 | ||||
-rw-r--r-- | src/backend/anastasis-httpd_truth-upload.c | 92 |
7 files changed, 159 insertions, 276 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index db37478..c1b0931 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -37,11 +37,9 @@ anastasis_httpd_LDADD = \ -ltalerjson \ -ltalerutil \ -lgnunetcurl \ - -lgnunetrest \ -lgnunetjson \ -lgnunetutil \ -lmicrohttpd \ - -luuid \ $(XLIB) EXTRA_DIST = \ diff --git a/src/backend/anastasis-httpd_config.c b/src/backend/anastasis-httpd_config.c index 015fd01..315419e 100644 --- a/src/backend/anastasis-httpd_config.c +++ b/src/backend/anastasis-httpd_config.c @@ -1,6 +1,6 @@ /* This file is part of Anastasis - Copyright (C) 2020, 2021 Anastasis SARL + Copyright (C) 2020, 2021, 2024 Anastasis SARL Anastasis is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -78,46 +78,83 @@ MHD_RESULT AH_handler_config (struct AH_RequestHandler *rh, struct MHD_Connection *connection) { - json_t *method_arr = json_array (); + static struct MHD_Response *response; + static struct GNUNET_TIME_Absolute a; - GNUNET_assert (NULL != method_arr); + if ( (GNUNET_TIME_absolute_is_past (a)) && + (NULL != response) ) { - json_t *method; + MHD_destroy_response (response); + response = NULL; + } + if (NULL == response) + { + json_t *method_arr = json_array (); + struct GNUNET_TIME_Timestamp km; + char dat[128]; + + GNUNET_assert (NULL != method_arr); + a = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS); + /* Round up to next full day to ensure the expiration + time does not become a fingerprint! */ + a = GNUNET_TIME_absolute_round_down (a, + GNUNET_TIME_UNIT_DAYS); + a = GNUNET_TIME_absolute_add (a, + GNUNET_TIME_UNIT_DAYS); + /* => /config response stays at most 48h in caches! */ + km = GNUNET_TIME_absolute_to_timestamp (a); + TALER_MHD_get_date_string (km.abs_time, + dat); + { + json_t *method; + + method = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("type", + "question"), + TALER_JSON_pack_amount ("cost", + &AH_question_cost)); + GNUNET_assert ( + 0 == + json_array_append_new (method_arr, + method)); + } + GNUNET_CONFIGURATION_iterate_sections (AH_cfg, + &add_methods, + method_arr); - method = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("type", - "question"), - TALER_JSON_pack_amount ("cost", - &AH_question_cost)); - GNUNET_assert ( - 0 == - json_array_append_new (method_arr, - method)); + response = TALER_MHD_MAKE_JSON_PACK ( + GNUNET_JSON_pack_string ("name", + "anastasis"), + GNUNET_JSON_pack_string ("version", + "0:2:0"), + GNUNET_JSON_pack_string ("implementation", + "urn:net:taler:specs:anastasis:c-reference"), + GNUNET_JSON_pack_string ("business_name", + AH_business_name), + GNUNET_JSON_pack_array_steal ("methods", + method_arr), + GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes", + AH_upload_limit_mb), + TALER_JSON_pack_amount ("annual_fee", + &AH_annual_fee), + TALER_JSON_pack_amount ("truth_upload_fee", + &AH_truth_upload_fee), + TALER_JSON_pack_amount ("liability_limit", + &AH_insurance), + GNUNET_JSON_pack_data_auto ("provider_salt", + &AH_provider_salt)); + GNUNET_break (MHD_YES == + MHD_add_response_header (response, + MHD_HTTP_HEADER_EXPIRES, + dat)); + GNUNET_break (MHD_YES == + MHD_add_response_header (response, + MHD_HTTP_HEADER_CACHE_CONTROL, + "public,max-age=21600")); /* 6h */ } - GNUNET_CONFIGURATION_iterate_sections (AH_cfg, - &add_methods, - method_arr); - return TALER_MHD_REPLY_JSON_PACK ( - connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_string ("name", - "anastasis"), - GNUNET_JSON_pack_string ("version", - "0:0:0"), - GNUNET_JSON_pack_string ("business_name", - AH_business_name), - GNUNET_JSON_pack_array_steal ("methods", - method_arr), - GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes", - AH_upload_limit_mb), - TALER_JSON_pack_amount ("annual_fee", - &AH_annual_fee), - TALER_JSON_pack_amount ("truth_upload_fee", - &AH_truth_upload_fee), - TALER_JSON_pack_amount ("liability_limit", - &AH_insurance), - GNUNET_JSON_pack_data_auto ("provider_salt", - &AH_provider_salt)); + return MHD_queue_response (connection, + MHD_HTTP_OK, + response); } diff --git a/src/backend/anastasis-httpd_policy-upload.c b/src/backend/anastasis-httpd_policy-upload.c index 94a38bc..83e8117 100644 --- a/src/backend/anastasis-httpd_policy-upload.c +++ b/src/backend/anastasis-httpd_policy-upload.c @@ -387,15 +387,14 @@ proposal_cb (void *cls, * Callback to process a GET /check-payment request * * @param cls our `struct PolicyUploadContext` - * @param hr HTTP response details * @param osr order status */ static void check_payment_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, const struct TALER_MERCHANT_OrderStatusResponse *osr) { struct PolicyUploadContext *puc = cls; + const struct TALER_MERCHANT_HttpResponse *hr = &osr->hr; /* refunds are not supported, verify */ puc->cpo = NULL; @@ -422,10 +421,12 @@ check_payment_cb (void *cls, puc->response_code = MHD_HTTP_BAD_GATEWAY; return; } + + GNUNET_assert (MHD_HTTP_OK == hr->http_status); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Payment status checked: %s\n", - osr->status ? "paid" : "unpaid"); - switch (osr->status) + "Payment status checked: %d\n", + osr->details.ok.status); + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -440,7 +441,7 @@ check_payment_cb (void *cls, GNUNET_JSON_spec_end () }; - contract = osr->details.paid.contract_terms; + contract = osr->details.ok.details.paid.contract_terms; if (GNUNET_OK != GNUNET_JSON_parse (contract, cspec, @@ -536,7 +537,6 @@ await_payment (struct PolicyUploadContext *puc) AH_backend_url, order_id, NULL /* our payments are NOT session-bound */, - false, timeout, &check_payment_cb, puc); @@ -557,6 +557,7 @@ await_payment (struct PolicyUploadContext *puc) static MHD_RESULT begin_payment (struct PolicyUploadContext *puc) { + static const char *no_uuids[1] = { NULL }; json_t *order; GNUNET_CONTAINER_DLL_insert (puc_head, @@ -607,7 +608,7 @@ begin_payment (struct PolicyUploadContext *puc) 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, puc); @@ -661,34 +662,10 @@ AH_handler_policy_post ( hc->cc = &cleanup_ctx; puc->con = connection; - { - const char *pay_id; - - pay_id = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER); - if (NULL != pay_id) - { - if (GNUNET_OK != - GNUNET_STRINGS_string_to_data ( - pay_id, - strlen (pay_id), - &puc->payment_identifier, - sizeof (struct ANASTASIS_PaymentSecretP))) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER - " header must be a base32-encoded Payment-Secret"); - } - puc->payment_identifier_provided = true; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Policy upload started with payment identifier `%s'\n", - pay_id); - } - } + TALER_MHD_parse_request_header_auto (connection, + ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER, + &puc->payment_identifier, + puc->payment_identifier_provided); puc->account = *account_pub; /* check for meta-data */ @@ -767,28 +744,10 @@ AH_handler_policy_post ( } puc->upload_size = (size_t) len; } - { - /* Check if header contains Anastasis-Policy-Signature */ - const char *sig_s; - sig_s = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE); - if ( (NULL == sig_s) || - (GNUNET_OK != - GNUNET_STRINGS_string_to_data (sig_s, - strlen (sig_s), - &puc->account_sig, - sizeof (puc->account_sig))) ) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_ANASTASIS_POLICY_BAD_SIGNATURE, - ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE - " header must include a base32-encoded EdDSA signature"); - } - } + TALER_MHD_parse_request_header_auto_t (connection, + ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE, + &puc->account_sig); { /* Check if header contains an ETAG */ const char *etag; @@ -797,9 +756,12 @@ AH_handler_policy_post ( MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_NONE_MATCH); if ( (NULL == etag) || + (2 >= strlen (etag)) || + ('"' != etag[0]) || + ('"' != etag[strlen (etag) - 1]) || (GNUNET_OK != - GNUNET_STRINGS_string_to_data (etag, - strlen (etag), + GNUNET_STRINGS_string_to_data (etag + 1, + strlen (etag) - 2, &puc->new_policy_upload_hash, sizeof (puc->new_policy_upload_hash))) ) { @@ -833,39 +795,10 @@ AH_handler_policy_post ( } } - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - puc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - } - else - { - puc->timeout = GNUNET_TIME_relative_to_absolute ( - CHECK_PAYMENT_GENERIC_TIMEOUT); - } - } + puc->timeout = GNUNET_TIME_relative_to_absolute ( + CHECK_PAYMENT_GENERIC_TIMEOUT); + TALER_MHD_parse_request_timeout (connection, + &puc->timeout); /* check if the client insists on paying */ { diff --git a/src/backend/anastasis-httpd_policy.c b/src/backend/anastasis-httpd_policy.c index a26d11e..177cc06 100644 --- a/src/backend/anastasis-httpd_policy.c +++ b/src/backend/anastasis-httpd_policy.c @@ -122,25 +122,30 @@ return_policy (struct MHD_Connection *connection, { char *sig_s; char *etag; + char *etagq; sig_s = GNUNET_STRINGS_data_to_string_alloc (&account_sig, sizeof (account_sig)); - etag = GNUNET_STRINGS_data_to_string_alloc (&recovery_data_hash, - sizeof (recovery_data_hash)); GNUNET_break (MHD_YES == MHD_add_response_header (resp, ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE, sig_s)); + GNUNET_free (sig_s); GNUNET_break (MHD_YES == MHD_add_response_header (resp, ANASTASIS_HTTP_HEADER_POLICY_VERSION, version_s)); + etag = GNUNET_STRINGS_data_to_string_alloc (&recovery_data_hash, + sizeof (recovery_data_hash)); + GNUNET_asprintf (&etagq, + "\"%s\"", + etag); + GNUNET_free (etag); GNUNET_break (MHD_YES == MHD_add_response_header (resp, MHD_HTTP_HEADER_ETAG, - etag)); - GNUNET_free (etag); - GNUNET_free (sig_s); + etagq)); + GNUNET_free (etagq); } { MHD_RESULT ret; @@ -203,13 +208,16 @@ AH_policy_get (struct MHD_Connection *connection, inm = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_NONE_MATCH); - if (NULL != inm) + if ( (NULL != inm) && + (2 < strlen (inm)) && + ('"' == inm[0]) && + ('"' == inm[strlen (inm) - 1]) ) { struct GNUNET_HashCode inm_h; if (GNUNET_OK != - GNUNET_STRINGS_string_to_data (inm, - strlen (inm), + GNUNET_STRINGS_string_to_data (inm + 1, + strlen (inm) - 2, &inm_h, sizeof (inm_h))) { diff --git a/src/backend/anastasis-httpd_truth-challenge.c b/src/backend/anastasis-httpd_truth-challenge.c index 30379a7..a7d138f 100644 --- a/src/backend/anastasis-httpd_truth-challenge.c +++ b/src/backend/anastasis-httpd_truth-challenge.c @@ -360,22 +360,17 @@ AH_truth_challenge_shutdown (void) * Callback to process a POST /orders/ID/refund request * * @param cls closure with a `struct RefundEntry *` - * @param hr HTTP response details - * @param taler_refund_uri the refund uri offered to the wallet - * @param h_contract hash of the contract a Browser may need to authorize - * obtaining the HTTP response. + * @param rr response details */ static void refund_cb ( void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const char *taler_refund_uri, - const struct TALER_PrivateContractHashP *h_contract) + const struct TALER_MERCHANT_RefundResponse *rr) { struct RefundEntry *re = cls; re->ro = NULL; - switch (hr->http_status) + switch (rr->hr.http_status) { case MHD_HTTP_OK: { @@ -407,9 +402,9 @@ refund_cb ( GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Refund `%s' failed with HTTP status %u: %s (#%u)\n", re->order_id, - hr->http_status, - hr->hint, - (unsigned int) hr->ec); + rr->hr.http_status, + rr->hr.hint, + (unsigned int) rr->hr.ec); break; } GNUNET_CONTAINER_DLL_remove (re_head, @@ -650,16 +645,15 @@ proposal_cb (void *cls, * Callback to process a GET /check-payment request * * @param cls our `struct ChallengeContext` - * @param hr HTTP response details * @param osr order status */ static void check_payment_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, const struct TALER_MERCHANT_OrderStatusResponse *osr) { struct ChallengeContext *gc = cls; + const struct TALER_MERCHANT_HttpResponse *hr = &osr->hr; gc->cpo = NULL; GNUNET_assert (gc->in_list); @@ -713,7 +707,8 @@ check_payment_cb (void *cls, } } - switch (osr->status) + GNUNET_assert (MHD_HTTP_OK == hr->http_status); + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -796,7 +791,6 @@ begin_payment (struct ChallengeContext *gc) AH_backend_url, order_id, NULL /* NOT session-bound */, - false, timeout, &check_payment_cb, gc); @@ -804,6 +798,7 @@ begin_payment (struct ChallengeContext *gc) else { /* Create a fresh order */ + static const char *no_uuids[1] = { NULL }; json_t *order; struct GNUNET_TIME_Timestamp pay_deadline; @@ -837,7 +832,7 @@ begin_payment (struct ChallengeContext *gc) 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, gc); diff --git a/src/backend/anastasis-httpd_truth-solve.c b/src/backend/anastasis-httpd_truth-solve.c index 8133cc9..eb09dc7 100644 --- a/src/backend/anastasis-httpd_truth-solve.c +++ b/src/backend/anastasis-httpd_truth-solve.c @@ -199,14 +199,24 @@ static struct GNUNET_SCHEDULER_Task *to_task; static MHD_RESULT reply_rate_limited (const struct SolveContext *gc) { + if (NULL != gc->authorization) + return TALER_MHD_REPLY_JSON_PACK ( + gc->connection, + MHD_HTTP_TOO_MANY_REQUESTS, + TALER_MHD_PACK_EC (TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED), + GNUNET_JSON_pack_uint64 ("request_limit", + gc->authorization->retry_counter), + GNUNET_JSON_pack_time_rel ("request_frequency", + gc->authorization->code_rotation_period)); + /* must be security question */ return TALER_MHD_REPLY_JSON_PACK ( gc->connection, MHD_HTTP_TOO_MANY_REQUESTS, TALER_MHD_PACK_EC (TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED), GNUNET_JSON_pack_uint64 ("request_limit", - gc->authorization->retry_counter), + INITIAL_RETRY_COUNTER), GNUNET_JSON_pack_time_rel ("request_frequency", - gc->authorization->code_rotation_period)); + MAX_QUESTION_FREQ)); } @@ -482,16 +492,15 @@ proposal_cb (void *cls, * Callback to process a GET /check-payment request * * @param cls our `struct SolveContext` - * @param hr HTTP response details * @param osr order status */ static void check_payment_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, const struct TALER_MERCHANT_OrderStatusResponse *osr) { struct SolveContext *gc = cls; + const struct TALER_MERCHANT_HttpResponse *hr = &osr->hr; gc->cpo = NULL; GNUNET_assert (gc->in_list); @@ -545,7 +554,8 @@ check_payment_cb (void *cls, } } - switch (osr->status) + GNUNET_assert (MHD_HTTP_OK == hr->http_status); + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -628,7 +638,6 @@ begin_payment (struct SolveContext *gc) AH_backend_url, order_id, NULL /* NOT session-bound */, - false, timeout, &check_payment_cb, gc); @@ -636,6 +645,7 @@ begin_payment (struct SolveContext *gc) else { /* Create a fresh order */ + static const char *no_uuids[1] = { NULL }; json_t *order; struct GNUNET_TIME_Timestamp pay_deadline; @@ -669,7 +679,7 @@ begin_payment (struct SolveContext *gc) 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, gc); @@ -1130,40 +1140,10 @@ AH_handler_truth_solve ( gc->connection = connection; gc->truth_uuid = *truth_uuid; gc->hc->cc = &request_done; - - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - gc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - } - else - { - gc->timeout = GNUNET_TIME_relative_to_absolute ( - GNUNET_TIME_UNIT_SECONDS); - } - } + gc->timeout = GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_SECONDS); + TALER_MHD_parse_request_timeout (connection, + &gc->timeout); } /* end of first-time initialization (if NULL == gc) */ else { diff --git a/src/backend/anastasis-httpd_truth-upload.c b/src/backend/anastasis-httpd_truth-upload.c index 356dc36..1c2a58d 100644 --- a/src/backend/anastasis-httpd_truth-upload.c +++ b/src/backend/anastasis-httpd_truth-upload.c @@ -287,15 +287,14 @@ proposal_cb (void *cls, * Callback to process a GET /check-payment request * * @param cls our `struct PolicyUploadContext` - * @param hr HTTP response details * @param osr order status */ static void check_payment_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, const struct TALER_MERCHANT_OrderStatusResponse *osr) { struct TruthUploadContext *tuc = cls; + const struct TALER_MERCHANT_HttpResponse *hr = &osr->hr; tuc->cpo = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -311,7 +310,7 @@ check_payment_cb (void *cls, NULL); break; case MHD_HTTP_OK: - switch (osr->status) + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { @@ -326,7 +325,7 @@ check_payment_cb (void *cls, GNUNET_JSON_spec_end () }; - contract = osr->details.paid.contract_terms; + contract = osr->details.ok.details.paid.contract_terms; if (GNUNET_OK != GNUNET_JSON_parse (contract, cspec, @@ -355,7 +354,7 @@ check_payment_cb (void *cls, qs = db->record_truth_upload_payment ( db->cls, &tuc->truth_uuid, - &osr->details.paid.deposit_total, + &osr->details.ok.details.paid.deposit_total, paid_until); if (qs <= 0) { @@ -397,6 +396,7 @@ check_payment_cb (void *cls, case MHD_HTTP_NOT_FOUND: /* Setup fresh order */ { + static const char *no_uuids[1] = { NULL }; char *order_id; json_t *order; @@ -416,7 +416,6 @@ check_payment_cb (void *cls, "description", "challenge storage fee", "quantity", (json_int_t) tuc->years_to_pay, "unit", "years", - "order_id", order_id); GNUNET_free (order_id); @@ -428,7 +427,7 @@ check_payment_cb (void *cls, 0, NULL, /* no inventory products */ 0, - NULL, /* no uuids */ + no_uuids, /* no uuids */ false, /* do NOT require claim token */ &proposal_cb, tuc); @@ -486,7 +485,6 @@ begin_payment (struct TruthUploadContext *tuc) AH_backend_url, order_id, NULL /* our payments are NOT session-bound */, - false, timeout, &check_payment_cb, tuc); @@ -551,78 +549,12 @@ AH_handler_truth_post ( tuc->truth_uuid = *truth_uuid; hc->ctx = tuc; hc->cc = &cleanup_truth_post; - - /* check for excessive upload */ - { - const char *lens; - unsigned long len; - char dummy; - - lens = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_CONTENT_LENGTH); - if ( (NULL == lens) || - (1 != sscanf (lens, - "%lu%c", - &len, - &dummy)) ) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_BAD_REQUEST, - (NULL == lens) - ? TALER_EC_ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH - : TALER_EC_ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH, - NULL); - } - if (len / 1024 / 1024 >= AH_upload_limit_mb) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_PAYLOAD_TOO_LARGE, - TALER_EC_SYNC_MALFORMED_CONTENT_LENGTH, - "Content-length value not acceptable"); - } - } - - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms = MHD_lookup_connection_value (connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout; - char dummy; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - tuc->timeout - = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_MILLISECONDS, - timeout)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Long polling for %u ms enabled\n", - timeout); - } - else - { - tuc->timeout = GNUNET_TIME_relative_to_absolute ( - GNUNET_TIME_UNIT_SECONDS); - } - } - + TALER_MHD_check_content_length (connection, + AH_upload_limit_mb * 1024LLU * 1024LLU); + tuc->timeout = GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_SECONDS); + TALER_MHD_parse_request_timeout (connection, + &tuc->timeout); } /* end 'if (NULL == tuc)' */ if (NULL != tuc->resp) |