LCOV - code coverage report
Current view: top level - mhd - mhd_parsing.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 43.9 % 164 72
Test Date: 2026-10-17 15:46:49 Functions: 73.3 % 15 11

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2014--2024 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU Affero General Public License as published by the Free Software
       7              :   Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU Affero General Public License along with
      14              :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15              : */
      16              : /**
      17              :  * @file mhd_parsing.c
      18              :  * @brief functions to parse incoming requests (MHD arguments and JSON snippets)
      19              :  * @author Florian Dold
      20              :  * @author Benedikt Mueller
      21              :  * @author Christian Grothoff
      22              :  */
      23              : #include <gnunet/gnunet_util_lib.h>
      24              : #include <gnunet/gnunet_json_lib.h>
      25              : #include <gnunet/gnunet_mhd_lib.h>
      26              : #include "taler/taler_json_lib.h"
      27              : #include "taler/taler_mhd_lib.h"
      28              : 
      29              : 
      30              : /**
      31              :  * Longest long-poll wait we grant a client, in milliseconds.  While
      32              :  * long-polling, the connection is suspended and thus not subject to
      33              :  * MHD's connection timeout, so without a bound a client could pin the
      34              :  * connection (with its file descriptor and database event handler)
      35              :  * for the lifetime of the process.  Clients simply poll again.
      36              :  */
      37              : #define MAX_TIMEOUT_MS (30LLU * 60 * 1000)
      38              : 
      39              : 
      40              : enum GNUNET_GenericReturnValue
      41         2652 : TALER_MHD_parse_post_json (struct MHD_Connection *connection,
      42              :                            void **con_cls,
      43              :                            const char *upload_data,
      44              :                            size_t *upload_data_size,
      45              :                            json_t **json)
      46              : {
      47              :   enum GNUNET_MHD_PostResult pr;
      48              : 
      49         2652 :   pr = GNUNET_MHD_post_parser (TALER_MHD_REQUEST_BUFFER_MAX,
      50              :                                connection,
      51              :                                con_cls,
      52              :                                upload_data,
      53              :                                upload_data_size,
      54              :                                json);
      55         2652 :   switch (pr)
      56              :   {
      57            0 :   case GNUNET_MHD_PR_OUT_OF_MEMORY:
      58            0 :     GNUNET_break (NULL == *json);
      59              :     return (MHD_NO ==
      60            0 :             TALER_MHD_reply_with_error (
      61              :               connection,
      62              :               MHD_HTTP_INTERNAL_SERVER_ERROR,
      63              :               TALER_EC_GENERIC_PARSER_OUT_OF_MEMORY,
      64            0 :               NULL)) ? GNUNET_SYSERR : GNUNET_NO;
      65              : 
      66         1768 :   case GNUNET_MHD_PR_CONTINUE:
      67         1768 :     GNUNET_break (NULL == *json);
      68         1768 :     return GNUNET_YES;
      69            0 :   case GNUNET_MHD_PR_REQUEST_TOO_LARGE:
      70            0 :     GNUNET_break (NULL == *json);
      71            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
      72              :                 "Closing connection, upload too large\n");
      73            0 :     return GNUNET_SYSERR;
      74            0 :   case GNUNET_MHD_PR_JSON_INVALID:
      75            0 :     GNUNET_break (NULL == *json);
      76              :     return (MHD_YES ==
      77            0 :             TALER_MHD_reply_with_error (connection,
      78              :                                         MHD_HTTP_BAD_REQUEST,
      79              :                                         TALER_EC_GENERIC_JSON_INVALID,
      80              :                                         NULL))
      81            0 :            ? GNUNET_NO : GNUNET_SYSERR;
      82          884 :   case GNUNET_MHD_PR_SUCCESS:
      83          884 :     GNUNET_break (NULL != *json);
      84          884 :     return GNUNET_YES;
      85              :   }
      86              :   /* this should never happen */
      87            0 :   GNUNET_break (0);
      88            0 :   return GNUNET_SYSERR;
      89              : }
      90              : 
      91              : 
      92              : void
      93         1176 : TALER_MHD_parse_post_cleanup_callback (void *con_cls)
      94              : {
      95         1176 :   GNUNET_MHD_post_parser_cleanup (con_cls);
      96         1176 : }
      97              : 
      98              : 
      99              : /**
     100              :  * Extract fixed-size base32crockford encoded data from request.
     101              :  *
     102              :  * Queues an error response to the connection if the parameter is missing or
     103              :  * invalid.
     104              :  *
     105              :  * @param connection the MHD connection
     106              :  * @param param_name the name of the HTTP key with the value
     107              :  * @param kind whether to extract from header, argument or footer
     108              :  * @param[out] out_data pointer to store the result
     109              :  * @param out_size expected size of @a out_data
     110              :  * @param[out] present set to true if argument was found
     111              :  * @return
     112              :  *   #GNUNET_YES if the the argument is present
     113              :  *   #GNUNET_NO if the argument is absent or malformed
     114              :  *   #GNUNET_SYSERR on internal error (error response could not be sent)
     115              :  */
     116              : static enum GNUNET_GenericReturnValue
     117           68 : parse_request_data (
     118              :   struct MHD_Connection *connection,
     119              :   const char *param_name,
     120              :   enum MHD_ValueKind kind,
     121              :   void *out_data,
     122              :   size_t out_size,
     123              :   bool *present)
     124              : {
     125              :   const char *str;
     126              : 
     127           68 :   str = MHD_lookup_connection_value (connection,
     128              :                                      kind,
     129              :                                      param_name);
     130           68 :   if (NULL == str)
     131              :   {
     132            7 :     *present = false;
     133            7 :     return GNUNET_OK;
     134              :   }
     135           61 :   if (GNUNET_OK !=
     136           61 :       GNUNET_STRINGS_string_to_data (str,
     137              :                                      strlen (str),
     138              :                                      out_data,
     139              :                                      out_size))
     140              :   {
     141            0 :     GNUNET_break_op (0);
     142              :     return (MHD_NO ==
     143            0 :             TALER_MHD_reply_with_error (connection,
     144              :                                         MHD_HTTP_BAD_REQUEST,
     145              :                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
     146              :                                         param_name))
     147            0 :            ? GNUNET_SYSERR : GNUNET_NO;
     148              :   }
     149           61 :   *present = true;
     150           61 :   return GNUNET_OK;
     151              : }
     152              : 
     153              : 
     154              : enum GNUNET_GenericReturnValue
     155           18 : TALER_MHD_parse_request_arg_data (
     156              :   struct MHD_Connection *connection,
     157              :   const char *param_name,
     158              :   void *out_data,
     159              :   size_t out_size,
     160              :   bool *present)
     161              : {
     162           18 :   return parse_request_data (connection,
     163              :                              param_name,
     164              :                              MHD_GET_ARGUMENT_KIND,
     165              :                              out_data,
     166              :                              out_size,
     167              :                              present);
     168              : }
     169              : 
     170              : 
     171              : enum GNUNET_GenericReturnValue
     172           50 : TALER_MHD_parse_request_header_data (
     173              :   struct MHD_Connection *connection,
     174              :   const char *header_name,
     175              :   void *out_data,
     176              :   size_t out_size,
     177              :   bool *present)
     178              : {
     179           50 :   return parse_request_data (connection,
     180              :                              header_name,
     181              :                              MHD_HEADER_KIND,
     182              :                              out_data,
     183              :                              out_size,
     184              :                              present);
     185              : }
     186              : 
     187              : 
     188              : enum GNUNET_GenericReturnValue
     189            0 : TALER_MHD_parse_request_arg_rel_time (
     190              :   struct MHD_Connection *connection,
     191              :   const char *label,
     192              :   struct GNUNET_TIME_Relative *duration)
     193              : {
     194              :   const char *ts;
     195              :   char dummy;
     196              :   unsigned long long tms;
     197              : 
     198            0 :   ts = MHD_lookup_connection_value (connection,
     199              :                                     MHD_GET_ARGUMENT_KIND,
     200              :                                     label);
     201            0 :   if (NULL == ts)
     202              :   {
     203            0 :     *duration = GNUNET_TIME_UNIT_ZERO;
     204            0 :     return GNUNET_OK;
     205              :   }
     206            0 :   if (1 !=
     207            0 :       sscanf (ts,
     208              :               "%llu%c",
     209              :               &tms,
     210              :               &dummy))
     211              :   {
     212              :     enum MHD_Result mret;
     213              : 
     214            0 :     GNUNET_break_op (0);
     215            0 :     mret = TALER_MHD_reply_with_error (connection,
     216              :                                        MHD_HTTP_BAD_REQUEST,
     217              :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     218              :                                        label);
     219              :     return (MHD_YES == mret)
     220              :       ? GNUNET_NO
     221            0 :       : GNUNET_SYSERR;
     222              :   }
     223            0 :   *duration = GNUNET_TIME_relative_saturating_multiply (
     224              :     GNUNET_TIME_UNIT_MILLISECONDS,
     225              :     tms);
     226            0 :   return GNUNET_OK;
     227              : }
     228              : 
     229              : 
     230              : enum GNUNET_GenericReturnValue
     231           81 : TALER_MHD_parse_request_arg_timeout (
     232              :   struct MHD_Connection *connection,
     233              :   struct GNUNET_TIME_Absolute *expiration)
     234              : {
     235              :   const char *ts;
     236              :   char dummy;
     237              :   unsigned long long tms;
     238              : 
     239           81 :   ts = MHD_lookup_connection_value (connection,
     240              :                                     MHD_GET_ARGUMENT_KIND,
     241              :                                     "timeout_ms");
     242           81 :   if (NULL == ts)
     243              :   {
     244           50 :     *expiration = GNUNET_TIME_UNIT_ZERO_ABS;
     245           50 :     return GNUNET_OK;
     246              :   }
     247           31 :   if (1 !=
     248           31 :       sscanf (ts,
     249              :               "%llu%c",
     250              :               &tms,
     251              :               &dummy))
     252              :   {
     253              :     enum MHD_Result mret;
     254              : 
     255            0 :     GNUNET_break_op (0);
     256            0 :     mret = TALER_MHD_reply_with_error (connection,
     257              :                                        MHD_HTTP_BAD_REQUEST,
     258              :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     259              :                                        "timeout_ms");
     260              :     return (MHD_YES == mret)
     261              :       ? GNUNET_NO
     262            0 :       : GNUNET_SYSERR;
     263              :   }
     264           31 :   if (tms > MAX_TIMEOUT_MS)
     265            0 :     tms = MAX_TIMEOUT_MS;
     266           31 :   *expiration = GNUNET_TIME_relative_to_absolute (
     267              :     GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
     268              :                                    tms));
     269           31 :   return GNUNET_OK;
     270              : }
     271              : 
     272              : 
     273              : enum GNUNET_GenericReturnValue
     274            0 : TALER_MHD_parse_request_arg_timestamp (
     275              :   struct MHD_Connection *connection,
     276              :   const char *fname,
     277              :   struct GNUNET_TIME_Timestamp *ts)
     278              : {
     279              :   const char *s;
     280              : 
     281            0 :   s = MHD_lookup_connection_value (connection,
     282              :                                    MHD_GET_ARGUMENT_KIND,
     283              :                                    fname);
     284            0 :   if (NULL == s)
     285            0 :     return GNUNET_OK;
     286            0 :   if (GNUNET_OK !=
     287            0 :       GNUNET_STRINGS_fancy_time_to_timestamp (s,
     288              :                                               ts))
     289              :   {
     290              :     enum MHD_Result mret;
     291              : 
     292            0 :     GNUNET_break_op (0);
     293            0 :     mret = TALER_MHD_reply_with_error (
     294              :       connection,
     295              :       MHD_HTTP_BAD_REQUEST,
     296              :       TALER_EC_GENERIC_PARAMETER_MALFORMED,
     297              :       fname);
     298              :     return (MHD_YES == mret)
     299              :       ? GNUNET_NO
     300            0 :       : GNUNET_SYSERR;
     301              :   }
     302            0 :   return GNUNET_OK;
     303              : }
     304              : 
     305              : 
     306              : enum GNUNET_GenericReturnValue
     307          192 : TALER_MHD_parse_request_arg_number (struct MHD_Connection *connection,
     308              :                                     const char *name,
     309              :                                     uint64_t *off)
     310              : {
     311              :   const char *ts;
     312              :   char dummy;
     313              :   unsigned long long num;
     314              : 
     315          192 :   ts = MHD_lookup_connection_value (connection,
     316              :                                     MHD_GET_ARGUMENT_KIND,
     317              :                                     name);
     318          192 :   if (NULL == ts)
     319          178 :     return GNUNET_OK;
     320           14 :   if (1 !=
     321           14 :       sscanf (ts,
     322              :               "%llu%c",
     323              :               &num,
     324              :               &dummy))
     325              :   {
     326              :     enum MHD_Result mret;
     327              : 
     328            0 :     GNUNET_break_op (0);
     329            0 :     mret = TALER_MHD_reply_with_error (connection,
     330              :                                        MHD_HTTP_BAD_REQUEST,
     331              :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     332              :                                        name);
     333              :     return (MHD_YES == mret)
     334              :       ? GNUNET_NO
     335            0 :       : GNUNET_SYSERR;
     336              :   }
     337           14 :   *off = (uint64_t) num;
     338           14 :   return GNUNET_OK;
     339              : }
     340              : 
     341              : 
     342              : enum GNUNET_GenericReturnValue
     343          136 : TALER_MHD_parse_request_arg_snumber (struct MHD_Connection *connection,
     344              :                                      const char *name,
     345              :                                      int64_t *val)
     346              : {
     347              :   const char *ts;
     348              :   char dummy;
     349              :   long long num;
     350              : 
     351          136 :   ts = MHD_lookup_connection_value (connection,
     352              :                                     MHD_GET_ARGUMENT_KIND,
     353              :                                     name);
     354          136 :   if (NULL == ts)
     355          132 :     return GNUNET_OK;
     356            4 :   if (1 !=
     357            4 :       sscanf (ts,
     358              :               "%lld%c",
     359              :               &num,
     360              :               &dummy))
     361              :   {
     362              :     enum MHD_Result mret;
     363              : 
     364            0 :     GNUNET_break_op (0);
     365            0 :     mret = TALER_MHD_reply_with_error (connection,
     366              :                                        MHD_HTTP_BAD_REQUEST,
     367              :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     368              :                                        name);
     369              :     return (MHD_YES == mret)
     370              :       ? GNUNET_NO
     371            0 :       : GNUNET_SYSERR;
     372              :   }
     373            4 :   *val = (int64_t) num;
     374            4 :   return GNUNET_OK;
     375              : }
     376              : 
     377              : 
     378              : enum GNUNET_GenericReturnValue
     379            0 : TALER_MHD_parse_request_arg_amount (struct MHD_Connection *connection,
     380              :                                     const char *name,
     381              :                                     struct TALER_Amount *val)
     382              : {
     383              :   const char *ts;
     384              : 
     385            0 :   ts = MHD_lookup_connection_value (connection,
     386              :                                     MHD_GET_ARGUMENT_KIND,
     387              :                                     name);
     388            0 :   if (NULL == ts)
     389            0 :     return GNUNET_OK;
     390            0 :   if (GNUNET_OK !=
     391            0 :       TALER_string_to_amount (ts,
     392              :                               val))
     393              :   {
     394              :     enum MHD_Result mret;
     395              : 
     396            0 :     GNUNET_break_op (0);
     397            0 :     mret = TALER_MHD_reply_with_error (connection,
     398              :                                        MHD_HTTP_BAD_REQUEST,
     399              :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     400              :                                        name);
     401              :     return (MHD_YES == mret)
     402              :       ? GNUNET_NO
     403            0 :       : GNUNET_SYSERR;
     404              :   }
     405            0 :   return GNUNET_OK;
     406              : }
     407              : 
     408              : 
     409              : enum GNUNET_GenericReturnValue
     410         2860 : TALER_MHD_parse_json_data (struct MHD_Connection *connection,
     411              :                            const json_t *root,
     412              :                            struct GNUNET_JSON_Specification *spec)
     413              : {
     414              :   enum GNUNET_GenericReturnValue ret;
     415              :   const char *error_json_name;
     416              :   unsigned int error_line;
     417              : 
     418         2860 :   ret = GNUNET_JSON_parse (root,
     419              :                            spec,
     420              :                            &error_json_name,
     421              :                            &error_line);
     422         2860 :   if (GNUNET_SYSERR == ret)
     423              :   {
     424            0 :     if (NULL == error_json_name)
     425            0 :       error_json_name = "<no field>";
     426            0 :     ret = (MHD_YES ==
     427            0 :            TALER_MHD_REPLY_JSON_PACK (
     428              :              connection,
     429              :              MHD_HTTP_BAD_REQUEST,
     430              :              GNUNET_JSON_pack_string ("hint",
     431              :                                       TALER_ErrorCode_get_hint (
     432              :                                         TALER_EC_GENERIC_JSON_INVALID)),
     433              :              GNUNET_JSON_pack_uint64 ("code",
     434              :                                       TALER_EC_GENERIC_JSON_INVALID),
     435              :              GNUNET_JSON_pack_string ("field",
     436              :                                       error_json_name),
     437              :              GNUNET_JSON_pack_uint64 ("line",
     438              :                                       error_line)))
     439            0 :           ? GNUNET_NO : GNUNET_SYSERR;
     440            0 :     return ret;
     441              :   }
     442         2860 :   return GNUNET_YES;
     443              : }
     444              : 
     445              : 
     446              : enum GNUNET_GenericReturnValue
     447            0 : TALER_MHD_parse_internal_json_data (struct MHD_Connection *connection,
     448              :                                     const json_t *root,
     449              :                                     struct GNUNET_JSON_Specification *spec)
     450              : {
     451              :   enum GNUNET_GenericReturnValue ret;
     452              :   const char *error_json_name;
     453              :   unsigned int error_line;
     454              : 
     455            0 :   ret = GNUNET_JSON_parse (root,
     456              :                            spec,
     457              :                            &error_json_name,
     458              :                            &error_line);
     459            0 :   if (GNUNET_SYSERR == ret)
     460              :   {
     461            0 :     if (NULL == error_json_name)
     462            0 :       error_json_name = "<no field>";
     463            0 :     ret = (MHD_YES ==
     464            0 :            TALER_MHD_REPLY_JSON_PACK (
     465              :              connection,
     466              :              MHD_HTTP_INTERNAL_SERVER_ERROR,
     467              :              GNUNET_JSON_pack_string ("hint",
     468              :                                       TALER_ErrorCode_get_hint (
     469              :                                         TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE)),
     470              :              GNUNET_JSON_pack_uint64 ("code",
     471              :                                       TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE),
     472              :              GNUNET_JSON_pack_string ("field",
     473              :                                       error_json_name),
     474              :              GNUNET_JSON_pack_uint64 ("line",
     475              :                                       error_line)))
     476            0 :           ? GNUNET_NO : GNUNET_SYSERR;
     477            0 :     return ret;
     478              :   }
     479            0 :   return GNUNET_YES;
     480              : }
     481              : 
     482              : 
     483              : enum GNUNET_GenericReturnValue
     484          132 : TALER_MHD_parse_json_array (struct MHD_Connection *connection,
     485              :                             const json_t *root,
     486              :                             struct GNUNET_JSON_Specification *spec,
     487              :                             ...)
     488              : {
     489              :   enum GNUNET_GenericReturnValue ret;
     490              :   const char *error_json_name;
     491              :   unsigned int error_line;
     492              :   va_list ap;
     493              :   json_int_t dim;
     494              : 
     495          132 :   va_start (ap, spec);
     496          132 :   dim = 0;
     497          264 :   while ( (-1 != (ret = va_arg (ap, int))) &&
     498              :           (NULL != root) )
     499              :   {
     500          132 :     dim++;
     501          132 :     root = json_array_get (root, ret);
     502              :   }
     503          132 :   va_end (ap);
     504          132 :   if (NULL == root)
     505              :   {
     506            0 :     ret = (MHD_YES ==
     507            0 :            TALER_MHD_REPLY_JSON_PACK (
     508              :              connection,
     509              :              MHD_HTTP_BAD_REQUEST,
     510              :              GNUNET_JSON_pack_string ("hint",
     511              :                                       TALER_ErrorCode_get_hint (
     512              :                                         TALER_EC_GENERIC_JSON_INVALID)),
     513              :              GNUNET_JSON_pack_uint64 ("code",
     514              :                                       TALER_EC_GENERIC_JSON_INVALID),
     515              :              GNUNET_JSON_pack_string ("detail",
     516              :                                       "expected array"),
     517              :              GNUNET_JSON_pack_uint64 ("dimension",
     518              :                                       dim)))
     519            0 :           ? GNUNET_NO : GNUNET_SYSERR;
     520            0 :     return ret;
     521              :   }
     522          132 :   ret = GNUNET_JSON_parse (root,
     523              :                            spec,
     524              :                            &error_json_name,
     525              :                            &error_line);
     526          132 :   if (GNUNET_SYSERR == ret)
     527              :   {
     528            0 :     if (NULL == error_json_name)
     529            0 :       error_json_name = "<no field>";
     530            0 :     ret = (MHD_YES ==
     531            0 :            TALER_MHD_REPLY_JSON_PACK (
     532              :              connection,
     533              :              MHD_HTTP_BAD_REQUEST,
     534              :              GNUNET_JSON_pack_string ("detail",
     535              :                                       error_json_name),
     536              :              GNUNET_JSON_pack_string ("hint",
     537              :                                       TALER_ErrorCode_get_hint (
     538              :                                         TALER_EC_GENERIC_JSON_INVALID)),
     539              :              GNUNET_JSON_pack_uint64 ("code",
     540              :                                       TALER_EC_GENERIC_JSON_INVALID),
     541              :              GNUNET_JSON_pack_uint64 ("line",
     542              :                                       error_line)))
     543            0 :           ? GNUNET_NO : GNUNET_SYSERR;
     544            0 :     return ret;
     545              :   }
     546          132 :   return GNUNET_YES;
     547              : }
     548              : 
     549              : 
     550              : enum GNUNET_GenericReturnValue
     551          884 : TALER_MHD_check_content_length_ (struct MHD_Connection *connection,
     552              :                                  unsigned long long max_len)
     553              : {
     554              :   const char *cl;
     555              :   unsigned long long cv;
     556              :   char dummy;
     557              : 
     558              :   /* Maybe check for maximum upload size
     559              :        and refuse requests if they are just too big. */
     560          884 :   cl = MHD_lookup_connection_value (connection,
     561              :                                     MHD_HEADER_KIND,
     562              :                                     MHD_HTTP_HEADER_CONTENT_LENGTH);
     563          884 :   if (NULL == cl)
     564              :   {
     565            0 :     return GNUNET_OK;
     566              : #if 0
     567              :     /* wallet currently doesn't always send content-length! */
     568              :     GNUNET_break_op (0);
     569              :     return (MHD_YES ==
     570              :             TALER_MHD_reply_with_error (connection,
     571              :                                         MHD_HTTP_BAD_REQUEST,
     572              :                                         TALER_EC_GENERIC_PARAMETER_MISSING,
     573              :                                         MHD_HTTP_HEADER_CONTENT_LENGTH))
     574              :       ? GNUNET_NO
     575              :       : GNUNET_SYSERR;
     576              : #endif
     577              :   }
     578          884 :   if (1 != sscanf (cl,
     579              :                    "%llu%c",
     580              :                    &cv,
     581              :                    &dummy))
     582              :   {
     583              :     /* Not valid HTTP request, just close connection. */
     584            0 :     GNUNET_break_op (0);
     585              :     return (MHD_YES ==
     586            0 :             TALER_MHD_reply_with_error (connection,
     587              :                                         MHD_HTTP_BAD_REQUEST,
     588              :                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
     589              :                                         MHD_HTTP_HEADER_CONTENT_LENGTH))
     590              :       ? GNUNET_NO
     591            0 :       : GNUNET_SYSERR;
     592              :   }
     593          884 :   if (cv > max_len)
     594              :   {
     595            0 :     GNUNET_break_op (0);
     596              :     return (MHD_YES ==
     597            0 :             TALER_MHD_reply_request_too_large (connection))
     598              :     ? GNUNET_NO
     599            0 :     : GNUNET_SYSERR;
     600              :   }
     601          884 :   return GNUNET_OK;
     602              : }
     603              : 
     604              : 
     605              : /* end of mhd_parsing.c */
        

Generated by: LCOV version 2.0-1