[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-merchant] branch master updated: fix spec compliance for 405 reply, handle OPTIONS request with asterisk-form (RFC 7230, section 5.3.4),
gnunet <=