de-duplicate url.c

This commit is contained in:
Christian Grothoff 2020-03-01 13:04:06 +01:00
parent effa6451a2
commit d11a13c825
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 144 additions and 106 deletions

View File

@ -281,7 +281,7 @@ static struct GNUNET_CURL_RescheduleContext *rc;
/** /**
* How long should we sleep when idle before trying to find more work? * How long should we sleep when idle before trying to find more work?
*/ */
static struct GNUNET_TIME_Relative aggreator_idle_sleep_interval; static struct GNUNET_TIME_Relative aggregator_idle_sleep_interval;
/** /**
* Value to return from main(). #GNUNET_OK on success, #GNUNET_SYSERR * Value to return from main(). #GNUNET_OK on success, #GNUNET_SYSERR

View File

@ -29,7 +29,9 @@
/** /**
* Obtain the payment method from a @a payto_uri * Obtain the payment method from a @a payto_uri. The
* format of a payto URI is 'payto://$METHOD/$SOMETHING'.
* We return $METHOD.
* *
* @param payto_uri the URL to parse * @param payto_uri the URL to parse
* @return NULL on error (malformed @a payto_uri) * @return NULL on error (malformed @a payto_uri)
@ -40,9 +42,9 @@ TALER_payto_get_method (const char *payto_uri)
const char *start; const char *start;
const char *end; const char *end;
if (0 != strncmp (payto_uri, if (0 != strncasecmp (payto_uri,
PAYTO, PAYTO,
strlen (PAYTO))) strlen (PAYTO)))
return NULL; return NULL;
start = &payto_uri[strlen (PAYTO)]; start = &payto_uri[strlen (PAYTO)];
end = strchr (start, end = strchr (start,
@ -55,7 +57,10 @@ TALER_payto_get_method (const char *payto_uri)
/** /**
* Obtain the account name from a payto URL. * Obtain the account name from a payto URL. The format
* of the @a payto URL is 'payto://x-taler-bank/$HOSTNAME/$ACCOUNT[?PARAMS]'.
* We check the first part matches, skip over the $HOSTNAME
* and return the $ACCOUNT portion.
* *
* @param payto an x-taler-bank 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 * @return only the account name from the @a payto URL, NULL if not an x-taler-bank
@ -68,18 +73,18 @@ TALER_xtalerbank_account_from_payto (const char *payto)
const char *end; const char *end;
if (0 != strncasecmp (payto, if (0 != strncasecmp (payto,
"payto://x-taler-bank/", PAYTO "x-taler-bank/",
strlen ("payto://x-taler-bank/"))) strlen (PAYTO "x-taler-bank/")))
return NULL; return NULL;
beg = strchr (&payto[strlen ("payto://x-taler-bank/")], beg = strchr (&payto[strlen (PAYTO "x-taler-bank/")],
'/'); '/');
if (NULL == beg) if (NULL == beg)
return NULL; return NULL;
beg++; beg++; /* now points to $ACCOUNT */
end = strchr (beg, end = strchr (beg,
'?'); '?');
if (NULL == end) if (NULL == end)
return GNUNET_strdup (beg); return GNUNET_strdup (beg); /* optional part is missing */
return GNUNET_strndup (beg, return GNUNET_strndup (beg,
end - beg); end - beg);
} }

View File

@ -84,12 +84,14 @@ static void
buffer_write_urlencode (struct GNUNET_Buffer *buf, buffer_write_urlencode (struct GNUNET_Buffer *buf,
const char *s) const char *s)
{ {
GNUNET_buffer_ensure_remaining (buf, urlencode_len (s) + 1); GNUNET_buffer_ensure_remaining (buf,
urlencode_len (s) + 1);
for (size_t i = 0; i < strlen (s); i++) for (size_t i = 0; i < strlen (s); i++)
{ {
if (GNUNET_YES == is_reserved (s[i])) if (GNUNET_YES == is_reserved (s[i]))
GNUNET_buffer_write_fstr (buf, "%%%02X", s[i]); GNUNET_buffer_write_fstr (buf,
"%%%02X",
s[i]);
else else
buf->mem[buf->position++] = s[i]; buf->mem[buf->position++] = s[i];
} }
@ -107,11 +109,95 @@ TALER_urlencode (const char *s)
{ {
struct GNUNET_Buffer buf = { 0 }; struct GNUNET_Buffer buf = { 0 };
buffer_write_urlencode (&buf, s); buffer_write_urlencode (&buf,
s);
return GNUNET_buffer_reap_str (&buf); return GNUNET_buffer_reap_str (&buf);
} }
/**
* Compute the total length of the @a args given. The args are a
* NULL-terminated list of key-value pairs, where the values
* must be URL-encoded. When serializing, the pairs will be separated
* via '?' or '&' and an '=' between key and value. Hence each
* pair takes an extra 2 characters to encode. This function computes
* how many bytes are needed. It must match the #serialize_arguments()
* function.
*
* @param args NULL-terminated key-value pairs (char *) for query parameters
* @return number of bytes needed (excluding 0-terminator) for the string buffer
*/
static size_t
calculate_argument_length (va_list args)
{
size_t len = 0;
va_list ap;
va_copy (ap,
args);
while (1)
{
char *key;
char *value;
key = va_arg (ap,
char *);
if (NULL == key)
break;
value = va_arg (ap,
char *);
if (NULL == value)
continue;
len += urlencode_len (value) + strlen (key) + 2;
}
va_end (ap);
return len;
}
/**
* Take the key-value pairs in @a args and serialize them into
* @a buf, using URL encoding for the values.
*
* @param buf where to write the values
* @param args NULL-terminated key-value pairs (char *) for query parameters,
* the value will be url-encoded
*/
static void
serialize_arguments (struct GNUNET_Buffer *buf,
va_list args)
{
/* used to indicate if we are processing the initial
parameter which starts with '?' or subsequent
parameters which are separated with '&' */
unsigned int iparam = 0;
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 = 1;
GNUNET_buffer_write_str (buf,
key);
GNUNET_buffer_write_str (buf,
"=");
buffer_write_urlencode (buf,
value);
}
}
/** /**
* Make an absolute URL with query parameters. * Make an absolute URL with query parameters.
* *
@ -127,9 +213,8 @@ TALER_url_join (const char *base_url,
const char *path, const char *path,
...) ...)
{ {
unsigned int iparam = 0;
va_list args;
struct GNUNET_Buffer buf = { 0 }; struct GNUNET_Buffer buf = { 0 };
va_list args;
size_t len; size_t len;
GNUNET_assert (NULL != base_url); GNUNET_assert (NULL != base_url);
@ -157,46 +242,20 @@ TALER_url_join (const char *base_url,
return NULL; return NULL;
} }
/* 1st pass: compute length */ va_start (args,
path);
len = strlen (base_url) + strlen (path) + 1; len = strlen (base_url) + strlen (path) + 1;
len += calculate_argument_length (args);
va_start (args, path); GNUNET_buffer_prealloc (&buf,
while (1) len);
{ GNUNET_buffer_write_str (&buf,
char *key; base_url);
char *value; GNUNET_buffer_write_str (&buf,
key = va_arg (args, char *); path);
if (NULL == key) serialize_arguments (&buf,
break; args);
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); va_end (args);
return GNUNET_buffer_reap_str (&buf); return GNUNET_buffer_reap_str (&buf);
@ -222,56 +281,26 @@ TALER_url_absolute_raw_va (const char *proto,
va_list args) va_list args)
{ {
struct GNUNET_Buffer buf = { 0 }; struct GNUNET_Buffer buf = { 0 };
unsigned int iparam = 0;
size_t len = 0; size_t len = 0;
va_list args2;
len += strlen (proto) + strlen ("://") + strlen (host); len += strlen (proto) + strlen ("://") + strlen (host);
len += strlen (prefix) + strlen (path); len += strlen (prefix) + strlen (path);
len += calculate_argument_length (args);
va_copy (args2, args); GNUNET_buffer_prealloc (&buf,
while (1) len);
{ GNUNET_buffer_write_str (&buf,
char *key; proto);
char *value; GNUNET_buffer_write_str (&buf,
key = va_arg (args2, char *); "://");
if (NULL == key) GNUNET_buffer_write_str (&buf,
break; host);
value = va_arg (args2, char *); GNUNET_buffer_write_path (&buf,
if (NULL == value) prefix);
continue; GNUNET_buffer_write_path (&buf,
len += urlencode_len (value) + strlen (key) + 2; path);
} serialize_arguments (&buf,
va_end (args2); args);
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); return GNUNET_buffer_reap_str (&buf);
} }
@ -285,7 +314,7 @@ TALER_url_absolute_raw_va (const char *proto,
* @param path path for the URL * @param path path for the URL
* @param ... NULL-terminated key-value pairs (char *) for query parameters, * @param ... NULL-terminated key-value pairs (char *) for query parameters,
* the value will be url-encoded * the value will be url-encoded
* @returns the URL, must be freed with #GNUNET_free * @return the URL, must be freed with #GNUNET_free
*/ */
char * char *
TALER_url_absolute_raw (const char *proto, TALER_url_absolute_raw (const char *proto,
@ -297,8 +326,13 @@ TALER_url_absolute_raw (const char *proto,
char *result; char *result;
va_list args; va_list args;
va_start (args, path); va_start (args,
result = TALER_url_absolute_raw_va (proto, host, prefix, path, args); path);
result = TALER_url_absolute_raw_va (proto,
host,
prefix,
path,
args);
va_end (args); va_end (args);
return result; return result;
} }

View File

@ -25,9 +25,8 @@
/** /**
* Convert a buffer to an 8-character string * Convert a buffer to an 8-character string representative of the
* representative of the contents. This is used * contents. This is used for logging binary data when debugging.
* for logging binary data when debugging.
* *
* @param buf buffer to log * @param buf buffer to log
* @param buf_size number of bytes in @a buf * @param buf_size number of bytes in @a buf