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

📄 url.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
    test_scheme(pres); break;  case 'r': case 'R':     test_scheme(rtsp); test_scheme(rtspu); break;  case 's': case 'S':     test_scheme(sip); test_scheme(sips); break;  case 't': case 'T':     test_scheme(tel); break;  case 'w': case 'W':     test_scheme(wv); break;  default: break;  }#undef test_scheme  if (len != span_unreserved(scheme))    return url_invalid;  else    return url_unknown;}/** * Decode a URL. * * This function decodes a (SIP) 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. */staticint _url_d(url_t *url, char *s){  int n;  char *s0, rest_c, *host;  int net_path = 1;  memset(url, 0, sizeof(*url));    if (strcmp(s, "*") == 0) {    url->url_type = url_any;    url->url_scheme = "*";    return 0;  }  s0 = s;  n = strcspn(s, ":/?#");  if (n && s[n] == ':') {    char *scheme;    url->url_scheme = scheme = s; s[n] = '\0'; s = s + n + 1;    if (!(scheme = url_canonize(scheme, scheme, -1, "+")))      return -1;    n = scheme - url->url_scheme;    url->url_type = url_get_type(url->url_scheme, n);    net_path = !url_type_is_opaque(url->url_type);  }  else {    url->url_type = url_unknown;  }  host = s;  if (url->url_type == url_sip || url->url_type == url_sips) {    /* SIP URL may have /; in user part */    n = strcspn(s, "@#");	/* Opaque part */    if (s[n] != '@')      n = 0;    n += strcspn(s + n, "/;?#");  }  else if (url->url_type == url_wv) {    /* WV URL may have / in user part */    n = strcspn(s, "@#?;");    if (s[n] == '@')      n += strcspn(s + n, ";?#");  }  else if (url->url_type == url_invalid) {    n = strcspn(s, "#");  }  else if (net_path && host[0] == '/') {    url->url_root = host[0];	/* Absolute path */    if (host[1] == '/') {	/* We have host-part */      host += 2; s += 2;    }    else       host = NULL;    n = strcspn(s, "/;?#");	/* Find path, query and/or fragment */  }  else {    n = strcspn(s, "/;?#");	/* Find params, query and/or fragment */  }  rest_c = s[n]; s[n] = 0; s = rest_c ? s + n + 1 : NULL;  if (host) {    char *atsign, *port;    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 +

⌨️ 快捷键说明

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