diff options
| author | Christian Grothoff <christian@grothoff.org> | 2021-04-01 12:07:44 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2021-04-01 12:10:01 +0200 | 
| commit | 4345e6b43447fd56213190b31e3ced2af1829f2d (patch) | |
| tree | a99ca8d3a365d08dae91e2ab139541f43866dba5 /src/exchange/taler-exchange-httpd.c | |
| parent | 7c485a21537c13132fadefae1787bd01c1bc195a (diff) | |
fix spec compliance for 405 reply, handle OPTIONS request with asterisk-form (RFC 7230, section 5.3.4)
Diffstat (limited to 'src/exchange/taler-exchange-httpd.c')
| -rw-r--r-- | src/exchange/taler-exchange-httpd.c | 69 | 
1 files changed, 62 insertions, 7 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 3b8d6ed8..917b686e 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -966,13 +966,19 @@ handle_mhd_request (void *cls,      return ret;    } +  if ( (0 == strcasecmp (method, +                         MHD_HTTP_METHOD_OPTIONS)) && +       (0 == strcmp ("*", +                     url)) ) +    return TALER_MHD_reply_cors_preflight (connection); +    if (0 == strcasecmp (method,                         MHD_HTTP_METHOD_HEAD))      method = MHD_HTTP_METHOD_GET;   /* treat HEAD as GET here, MHD will do the rest */    /* parse first part of URL */    { -    int found = GNUNET_NO; +    bool found = false;      size_t tok_size;      const char *tok;      const char *rest; @@ -1000,7 +1006,7 @@ handle_mhd_request (void *cls,                            tok_size)) ||             (tok_size != strlen (rh->url) ) )          continue; -      found = GNUNET_YES; +      found = true;        /* The URL is a match!  What we now do depends on the method. */        if (0 == strcasecmp (method, MHD_HTTP_METHOD_OPTIONS))        { @@ -1027,14 +1033,63 @@ handle_mhd_request (void *cls,        }      } -    if (GNUNET_YES == found) +    if (found)      {        /* we found a matching address, but the method is wrong */ +      struct MHD_Response *reply; +      MHD_RESULT ret; +      char *allowed = NULL; +        GNUNET_break_op (0); -      return TALER_MHD_reply_with_error (connection, -                                         MHD_HTTP_METHOD_NOT_ALLOWED, -                                         TALER_EC_GENERIC_METHOD_INVALID, -                                         method); +      for (unsigned int i = 0; NULL != handlers[i].url; i++) +      { +        struct TEH_RequestHandler *rh = &handlers[i]; + +        if ( (0 != strncmp (tok, +                            rh->url, +                            tok_size)) || +             (tok_size != strlen (rh->url) ) ) +          continue; +        if (NULL == allowed) +        { +          allowed = GNUNET_strdup (rh->method); +        } +        else +        { +          char *tmp; + +          GNUNET_asprintf (&tmp, +                           "%s, %s", +                           allowed, +                           rh->method); +          GNUNET_free (allowed); +          allowed = tmp; +        } +        if (0 == strcasecmp (rh->method, +                             MHD_HTTP_METHOD_GET)) +        { +          char *tmp; + +          GNUNET_asprintf (&tmp, +                           "%s, %s", +                           allowed, +                           MHD_HTTP_METHOD_HEAD); +          GNUNET_free (allowed); +          allowed = tmp; +        } +      } +      reply = TALER_MHD_make_error (TALER_EC_GENERIC_METHOD_INVALID, +                                    method); +      GNUNET_break (MHD_YES == +                    MHD_add_response_header (reply, +                                             MHD_HTTP_HEADER_ALLOW, +                                             allowed)); +      GNUNET_free (allowed); +      ret = MHD_queue_response (connection, +                                MHD_HTTP_METHOD_NOT_ALLOWED, +                                reply); +      MHD_destroy_response (reply); +      return ret;      }    }  | 
