diff options
| author | Christian Grothoff <christian@grothoff.org> | 2020-03-01 13:04:06 +0100 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2020-03-01 13:04:06 +0100 | 
| commit | d11a13c825a169e3cc42efa8dca679c14e627d40 (patch) | |
| tree | 57d9f7ff91a65b48d250a590ff0a694b7f4f993f /src | |
| parent | effa6451a265d0a4d745443e9ee022c3f24e1bb8 (diff) | |
de-duplicate url.c
Diffstat (limited to 'src')
| -rw-r--r-- | src/exchange/taler-exchange-aggregator.c | 2 | ||||
| -rw-r--r-- | src/util/payto.c | 25 | ||||
| -rw-r--r-- | src/util/url.c | 222 | ||||
| -rw-r--r-- | src/util/util.c | 5 | 
4 files changed, 146 insertions, 108 deletions
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 550be55c..1a8889fd 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -281,7 +281,7 @@ static struct GNUNET_CURL_RescheduleContext *rc;  /**   * 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 diff --git a/src/util/payto.c b/src/util/payto.c index 484db0bb..3540052c 100644 --- a/src/util/payto.c +++ b/src/util/payto.c @@ -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   * @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 *end; -  if (0 != strncmp (payto_uri, -                    PAYTO, -                    strlen (PAYTO))) +  if (0 != strncasecmp (payto_uri, +                        PAYTO, +                        strlen (PAYTO)))      return NULL;    start = &payto_uri[strlen (PAYTO)];    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   * @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;    if (0 != strncasecmp (payto, -                        "payto://x-taler-bank/", -                        strlen ("payto://x-taler-bank/"))) +                        PAYTO "x-taler-bank/", +                        strlen (PAYTO "x-taler-bank/")))      return NULL; -  beg = strchr (&payto[strlen ("payto://x-taler-bank/")], +  beg = strchr (&payto[strlen (PAYTO "x-taler-bank/")],                  '/');    if (NULL == beg)      return NULL; -  beg++; +  beg++; /* now points to $ACCOUNT */    end = strchr (beg,                  '?');    if (NULL == end) -    return GNUNET_strdup (beg); +    return GNUNET_strdup (beg); /* optional part is missing */    return GNUNET_strndup (beg,                           end - beg);  } diff --git a/src/util/url.c b/src/util/url.c index 2096ebd8..22bdd3fc 100644 --- a/src/util/url.c +++ b/src/util/url.c @@ -84,12 +84,14 @@ static void  buffer_write_urlencode (struct GNUNET_Buffer *buf,                          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++)    {      if (GNUNET_YES == is_reserved (s[i])) -      GNUNET_buffer_write_fstr (buf, "%%%02X", s[i]); +      GNUNET_buffer_write_fstr (buf, +                                "%%%02X", +                                s[i]);      else        buf->mem[buf->position++] = s[i];    } @@ -107,12 +109,96 @@ TALER_urlencode (const char *s)  {    struct GNUNET_Buffer buf = { 0 }; -  buffer_write_urlencode (&buf, s); +  buffer_write_urlencode (&buf, +                          s);    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.   *   * @param base_url absolute base URL to use @@ -127,9 +213,8 @@ TALER_url_join (const char *base_url,                  const char *path,                  ...)  { -  unsigned int iparam = 0; -  va_list args;    struct GNUNET_Buffer buf = { 0 }; +  va_list args;    size_t len;    GNUNET_assert (NULL != base_url); @@ -157,46 +242,20 @@ TALER_url_join (const char *base_url,      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); -  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); -  } +  len = strlen (base_url) + strlen (path) + 1; +  len += calculate_argument_length (args); + +  GNUNET_buffer_prealloc (&buf, +                          len); +  GNUNET_buffer_write_str (&buf, +                           base_url); +  GNUNET_buffer_write_str (&buf, +                           path); +  serialize_arguments (&buf, +                       args);    va_end (args);    return GNUNET_buffer_reap_str (&buf); @@ -222,56 +281,26 @@ TALER_url_absolute_raw_va (const char *proto,                             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); - +  len += calculate_argument_length (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); +  serialize_arguments (&buf, +                       args);    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 ... NULL-terminated key-value pairs (char *) for query parameters,   *        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 *  TALER_url_absolute_raw (const char *proto, @@ -297,8 +326,13 @@ TALER_url_absolute_raw (const char *proto,    char *result;    va_list args; -  va_start (args, path); -  result = TALER_url_absolute_raw_va (proto, host, prefix, path, args); +  va_start (args, +            path); +  result = TALER_url_absolute_raw_va (proto, +                                      host, +                                      prefix, +                                      path, +                                      args);    va_end (args);    return result;  } diff --git a/src/util/util.c b/src/util/util.c index f49bc7c2..489928dd 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -25,9 +25,8 @@  /** - * Convert a buffer to an 8-character string - * representative of the contents. This is used - * for logging binary data when debugging. + * Convert a buffer to an 8-character string representative of the + * contents. This is used for logging binary data when debugging.   *   * @param buf buffer to log   * @param buf_size number of bytes in @a buf  | 
