⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 url.c

📁 Internet Phone, Chat, Conferencing
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (!net_path) {      url->url_user = host;      host = NULL;    } else if ((atsign = strchr(host, '@'))) {      char *user;      url->url_user = user = host;      if (atsign)	*atsign++ = '\0';      host = atsign;      if (url->url_type != url_unknown) {	char *colon = strchr(user, ':');	if (colon)	  *colon++ = '\0';	url->url_password = colon;      }    }    if ((url->url_host = host)) {      /* IPv6 (and in some cases, IPv4) addresses are quoted with [] */      if (host[0] == '[') {	port = strchr(host, ']');	if (!port)	  return -1;	port = strchr(port + 1, ':');      }      else 	port = strchr(host, ':');      if (port) {	*port++ = '\0';	url->url_port = port;	switch (url->url_type) {	case url_any:	case url_sip:	case url_sips:	case url_http:	case url_https:	case url_ftp:	case url_file:	case url_rtsp:	case url_rtspu:	  	  if (!url_canonize2(port, port, -1, RESERVED_MASK))	    return -1;	  /* Check that port is really numeric or wildcard */	  /* Port can be *digit, empty string or "*" */	  while (*port >= '0' && *port <= '9')	    port++;	  if (port != url->url_port 	      ? port[0] != '\0' 	      : port[0] != '\0'	      && (port[0] != '*' || port[1] != '\0'))	    return -1;	}      }    }  }  if (rest_c == '/') {    url->url_path = s; n = strcspn(s, "?#");    rest_c = s[n]; s[n] = 0; s = rest_c ? s + n + 1 : NULL;  }  if (rest_c == ';') {    url->url_params = s; n = strcspn(s, "?#");    rest_c = s[n]; s[n] = 0; s = rest_c ? s + n + 1 : NULL;  }  if (rest_c == '?') {    url->url_headers = s; n = strcspn(s, "#");    rest_c = s[n]; s[n] = 0; s = rest_c ? s + n + 1 : NULL;  }  if (rest_c == '#') {    url->url_fragment = s;    rest_c = '\0';  }  if (rest_c)    return -1;  return 0;}/* Unreserved things *//** * Decode a URL. * * This function decodes a URL string to a url_t structure. * * @param url structure to store the parsing result * @param s   NUL-terminated string to be parsed * * @note The parsed string @a s will be modified when parsing it. * * @retval 0 if successful,  * @retval -1 otherwise. */int url_d(url_t *url, char *s){  if (url == NULL || _url_d(url, s) < 0)    return -1;  /* Canonize  URL */  /* scheme is canonized by _url_d() */  if (url->url_type == url_sip || url->url_type == url_sips) {#   define SIP_USER_UNRESERVED "&=+$,;?/"    s = (char *)url->url_user;    if (s && !url_canonize(s, s, -1, SIP_USER_UNRESERVED))      return -1;#   define SIP_PASS_UNRESERVED "&=+$,"    s = (char *)url->url_password;    if (s && !url_canonize(s, s, -1, SIP_PASS_UNRESERVED))      return -1;  } else {#   define USER_UNRESERVED "&=+$,;"    s = (char *)url->url_user;    if (s && !url_canonize(s, s, -1, USER_UNRESERVED))      return -1;#   define PASS_UNRESERVED "&=+$,;:"    s = (char *)url->url_password;    if (s && !url_canonize(s, s, -1, PASS_UNRESERVED))      return -1;  }  s = (char *)url->url_host;  if (s && !url_canonize2(s, s, -1, RESERVED_MASK))    return -1;  /* port is canonized by _url_d() */  /* Allow all URI characters but ? and ; */# define PATH_UNRESERVED "/:@&=+$,"  s = (char *)url->url_path;  if (s && !url_canonize(s, s, -1, PATH_UNRESERVED))    return -1;  /* Allow all URI characters but ? */# define PARAMS_UNRESERVED ";" PATH_UNRESERVED  s = (char *)url->url_params;  if (s && !url_canonize(s, s, -1, PARAMS_UNRESERVED))    return -1;    /* Unhex alphanumeric and unreserved URI characters */  s = (char *)url->url_headers;  if (s && !url_canonize3(s, s, -1, RESERVED_MASK))    return -1;  /* Allow all URI characters (including reserved ones) */  s = (char *)url->url_fragment;  if (s && !url_canonize2(s, s, -1, URIC_MASK))    return -1;  return 0;}/** Encode an URL.  *  * The function url_e() combines a URL from substrings in url_t structure * according the @ref url_syntax "URL syntax" presented above.  The encoded * @a url is stored in a @a buffer of @a n bytes. * * @param buffer memory area to store the encoded @a url. * @param n      size of @a buffer. * @param url    URL to be encoded. * * @return  * The function url_e() returns the number of bytes in the encoding.   * * @note The function follows the convention set by C99 snprintf().  Even if * the result does not fit into the @a buffer and it is truncated, the * function returns the number of bytes in an untruncated encoding. */int url_e(char buffer[], int n, url_t const *url){  int i;  char *b = buffer;  int m = n;  int do_copy = n > 0;  if (url == NULL)    return -1;  if (URL_STRING_P(url)) {    char const *u = (char *)url;    i = strlen(u);    if (!buffer)      return i;    if (i >= n) {      memcpy(buffer, u, n - 2);      buffer[n - 1] = '\0';    } else {      memcpy(buffer, u, i + 1);    }    return i;  }  if (url->url_type == url_any) {    if (b && m > 0) {      if (m > 1) strcpy(b, "*"); else b[0] = '\0';    }    return 1;  }  if (url->url_scheme && url->url_scheme[0]) {    i = strlen(url->url_scheme) + 1;    if (do_copy && (do_copy = i <= n)) {      memcpy(b, url->url_scheme, i - 1);      b[i - 1] = ':';    }    b += i; n -= i;  }  if (url->url_root && (url->url_host || url->url_user)) {    if (do_copy && (do_copy = 2 <= n))      memcpy(b, "//", 2);    b += 2; n -= 2;  }  if (url->url_user) {    i = strlen(url->url_user);    if (do_copy && (do_copy = i <= n))      memcpy(b, url->url_user, i);    b += i; n -= i;    if (url->url_password) {      if (do_copy && (do_copy = 1 <= n))	*b = ':';       b++; n--;      i = strlen(url->url_password);      if (do_copy && (do_copy = i <= n))	memcpy(b, url->url_password, i);      b += i; n -= i;    }    if (url->url_host) {      if (do_copy && (do_copy = 1 <= n))	*b = '@';       b++; n--;    }  }  if (url->url_host) {    i = strlen(url->url_host);    if (do_copy && (do_copy = i <= n))      memcpy(b, url->url_host, i);    b += i; n -= i;    if (url->url_port) {      i = strlen(url->url_port) + 1;      if (do_copy && (do_copy = i <= n)) {	b[0] = ':';	memcpy(b + 1, url->url_port, i - 1);      }       b += i; n -= i;    }  }  if (url->url_path) {    if (url->url_root) {      if (do_copy && (do_copy = 1 <= n))	b[0] = '/';      b++, n--;    }    i = strlen(url->url_path);    if (do_copy && (do_copy = i < n))      memcpy(b, url->url_path, i);    b += i; n -= i;  }    {    static char const sep[] = ";?#";    char const *pp[3];    int j;    pp[0] = url->url_params;    pp[1] = url->url_headers;    pp[2] = url->url_fragment;    for (j = 0; j < 3; j++) {      char const *p = pp[j];      if (!p) continue;      i = strlen(p) + 1;      if (do_copy && (do_copy = i <= n)) {	*b = sep[j];	memcpy(b + 1, p, i - 1);      }      b += i; n -= i;    }  }  if (do_copy && (do_copy = 1 <= n))    *b = '\0';  else if (buffer && m > 0)    buffer[m - 1] = '\0';  assert(b - buffer == m - n);    /* This follows the snprintf(C99) return value,    * Number of characters written (excluding NUL)   */  return b - buffer;}/** Calculate the lengh of URL when encoded.  * */int url_len(url_t const * url){  int rv = 0;  if (url->url_scheme) rv += strlen(url->url_scheme) + 1; /* plus ':' */  if (url->url_user) {    rv += strlen(url->url_user);    if (url->url_password)       rv += strlen(url->url_password) + 1;   /* plus ':' */    rv += url->url_host != NULL;  /* plus '@' */  }  if (url->url_host) rv += strlen(url->url_host);  if (url->url_port) rv += strlen(url->url_port) + 1;	        /* plus ':' */  if (url->url_path) rv += strlen(url->url_path) + 1;     /* plus initial / */  if (url->url_params) rv += strlen(url->url_params) + 1; /* plus initial ; */  if (url->url_headers) rv += strlen(url->url_headers) + 1;	/* plus '?' */  if (url->url_fragment) rv += strlen(url->url_fragment) + 1;   /* plus '#' */  return rv;}/**@def URL_E(buf, end, url) * Encode an URL: use @a buf up to @a end.  * @hideinitializer *//**  * Calculate the size of strings associated with a #url_t sructure. * * @param url pointer to a #url_t structure or string * @return Number of bytes for URL */int url_xtra(url_t const *url){  if (URL_STRING_P(url)) {    return strlen((char const *)url) + 1;  }  else {    unsigned len_scheme, len_user, len_password,      len_host, len_port, len_path, len_params,       len_headers, len_fragment;    len_scheme = (url->url_type <= url_unknown && url->url_scheme) ?      strlen(url->url_scheme) + 1 : 0;    len_user = url->url_user ? strlen(url->url_user) + 1 : 0;    len_password = url->url_password ? strlen(url->url_password) + 1 : 0;    len_host = url->url_host ? strlen(url->url_host) + 1 : 0;    len_port = url->url_port ? strlen(url->url_port) + 1 : 0;    len_path = url->url_path ? strlen(url->url_path) + 1 : 0;    len_params = url->url_params ? strlen(url->url_params) + 1 : 0;    len_headers = url->url_headers ? strlen(url->url_headers) + 1 : 0;    len_fragment = url->url_fragment ? strlen(url->url_fragment) + 1 : 0;    return       len_scheme + len_user + len_password + len_host + len_port +      len_path + len_params + len_headers + len_fragment;  }}static inlinechar *copy(char *buf, char *end, char const *src){#if HAVE_MEMCCPY  char *b = memccpy(buf, src, '\0', end - buf);  if (b)    return b;  else    return end + strlen(src + (end - buf)) + 1;#else  for (; buf < end && (*buf = *src); buf++, src++)    ;  if (buf >= end)     while (*src++)      buf++;  return buf + 1;#endif}/**  * Duplicate the url. *  * The function url_dup() copies the url structure @a src and the strings * attached to it to @a url.  The non-constant strings in @a src are copied * to @a buf.  If the size of duplicated strings exceed @a bufsize, the  * corresponding string fields in @a url are set to NULL. * * The calling function can calculate the size of buffer required by calling * url_dup() with zero as @a bufsize and NULL as @a dst. * @param buf     Buffer for non-constant strings copied from @a src. * @param bufsize Size of @a buf. * @param dst     Destination URL structure. *燖param src     Source URL structure. * * @return The function url_dup() returns number of characters required for * duplicating the strings in @a str, or -1 if an error * occurred. */int url_dup(char *buf, int bufsize, url_t *dst, url_t const *src){  if (!src && !dst)    return -1;  else if (URL_STRING_P(src)) {    int n = strlen((char *)src) + 1;    if (n > bufsize || dst == NULL)      return n;    strcpy(buf, (char *)src);    memset(dst, 0, sizeof(*dst));    if (url_d(dst, buf) < 0)      return -1;    return n;  }  else {    char *b = buf;    char *end = b + bufsize;    char const **dstp;     char const * const *srcp;    url_t dst0[1];    if (dst == NULL)      dst = dst0;    memset(dst, 0, sizeof(*dst));    if (!src)      return 0;    memset(dst->url_pad, 0, sizeof dst->url_pad);    dst->url_type = src->url_type;    dst->url_root = src->url_root;    dstp = &dst->url_scheme;    srcp = &src->url_scheme;    if (dst->url_type > url_unknown)      *dstp = url_scheme(dst->url_type);    if (*dstp != NULL)      dstp++, srcp++;	/* Skip scheme if it is constant */    if (dst != dst0 && buf != NULL && bufsize != 0)      for (; srcp <= &src->url_fragment; srcp++, dstp++)	if (*srcp) {	  char *next = copy(b, end, *srcp);	  if (next > end)	    break;	  *dstp = b, b = next;	}    for (; srcp <= &src->url_fragment; srcp++)      if (*srcp) {	b += strlen(*srcp) + 1;      }    return b - buf;  }}/**@def URL_DUP(buf, end, dst, src) *  Duplicate the url: use @a buf up to @a end. @HI  * * The macro URL_DUP() duplicates the url.  The non-constant strings in @a * src are copied to @a buf.  However, no strings are copied past @a end. * In other words, the size of buffer is @a end - @a buf. * * The macro updates the buffer pointer @a buf, so that it points to the * first unused byte in the buffer.  The buffer pointer @a buf is updated, * even if the buffer is too small for the duplicated strings. * * @param buf     Buffer for non-constant strings copied from @a src. * @param end     End of @a buf. * @param dst     Destination URL structure. *燖param src     Source URL structure. * * @return  * The macro URL_DUP() returns pointer to first unused byte in the  * buffer @a buf. *//** Duplicate the url to memory allocated via home. * * The function url_hdup() duplicates (deep copies) an #url_t structure.  * Alternatively, it can be passed a string; string is then copied and * parsed to the #url_t structure. * * The function url_hdup() allocates the destination structure from @a home * as a single memory block. It is possible to free the copied url structure * and all the associated strings using a single call to su_free(). * * @param home memory home used to allocate new url object * @param src  pointer to URL (or string) * * @return * The function url_hdup() returns a pointer to the newly allocated #url_t * structure, or NULL upon an error. */ url_t *url_hdup(su_home_t *home, url_t const *src){  if (src) {    int len = sizeof(*src) + url_xtra(src), actual;    url_t *dst = su_alloc(home, len);    if (dst) {      actual = url_dup((char *)(dst + 1), len - sizeof(*src), dst, src);      if (actual < 0)	su_free(home, dst), dst = NULL;      else	assert(len == sizeof(*src) + actual);    }    return dst;  }  else    return NULL;}/** Convert an string to an url */ url_t *url_make(su_home_t *h, char const *str){  return url_hdup(h, URL_STRING_MAKE(str)->us_url);}/** Print an URL */ url_t *url_format(su_home_t *h, char const *fmt, ...){  url_t *url;  char *us;  va_list ap;  va_start(ap, fmt);  us = su_vsprintf(h, fmt, ap);  va_end(ap);  if (us == NULL)    return NULL;  url = url_hdup(h, URL_STRING_MAKE(us)->us_url);  su_free(h, us);  return url;}/** Convert @a url to a string allocated from @a home */char *url_as_string(su_home_t *home, url_t const *url){  if (url) {    int len = url_e(NULL, 0, url);    char *b = su_alloc(home, len + 1);    url_e(b, len + 1, url);    return b;  } else {    return NULL;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -