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

📄 url.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
    return rv;  if (a->url_port != b->url_port) {    char const *a_port;    char const *b_port;    if (url_type != url_sip && url_type != url_sips)      a_port = b_port = url_port_default(url_type);    else if (host_is_ip_address(a->url_host))      a_port = b_port = url_port_default(url_type);    else      a_port = b_port = "";        if (a->url_port) a_port = a->url_port;    if (b->url_port) b_port = b->url_port;    if ((rv = strcmp(a_port, b_port)))      return rv;  }  if (a->url_user != b->url_user) {    if (a->url_user == NULL) return -1;    if (b->url_user == NULL) return +1;    switch (url_type) {    case url_tel: case url_modem: case url_fax:      rv = url_tel_cmp_numbers(a->url_user, b->url_user);      break;    default:      rv = strcmp(a->url_user, b->url_user);      break;    }    if (rv)      return rv;  }#if 0  if (a->url_path != b->url_path) {    if (a->url_path == NULL) return -1;    if (b->url_path == NULL) return +1;    if ((rv = strcmp(a->url_path, b->url_path)))      return rv;  }#endif  return 0;}staticint url_tel_cmp_numbers(char const *A, char const *B){  char a, b;  int rv;  while (*A && *B) {    #define UNHEX(a) (a - (a >= 'a' ? 'a' - 10 : (a >= 'A' ? 'A' - 10 : '0')))    /* Skip visual-separators */    do {      a = *A++;      if (a == '%' && IS_HEX(A[0]) && IS_HEX(A[1])) 	a = (UNHEX(A[0]) << 4) | UNHEX(A[1]), A +=2;    } while (a == ' ' || a == '-' || a == '.' || a == '(' || a == ')');    if (isupper(a))      a = tolower(a);    do {      b = *B++;      if (b == '%' && IS_HEX(B[0]) && IS_HEX(B[1])) 	b = (UNHEX(B[0]) << 4) | UNHEX(B[1]), B +=2;    } while (b == ' ' || b == '-' || b == '.' || b == '(' || b == ')');    if (isupper(b))      b = tolower(b);    if ((rv = a - b))      return rv;  }  return (int)*A - (int)*B;}/**Conservative comparison of urls. * * Compare all parts of URLs. * * @note * The @a a and @a b must be pointers to URL structures. * */int url_cmp_all(url_t const *a, url_t const *b){  int rv, url_type;  if (!a || !b)    return (a != NULL) - (b != NULL);  if ((rv = a->url_type - b->url_type))    return rv;  url_type = a->url_type;	/* Or b->url_type, they are equal! */  if (url_type <= url_unknown &&       ((rv = !a->url_scheme - !b->url_scheme) ||       (a->url_scheme && b->url_scheme &&	(rv = strcasecmp(a->url_scheme, b->url_scheme)))))    return rv;  if ((rv = a->url_root - b->url_root))    return rv;  if (a->url_host != b->url_host &&       ((rv = !a->url_host - !b->url_host) ||       (rv = strcasecmp(a->url_host, b->url_host))))    return rv;  if (a->url_port != b->url_port) {    char const *a_port;    char const *b_port;    if (url_type != url_sip && url_type != url_sips)      a_port = b_port = url_port_default(url_type);    else if (host_is_ip_address(a->url_host))      a_port = b_port = url_port_default(url_type);    else      a_port = b_port = "";        if (a->url_port) a_port = a->url_port;    if (b->url_port) b_port = b->url_port;    if ((rv = strcmp(a_port, b_port)))      return rv;  }  if (a->url_user != b->url_user) {    if (a->url_user == NULL) return -1;    if (b->url_user == NULL) return +1;    switch (url_type) {    case url_tel: case url_modem: case url_fax:      rv = url_tel_cmp_numbers(a->url_user, b->url_user);      break;    default:      rv = strcmp(a->url_user, b->url_user);      break;    }    if (rv)      return rv;  }  if (a->url_path != b->url_path) {    if (a->url_path == NULL) return -1;    if (b->url_path == NULL) return +1;    if ((rv = strcmp(a->url_path, b->url_path)))      return rv;  }  if (a->url_params != b->url_params) {    if (a->url_params == NULL) return -1;    if (b->url_params == NULL) return +1;    if ((rv = strcmp(a->url_params, b->url_params)))      return rv;  }  if (a->url_headers != b->url_headers) {    if (a->url_headers == NULL) return -1;    if (b->url_headers == NULL) return +1;    if ((rv = strcmp(a->url_headers, b->url_headers)))      return rv;  }  if (a->url_headers != b->url_headers) {    if (a->url_headers == NULL) return -1;    if (b->url_headers == NULL) return +1;    if ((rv = strcmp(a->url_headers, b->url_headers)))      return rv;  }  if (a->url_fragment != b->url_fragment) {    if (a->url_fragment == NULL) return -1;    if (b->url_fragment == NULL) return +1;    if ((rv = strcmp(a->url_fragment, b->url_fragment)))      return rv;  }  return 0;}/** Return default port number corresponding to the url type */char const *url_port_default(enum url_type_e url_type){  switch (url_type) {  case url_sip:			/* "sip:" */    return "5060";  case url_sips:		/* "sips:" */    return "5061";  case url_http:		/* "http:" */    return "80";  case url_https:		/* "https:" */    return "443";  case url_ftp:			/* "ftp:" */  case url_file:		/* "file:" */    return "21";  case url_rtsp:		/* "rtsp:" */  case url_rtspu:		/* "rtspu:" */    return "554";  case url_mailto:		/* "mailto:" */    return "25";  case url_any:			/* "*" */    return "*";  case url_msrp:    return "9999";		/* XXXX */  case url_tel:	  case url_fax:	  case url_modem:  case url_im:	  case url_pres:  case url_cid:  case url_wv:  default:			/* Unknown scheme */    return "";  }}/** Return default transport name corresponding to the url type */char const *url_tport_default(enum url_type_e url_type){  switch (url_type) {  case url_sip:    return "*";  case url_sips:    return "tls";  case url_http:    return "tcp";  case url_https:    return "tls";  case url_ftp:  case url_file:    return "tcp";  case url_rtsp:    return "tcp";  case url_rtspu:    return "udp";  case url_mailto:    return "tcp";  case url_msrp:    return "tcp";  case url_any:			/* "*" */  case url_tel:  case url_fax:  case url_modem:  case url_im:  case url_pres:  case url_cid:  case url_wv:  default:			/* Unknown scheme */    return "*";  }}/** Return the URL port string */char const *url_port(url_t const *u){  if (!u)    return "";  else if (u->url_port && u->url_port[0])    return u->url_port;  if (u->url_type == url_sips || u->url_type == url_sip)    if (!host_is_ip_address(u->url_host))      return "";  return url_port_default(u->url_type);}/** Sanitize URL. * * The function url_sanitize() adds a scheme to an incomplete URL.  It * modifies its parameter structure @a url.  Currently, the function follows * simple heuristics: * * - URL with host name starting with @c ftp. is an FTP URL * - URL with host name starting with @c www. is an HTTP URL * - URL with host and path, e.g., @c host/foo;bar, is an HTTP URL * - URL with host name, no path is a SIP URL. * * @param url pointer to URL struct to be sanitized (IN/OUT) * * @return * The function url_sanitize() returns 0 if it considers URL to be * sane, and -1 otherwise. */int url_sanitize(url_t *url){  if (!url)    return -1;  else if (url->url_scheme != NULL)    /* xyzzy */;  else if (url->url_host == NULL)    return -1;  else if (strncasecmp(url->url_host, "ftp.", strlen("ftp.")) == 0)    url->url_type = url_ftp, url->url_scheme = "ftp", url->url_root = '/';  else if (strncasecmp(url->url_host, "www.", strlen("www.")) == 0	   || url->url_path)    url->url_type = url_http, url->url_scheme = "http", url->url_root = '/';  else    url->url_type = url_sip, url->url_scheme = "sip";  return 0;}#include <sofia-sip/su_md5.h>staticvoid canon_update(su_md5_t *md5, char const *s, int n, char const *allow){  char const *s0 = s, *b = s;  for (;*s && s - s0 < n; s++) {    char c;    if (*s == '%' && IS_HEX(s[1]) && IS_HEX(s[2]) && s - s0 + 2 < n) {#define   UNHEX(a) (a - (a >= 'a' ? 'a' - 10 : (a >= 'A' ? 'A' - 10 : '0')))      c = (UNHEX(s[1]) << 4) | UNHEX(s[2]);#undef    UNHEX      if (c != '%' && c > ' ' && c < '\177' && 	  (!strchr(EXCLUDED, c) || strchr(allow, c))) {	if (b != s)	  su_md5_iupdate(md5, b, s - b);	su_md5_iupdate(md5, &c, 1);	b = s + 3;      }      s += 2;    }  }  if (b != s)    su_md5_iupdate(md5, b, s - b);}/** Update MD5 sum with url-string contents */staticvoid url_string_update(su_md5_t *md5, char const *s){  int n;  int hostpart = 1;  enum url_type_e type = url_any;  char const *at, *colon;  char schema[48];  if (s == NULL || strlen(s) == 0 || strcmp(s, "*") == 0) {    su_md5_update(md5, "*\0\0*", 4);    return;  }  n = strcspn(s, ":/?#");  if (n >= sizeof schema) {    su_md5_update(md5, ":", 1);  } else if (n && s[n] == ':' ) {    at = url_canonize(schema, s, n, "+");    type = url_get_type(schema, at - schema);    su_md5_iupdate(md5, schema, at - schema);    hostpart = !url_type_is_opaque(type);    s += n + 1;  }  else {    su_md5_update(md5, "", 1);  }    if (type == url_sip || type == url_sips) {    n = strcspn(s, "@#");	/* Opaque part */    if (s[n] != '@')      n = 0;    n += strcspn(s + n, "/;?#");  }  else if (!hostpart || s[0] != '/') {    n = strcspn(s, "/;?#");	/* Opaque part */  }  else if (s[1] == '/') {    s += 2;    n = strcspn(s, "/;?#");	/* Until path, query or fragment */  }  else {    /* foo:/bar */    su_md5_update(md5, "\0\0", 2); /* user, host */    su_md5_striupdate(md5, url_port_default(type));    return;  }    if (!hostpart) {    char const *colon = memchr(s, ':', n);        if (colon) n = colon - s;    canon_update(md5, s, n, ""); /* user */    su_md5_update(md5, "\0", 1); /* host, no port */    su_md5_striupdate(md5, url_port_default(type));    return;  }  at = memchr(s, '@', n);  if (at) {    char const *allow =       (type == url_sip || type == url_sips)       ? SIP_USER_UNRESERVED      : USER_UNRESERVED;    colon = memchr(s, ':', at - s);    /* Updated only user part */    if (colon)      canon_update(md5, s, colon - s, allow);    else      canon_update(md5, s, at - s, allow);    n = n - (at + 1 - s);    s = at + 1;  }  else    su_md5_iupdate(md5, "", 1);	/* user */  colon = memchr(s, ':', n);	/* XXX - IPv6! */  if (colon) {    canon_update(md5, s, colon - s, ""); /* host */    canon_update(md5, colon + 1, (s + n) - (colon + 1), "");  }  else {    canon_update(md5, s, n, ""); /* host */    su_md5_strupdate(md5, url_port_default(type));	/* port */  }  /* ignore parameters/path/headers.... */}/** Update md5 digest with contents of URL. * */void url_update(su_md5_t *md5, url_t const *url){  if (url_string_p((url_string_t *)url)) {    url_string_update(md5, (char const *)url);  }  else {    SU_MD5_STRI0UPDATE(md5, url->url_scheme);    SU_MD5_STRI0UPDATE(md5, url->url_user);    SU_MD5_STRI0UPDATE(md5, url->url_host);    su_md5_striupdate(md5, URL_PORT(url));    /* XXX - parameters/path.... */    /* SU_MD5_STRI0UPDATE(md5, url->url_path); */  }}/** Calculate a digest from URL contents. */void url_digest(void *hash, int hsize, url_t const *url, char const *key){  su_md5_t md5[1];  uint8_t digest[SU_MD5_DIGEST_SIZE];  su_md5_init(md5);  if (key) su_md5_strupdate(md5, key);  url_update(md5, url);  su_md5_digest(md5, digest);  if (hsize > SU_MD5_DIGEST_SIZE) {    memset((char *)hash + SU_MD5_DIGEST_SIZE, 0, hsize - SU_MD5_DIGEST_SIZE);    hsize = SU_MD5_DIGEST_SIZE;  }  memcpy(hash, digest, hsize);}

⌨️ 快捷键说明

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