gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: fix spec compliance for 405 repl


From: gnunet
Subject: [taler-merchant] branch master updated: fix spec compliance for 405 reply, handle OPTIONS request with asterisk-form (RFC 7230, section 5.3.4)
Date: Thu, 01 Apr 2021 12:12:36 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new fb6d4b23 fix spec compliance for 405 reply, handle OPTIONS request 
with asterisk-form (RFC 7230, section 5.3.4)
fb6d4b23 is described below

commit fb6d4b23a34436310b9646f14913ba1c4cd4b071
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Apr 1 12:07:48 2021 +0200

    fix spec compliance for 405 reply, handle OPTIONS request with 
asterisk-form (RFC 7230, section 5.3.4)
---
 src/backend/taler-merchant-httpd.c | 184 +++++++++++++++++++++++++++++--------
 1 file changed, 147 insertions(+), 37 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c 
b/src/backend/taler-merchant-httpd.c
index a1727a3f..fdb752c9 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -962,6 +962,23 @@ TMH_add_instance (struct TMH_MerchantInstance *mi)
 }
 
 
+/**
+ * Handle a OPTIONS "*" request.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] hc context with further information about the request
+ * @return MHD result code
+ */
+static MHD_RESULT
+handle_server_options (const struct TMH_RequestHandler *rh,
+                       struct MHD_Connection *connection,
+                       struct TMH_HandlerContext *hc)
+{
+  return TALER_MHD_reply_cors_preflight (connection);
+}
+
+
 /**
  * Extract the token from authorization header value @a auth.
  *
@@ -993,6 +1010,65 @@ extract_token (const char **auth)
 }
 
 
+/**
+ * Checks if the @a rh matches the given (parsed) URL.
+ *
+ * @param rh handler to compare against
+ * @param url the main URL (without "/private/" prefix, if any)
+ * @param prefix_strlen length of the prefix, i.e. 8 for '/orders/' or 7 for 
'/config'
+ * @param infix_url infix text, i.e. "$ORDER_ID".
+ * @param infix_strlen length of the string in @a infix_url
+ * @param suffix_url suffix, i.e. "/refund", including the "/"
+ * @param suffix_strlen number of characters in @a suffix_url
+ * @return true if @a rh matches this request
+ */
+static bool
+prefix_match (const struct TMH_RequestHandler *rh,
+              const char *url,
+              size_t prefix_strlen,
+              const char *infix_url,
+              size_t infix_strlen,
+              const char *suffix_url,
+              size_t suffix_strlen)
+{
+  if ( (prefix_strlen != strlen (rh->url_prefix)) ||
+       (0 != memcmp (url,
+                     rh->url_prefix,
+                     prefix_strlen)) )
+    return false;
+  if (! rh->have_id_segment)
+  {
+    if (NULL != suffix_url)
+      return false;       /* too many segments to match */
+    if ( (NULL == infix_url)
+         ^ (NULL == rh->url_suffix) )
+      return false;       /* suffix existence mismatch */
+    if ( (NULL != infix_url) &&
+         ( (infix_strlen != strlen (rh->url_suffix)) ||
+           (0 != memcmp (infix_url,
+                         rh->url_suffix,
+                         infix_strlen)) ) )
+      return false;       /* cannot use infix as suffix: content mismatch */
+  }
+  else
+  {
+    if ( (NULL == infix_url)
+         ^ (! rh->have_id_segment) )       // FIXME: have_id_segment is always 
'true' here!
+      return false;       /* infix existence mismatch */
+    if ( ( (NULL == suffix_url)
+           ^ (NULL == rh->url_suffix) ) )
+      return false;       /* suffix existence mismatch */
+    if ( (NULL != suffix_url) &&
+         ( (suffix_strlen != strlen (rh->url_suffix)) ||
+           (0 != memcmp (suffix_url,
+                         rh->url_suffix,
+                         suffix_strlen)) ) )
+      return false;       /* suffix content mismatch */
+  }
+  return true;
+}
+
+
 /**
  * A client has requested the given url using the given method
  * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
@@ -1450,6 +1526,11 @@ url_handler (void *cls,
       .have_id_segment = true,
       .handler = &TMH_return_static
     },
+    {
+      .url_prefix = "*",
+      .method = MHD_HTTP_METHOD_OPTIONS,
+      .handler = &handle_server_options
+    },
     {
       NULL
     }
@@ -1658,40 +1739,14 @@ url_handler (void *cls,
       {
         struct TMH_RequestHandler *rh = &handlers[i];
 
-        if ( (prefix_strlen != strlen (rh->url_prefix)) ||
-             (0 != memcmp (url,
-                           rh->url_prefix,
-                           prefix_strlen)) )
+        if (! prefix_match (rh,
+                            url,
+                            prefix_strlen,
+                            infix_url,
+                            infix_strlen,
+                            suffix_url,
+                            suffix_strlen))
           continue;
-        if (! rh->have_id_segment)
-        {
-          if (NULL != suffix_url)
-            continue; /* too many segments to match */
-          if ( (NULL == infix_url)
-               ^ (NULL == rh->url_suffix) )
-            continue; /* suffix existence mismatch */
-          if ( (NULL != infix_url) &&
-               ( (infix_strlen != strlen (rh->url_suffix)) ||
-                 (0 != memcmp (infix_url,
-                               rh->url_suffix,
-                               infix_strlen)) ) )
-            continue; /* cannot use infix as suffix: content mismatch */
-        }
-        else
-        {
-          if ( (NULL == infix_url)
-               ^ (! rh->have_id_segment) ) // FIXME: have_id_segment is always 
'true' here!
-            continue; /* infix existence mismatch */
-          if ( ( (NULL == suffix_url)
-                 ^ (NULL == rh->url_suffix) ) )
-            continue; /* suffix existence mismatch */
-          if ( (NULL != suffix_url) &&
-               ( (suffix_strlen != strlen (rh->url_suffix)) ||
-                 (0 != memcmp (suffix_url,
-                               rh->url_suffix,
-                               suffix_strlen)) ) )
-            continue; /* suffix content mismatch */
-        }
         url_found = true;
         if (0 == strcasecmp (method,
                              MHD_HTTP_METHOD_OPTIONS))
@@ -1707,10 +1762,65 @@ url_handler (void *cls,
       }
       if ( (NULL == hc->rh) &&
            (url_found) )
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_METHOD_NOT_ALLOWED,
-                                           TALER_EC_GENERIC_METHOD_INVALID,
-                                           method);
+      {
+        struct MHD_Response *reply;
+        MHD_RESULT ret;
+        char *allowed = NULL;
+
+        GNUNET_break_op (0);
+        for (unsigned int i = 0; NULL != handlers[i].url_prefix; i++)
+        {
+          struct TMH_RequestHandler *rh = &handlers[i];
+
+          if (! prefix_match (rh,
+                              url,
+                              prefix_strlen,
+                              infix_url,
+                              infix_strlen,
+                              suffix_url,
+                              suffix_strlen))
+            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;
+      }
       if (NULL == hc->rh)
         return TALER_MHD_reply_with_error (connection,
                                            MHD_HTTP_NOT_FOUND,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]