static void DNSSD_API http_resolve_cb()

in cups/http-support.c [112:416]


static void DNSSD_API	http_resolve_cb(DNSServiceRef sdRef,
					DNSServiceFlags flags,
					uint32_t interfaceIndex,
					DNSServiceErrorType errorCode,
					const char *fullName,
					const char *hostTarget,
					uint16_t port, uint16_t txtLen,
					const unsigned char *txtRecord,
					void *context);
#endif /* HAVE_DNSSD */

#ifdef HAVE_AVAHI
static void	http_client_cb(AvahiClient *client,
			       AvahiClientState state, void *simple_poll);
static int	http_poll_cb(struct pollfd *pollfds, unsigned int num_pollfds,
		             int timeout, void *context);
static void	http_resolve_cb(AvahiServiceResolver *resolver,
				AvahiIfIndex interface,
				AvahiProtocol protocol,
				AvahiResolverEvent event,
				const char *name, const char *type,
				const char *domain, const char *host_name,
				const AvahiAddress *address, uint16_t port,
				AvahiStringList *txt,
				AvahiLookupResultFlags flags, void *context);
#endif /* HAVE_AVAHI */


/*
 * 'httpAssembleURI()' - Assemble a uniform resource identifier from its
 *                       components.
 *
 * This function escapes reserved characters in the URI depending on the
 * value of the "encoding" argument.  You should use this function in
 * place of traditional string functions whenever you need to create a
 * URI string.
 *
 * @since CUPS 1.2/macOS 10.5@
 */

http_uri_status_t			/* O - URI status */
httpAssembleURI(
    http_uri_coding_t encoding,		/* I - Encoding flags */
    char              *uri,		/* I - URI buffer */
    int               urilen,		/* I - Size of URI buffer */
    const char        *scheme,		/* I - Scheme name */
    const char        *username,	/* I - Username */
    const char        *host,		/* I - Hostname or address */
    int               port,		/* I - Port number */
    const char        *resource)	/* I - Resource */
{
  char		*ptr,			/* Pointer into URI buffer */
		*end;			/* End of URI buffer */


 /*
  * Range check input...
  */

  if (!uri || urilen < 1 || !scheme || port < 0)
  {
    if (uri)
      *uri = '\0';

    return (HTTP_URI_STATUS_BAD_ARGUMENTS);
  }

 /*
  * Assemble the URI starting with the scheme...
  */

  end = uri + urilen - 1;
  ptr = http_copy_encode(uri, scheme, end, NULL, NULL, 0);

  if (!ptr)
    goto assemble_overflow;

  if (!strcmp(scheme, "geo") || !strcmp(scheme, "mailto") || !strcmp(scheme, "tel"))
  {
   /*
    * geo:, mailto:, and tel: only have :, no //...
    */

    if (ptr < end)
      *ptr++ = ':';
    else
      goto assemble_overflow;
  }
  else
  {
   /*
    * Schemes other than geo:, mailto:, and tel: typically have //...
    */

    if ((ptr + 2) < end)
    {
      *ptr++ = ':';
      *ptr++ = '/';
      *ptr++ = '/';
    }
    else
      goto assemble_overflow;
  }

 /*
  * Next the username and hostname, if any...
  */

  if (host)
  {
    const char	*hostptr;		/* Pointer into hostname */
    int		have_ipv6;		/* Do we have an IPv6 address? */

    if (username && *username)
    {
     /*
      * Add username@ first...
      */

      ptr = http_copy_encode(ptr, username, end, "/?#[]@", NULL,
                             encoding & HTTP_URI_CODING_USERNAME);

      if (!ptr)
        goto assemble_overflow;

      if (ptr < end)
	*ptr++ = '@';
      else
        goto assemble_overflow;
    }

   /*
    * Then add the hostname.  Since IPv6 is a particular pain to deal
    * with, we have several special cases to deal with.  If we get
    * an IPv6 address with brackets around it, assume it is already in
    * URI format.  Since DNS-SD service names can sometimes look like
    * raw IPv6 addresses, we specifically look for "._tcp" in the name,
    * too...
    */

    for (hostptr = host,
             have_ipv6 = strchr(host, ':') && !strstr(host, "._tcp");
         *hostptr && have_ipv6;
         hostptr ++)
      if (*hostptr != ':' && !isxdigit(*hostptr & 255))
      {
        have_ipv6 = *hostptr == '%';
        break;
      }

    if (have_ipv6)
    {
     /*
      * We have a raw IPv6 address...
      */

      if (strchr(host, '%') && !(encoding & HTTP_URI_CODING_RFC6874))
      {
       /*
        * We have a link-local address, add "[v1." prefix...
	*/

	if ((ptr + 4) < end)
	{
	  *ptr++ = '[';
	  *ptr++ = 'v';
	  *ptr++ = '1';
	  *ptr++ = '.';
	}
	else
          goto assemble_overflow;
      }
      else
      {
       /*
        * We have a normal (or RFC 6874 link-local) address, add "[" prefix...
	*/

	if (ptr < end)
	  *ptr++ = '[';
	else
          goto assemble_overflow;
      }

     /*
      * Copy the rest of the IPv6 address, and terminate with "]".
      */

      while (ptr < end && *host)
      {
        if (*host == '%')
        {
         /*
          * Convert/encode zone separator
          */

          if (encoding & HTTP_URI_CODING_RFC6874)
          {
            if (ptr >= (end - 2))
              goto assemble_overflow;

            *ptr++ = '%';
            *ptr++ = '2';
            *ptr++ = '5';
          }
          else
	    *ptr++ = '+';

	  host ++;
	}
	else
	  *ptr++ = *host++;
      }

      if (*host)
        goto assemble_overflow;

      if (ptr < end)
	*ptr++ = ']';
      else
        goto assemble_overflow;
    }
    else
    {
     /*
      * Otherwise, just copy the host string (the extra chars are not in the
      * "reg-name" ABNF rule; anything <= SP or >= DEL plus % gets automatically
      * percent-encoded.
      */

      ptr = http_copy_encode(ptr, host, end, "\"#/:<>?@[\\]^`{|}", NULL,
                             encoding & HTTP_URI_CODING_HOSTNAME);

      if (!ptr)
        goto assemble_overflow;
    }

   /*
    * Finish things off with the port number...
    */

    if (port > 0)
    {
      snprintf(ptr, (size_t)(end - ptr + 1), ":%d", port);
      ptr += strlen(ptr);

      if (ptr >= end)
	goto assemble_overflow;
    }
  }

 /*
  * Last but not least, add the resource string...
  */

  if (resource)
  {
    char	*query;			/* Pointer to query string */


   /*
    * Copy the resource string up to the query string if present...
    */

    query = strchr(resource, '?');
    ptr   = http_copy_encode(ptr, resource, end, NULL, "?",
                             encoding & HTTP_URI_CODING_RESOURCE);
    if (!ptr)
      goto assemble_overflow;

    if (query)
    {
     /*
      * Copy query string without encoding...
      */

      ptr = http_copy_encode(ptr, query, end, NULL, NULL,
			     encoding & HTTP_URI_CODING_QUERY);
      if (!ptr)
	goto assemble_overflow;
    }
  }
  else if (ptr < end)
    *ptr++ = '/';
  else
    goto assemble_overflow;

 /*
  * Nul-terminate the URI buffer and return with no errors...
  */

  *ptr = '\0';

  return (HTTP_URI_STATUS_OK);

 /*
  * Clear the URI string and return an overflow error; I don't usually
  * like goto's, but in this case it makes sense...
  */

  assemble_overflow:

  *uri = '\0';
  return (HTTP_URI_STATUS_OVERFLOW);
}