summaryrefslogtreecommitdiff
path: root/src/util/util.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-01-19 20:33:07 +0100
committerChristian Grothoff <christian@grothoff.org>2020-01-19 20:33:07 +0100
commit59398cfd76ed01df0ba5f33022727047afd6b270 (patch)
tree0da425ba9a3e0aeaff94d058f653d59f73f46dcc /src/util/util.c
parent600592dbf6aced50a92cced8ab9d773d06f0f4f4 (diff)
downloadexchange-59398cfd76ed01df0ba5f33022727047afd6b270.tar.gz
exchange-59398cfd76ed01df0ba5f33022727047afd6b270.tar.bz2
exchange-59398cfd76ed01df0ba5f33022727047afd6b270.zip
separate util.c and url.c
Diffstat (limited to 'src/util/util.c')
-rw-r--r--src/util/util.c548
1 files changed, 1 insertions, 547 deletions
diff --git a/src/util/util.c b/src/util/util.c
index c9fd5a81f..f49bc7c2e 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -15,16 +15,13 @@
*/
/**
* @file util.c
- * @brief Common utility functions; we might choose to move those to GNUnet at some point
+ * @brief Common utility functions
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Florian Dold
* @author Benedikt Mueller
*/
-
#include "platform.h"
-#include "gnunet/gnunet_buffer_lib.h"
#include "taler_util.h"
-#include <gcrypt.h>
/**
@@ -59,547 +56,4 @@ TALER_b2s (const void *buf,
}
-/**
- * Obtain denomination amount from configuration file.
- *
- * @param cfg configuration to use
- * @param section section of the configuration to access
- * @param option option of the configuration to access
- * @param[out] denom set to the amount found in configuration
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-int
-TALER_config_get_denom (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *section,
- const char *option,
- struct TALER_Amount *denom)
-{
- char *str;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- section,
- option,
- &str))
- return GNUNET_NO;
- if (GNUNET_OK != TALER_string_to_amount (str,
- denom))
- {
- GNUNET_free (str);
- return GNUNET_SYSERR;
- }
- GNUNET_free (str);
- return GNUNET_OK;
-}
-
-
-/**
- * Set an option with an amount from the command line. A pointer to
- * this function should be passed as part of the 'struct
- * GNUNET_GETOPT_CommandLineOption' array to initialize options of
- * this type.
- *
- * @param ctx command line processing context
- * @param scls additional closure (will point to the `struct TALER_Amount`)
- * @param option name of the option
- * @param value actual value of the option as a string.
- * @return #GNUNET_OK if parsing the value worked
- */
-static int
-set_amount (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
- void *scls,
- const char *option,
- const char *value)
-{
- struct TALER_Amount *amount = scls;
-
- (void) ctx;
- if (GNUNET_OK !=
- TALER_string_to_amount (value,
- amount))
- {
- fprintf (stderr,
- _ ("Failed to parse amount in option `%s'\n"),
- option);
- return GNUNET_SYSERR;
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Allow user to specify an amount on the command line.
- *
- * @param shortName short name of the option
- * @param name long name of the option
- * @param argumentHelp help text for the option argument
- * @param description long help text for the option
- * @param[out] amount set to the amount specified at the command line
- */
-struct GNUNET_GETOPT_CommandLineOption
-TALER_getopt_get_amount (char shortName,
- const char *name,
- const char *argumentHelp,
- const char *description,
- struct TALER_Amount *amount)
-{
- struct GNUNET_GETOPT_CommandLineOption clo = {
- .shortName = shortName,
- .name = name,
- .argumentHelp = argumentHelp,
- .description = description,
- .require_argument = 1,
- .processor = &set_amount,
- .scls = (void *) amount
- };
-
- return clo;
-}
-
-
-/**
- * Check if a character is reserved and should
- * be urlencoded.
- *
- * @param c character to look at
- * @return #GNUNET_YES if @a c needs to be urlencoded,
- * #GNUNET_NO otherwise
- */
-static bool
-is_reserved (char c)
-{
- switch (c)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f': case 'g': case 'h': case 'i': case 'j':
- case 'k': case 'l': case 'm': case 'n': case 'o':
- case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F': case 'G': case 'H': case 'I': case 'J':
- case 'K': case 'L': case 'M': case 'N': case 'O':
- case 'P': case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
- case '-': case '.': case '_': case '~':
- return GNUNET_NO;
- default:
- break;
- }
- return GNUNET_YES;
-}
-
-
-/**
- * Get the length of a string after it has been
- * urlencoded.
- *
- * @param s the string
- * @returns the size of the urlencoded @a s
- */
-static size_t
-urlencode_len (const char *s)
-{
- size_t len = 0;
- for (; *s != '\0'; len++, s++)
- if (GNUNET_YES == is_reserved (*s))
- len += 2;
- return len;
-}
-
-
-/**
- * URL-encode a string according to rfc3986.
- *
- * @param buf buffer to write the result to
- * @param s string to encode
- */
-static void
-buffer_write_urlencode (struct GNUNET_Buffer *buf, const char *s)
-{
- GNUNET_buffer_ensure_remaining (buf, urlencode_len (s) + 1);
-
- for (size_t i = 0; i < strlen (s); i++)
- {
- if (GNUNET_YES == is_reserved (s[i]))
- GNUNET_buffer_write_fstr (buf, "%%%02X", s[i]);
- else
- buf->mem[buf->position++] = s[i];
- }
-}
-
-
-/**
- * URL-encode a string according to rfc3986.
- *
- * @param s string to encode
- * @returns the urlencoded string, the caller must free it with GNUNET_free
- */
-char *
-TALER_urlencode (const char *s)
-{
- struct GNUNET_Buffer buf = { 0 };
-
- buffer_write_urlencode (&buf, s);
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-/**
- * Make an absolute URL with query parameters.
- *
- * @param base_url absolute base URL to use
- * @param path path of the url
- * @param ... NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL (must be freed with #GNUNET_free) or
- * NULL if an error occured.
- */
-char *
-TALER_url_join (const char *base_url,
- const char *path,
- ...)
-{
- unsigned int iparam = 0;
- va_list args;
- struct GNUNET_Buffer buf = { 0 };
- size_t len;
-
- GNUNET_assert (NULL != base_url);
- GNUNET_assert (NULL != path);
- if (0 == strlen (base_url))
- {
- /* base URL can't be empty */
- GNUNET_break (0);
- return NULL;
- }
- if ('/' != base_url[strlen (base_url) - 1])
- {
- /* Must be an actual base URL! */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Base URL `%s' does not end with '/'\n",
- base_url);
- return NULL;
- }
- if ('/' == path[0])
- {
- /* The path must be relative. */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Path `%s' is not relative\n",
- path);
- return NULL;
- }
-
- /* 1st pass: compute length */
- len = strlen (base_url) + strlen (path) + 1;
-
- va_start (args, path);
- while (1)
- {
- char *key;
- char *value;
- key = va_arg (args, char *);
- if (NULL == key)
- break;
- value = va_arg (args, char *);
- if (NULL == value)
- continue;
- len += urlencode_len (value) + strlen (key) + 2;
- }
- va_end (args);
-
- GNUNET_buffer_prealloc (&buf, len);
- GNUNET_buffer_write_str (&buf, base_url);
- GNUNET_buffer_write_str (&buf, path);
-
- va_start (args, path);
- while (1)
- {
- char *key;
- char *value;
-
- key = va_arg (args, char *);
- if (NULL == key)
- break;
- value = va_arg (args, char *);
- if (NULL == value)
- continue;
- GNUNET_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
- iparam++;
- GNUNET_buffer_write_str (&buf, key);
- GNUNET_buffer_write_str (&buf, "=");
- buffer_write_urlencode (&buf, value);
- }
- va_end (args);
-
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-/**
- * Make an absolute URL for the given parameters.
- *
- * @param proto protocol for the URL (typically https)
- * @param host hostname for the URL
- * @param prefix prefix for the URL
- * @param path path for the URL
- * @param args NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL, must be freed with #GNUNET_free
- */
-char *
-TALER_url_absolute_raw_va (const char *proto,
- const char *host,
- const char *prefix,
- const char *path,
- va_list args)
-{
- struct GNUNET_Buffer buf = { 0 };
- unsigned int iparam = 0;
- size_t len = 0;
- va_list args2;
-
- len += strlen (proto) + strlen ("://") + strlen (host);
- len += strlen (prefix) + strlen (path);
-
- va_copy (args2, args);
- while (1)
- {
- char *key;
- char *value;
- key = va_arg (args2, char *);
- if (NULL == key)
- break;
- value = va_arg (args2, char *);
- if (NULL == value)
- continue;
- len += urlencode_len (value) + strlen (key) + 2;
- }
- va_end (args2);
-
- GNUNET_buffer_prealloc (&buf, len);
-
- GNUNET_buffer_write_str (&buf, proto);
- GNUNET_buffer_write_str (&buf, "://");
- GNUNET_buffer_write_str (&buf, host);
-
- GNUNET_buffer_write_path (&buf, prefix);
- GNUNET_buffer_write_path (&buf, path);
-
- va_copy (args2, args);
- while (1)
- {
- char *key;
- char *value;
- key = va_arg (args, char *);
- if (NULL == key)
- break;
- value = va_arg (args, char *);
- if (NULL == value)
- continue;
- GNUNET_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
- iparam++;
- GNUNET_buffer_write_str (&buf, key);
- GNUNET_buffer_write_str (&buf, "=");
- buffer_write_urlencode (&buf, value);
- }
- va_end (args2);
-
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-/**
- * Make an absolute URL for the given parameters.
- *
- * @param proto protocol for the URL (typically https)
- * @param host hostname for the URL
- * @param prefix prefix for the URL
- * @param path path for the URL
- * @param ... NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL, must be freed with #GNUNET_free
- */
-char *
-TALER_url_absolute_raw (const char *proto,
- const char *host,
- const char *prefix,
- const char *path,
- ...)
-{
- char *result;
- va_list args;
-
- va_start (args, path);
- result = TALER_url_absolute_raw_va (proto, host, prefix, path, args);
- va_end (args);
- return result;
-}
-
-
-/**
- * Find out if an MHD connection is using HTTPS (either
- * directly or via proxy).
- *
- * @param connection MHD connection
- * @returns GNUNET_YES if the MHD connection is using https,
- * GNUNET_NO if the MHD connection is using http,
- * GNUNET_SYSERR if the connection type couldn't be determined
- */
-int
-TALER_mhd_is_https (struct MHD_Connection *connection)
-{
- const union MHD_ConnectionInfo *ci;
- const union MHD_DaemonInfo *di;
- const char *forwarded_proto = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- "X-Forwarded-Proto");
-
- if (NULL != forwarded_proto)
- {
- if (0 == strcmp (forwarded_proto, "https"))
- return GNUNET_YES;
- if (0 == strcmp (forwarded_proto, "http"))
- return GNUNET_NO;
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- /* likely not reverse proxy, figure out if we are
- http by asking MHD */
- ci = MHD_get_connection_info (connection, MHD_CONNECTION_INFO_DAEMON);
- if (NULL == ci)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- di = MHD_get_daemon_info (ci->daemon, MHD_DAEMON_INFO_FLAGS);
- if (NULL == di)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (0 != (di->flags & MHD_USE_TLS))
- return GNUNET_YES;
- return GNUNET_NO;
-}
-
-
-/**
- * Make an absolute URL for a given MHD connection.
- *
- * @param connection the connection to get the URL for
- * @param path path of the url
- * @param ... NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL, must be freed with #GNUNET_free
- */
-char *
-TALER_url_absolute_mhd (struct MHD_Connection *connection,
- const char *path,
- ...)
-{
- /* By default we assume we're running under HTTPS */
- const char *proto;
- const char *host;
- const char *forwarded_host;
- const char *prefix;
- va_list args;
- char *result;
-
- if (GNUNET_YES == TALER_mhd_is_https (connection))
- proto = "https";
- else
- proto = "http";
-
- host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Host");
- forwarded_host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
- "X-Forwarded-Host");
-
- prefix = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
- "X-Forwarded-Prefix");
- if (NULL == prefix)
- prefix = "";
-
- if (NULL != forwarded_host)
- host = forwarded_host;
-
- if (NULL == host)
- {
- /* Should never happen, at last the host header should be defined */
- GNUNET_break (0);
- return NULL;
- }
-
- va_start (args, path);
- result = TALER_url_absolute_raw_va (proto, host, prefix, path, args);
- va_end (args);
- return result;
-}
-
-
-/**
- * Prefix of PAYTO URLs.
- */
-#define PAYTO "payto://"
-
-
-/**
- * Obtain the payment method from a @a payto_uri
- *
- * @param payto_uri the URL to parse
- * @return NULL on error (malformed @a payto_uri)
- */
-char *
-TALER_payto_get_method (const char *payto_uri)
-{
- const char *start;
- const char *end;
-
- if (0 != strncmp (payto_uri,
- PAYTO,
- strlen (PAYTO)))
- return NULL;
- start = &payto_uri[strlen (PAYTO)];
- end = strchr (start,
- (unsigned char) '/');
- if (NULL == end)
- return NULL;
- return GNUNET_strndup (start,
- end - start);
-}
-
-
-/**
- * Obtain the account name from a payto URL.
- *
- * @param payto an x-taler-bank payto URL
- * @return only the account name from the @a payto URL, NULL if not an x-taler-bank
- * payto URL
- */
-char *
-TALER_xtalerbank_account_from_payto (const char *payto)
-{
- const char *beg;
- const char *end;
-
- if (0 != strncasecmp (payto,
- "payto://x-taler-bank/",
- strlen ("payto://x-taler-bank/")))
- return NULL;
- beg = strchr (&payto[strlen ("payto://x-taler-bank/")],
- '/');
- if (NULL == beg)
- return NULL;
- beg++;
- end = strchr (beg,
- '?');
- if (NULL == end)
- return GNUNET_strdup (beg);
- return GNUNET_strndup (beg,
- end - beg);
-}
-
-
/* end of util.c */