📄 sip_parse_uri.c
字号:
} } } if (scan < uend) return (0); return (1);}static intsip_uri_hexVal(char *scan, char *uend){ int ret = -1; if (SIP_URI_ISURLESCAPE(scan, uend)) { ret = (SIP_URI_ISDIGIT(scan[1]) ? (scan[1] - '0') : (tolower(scan[1]) - 'a' + 10)) * 16 + (SIP_URI_ISDIGIT(scan[2]) ? (scan[2] - '0') : (tolower(scan[2]) - 'a' + 10)); } return (ret);}/* * service-provider = ";" provider-tag "=" provider-hostname * provider-tag = "tsp" * provider-hostname = domain */static intsip_uri_parse_tel_servicepro(char *scan, char *uend){ char *mark = (char *)0; if (scan == uend) return (0); /* parse domain=" " */ if (sip_uri_hexVal(scan, uend) == 0x20 && scan + 3 == uend) return (1); while (scan < uend) { mark = scan; while (scan < uend && (*scan == '-'|| SIP_URI_ISALNUM(*scan))) ++scan; if ((scan < uend && *scan != '.') || !SIP_URI_ISALPHA(*mark) || !SIP_URI_ISALNUM(*(scan - 1))) { return (0); } if (scan < uend) ++scan; } if (scan < uend) return (0); return (1);}/* * future-extension = ";" 1*(token-char) ["=" ((1*(token-char) * ["?" 1*(token-char)]) / quoted-string )] * token-char = (%x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 * / %x41-5A / %x5E-7A / %x7C / %x7E) */static intsip_uri_parse_tel_futureext(char *scan, char *uend){ char *mark; int uri_hexValue = 0; if (scan == uend) return (0); /* parse 1*(token-char) */ mark = scan; while (scan < uend && sip_uri_isTokenchar(&scan, uend)) ; if (mark == scan || (scan < uend && (*scan != '=' || scan + 1 == uend))) { return (0); } if (scan == uend) return (1); ++scan; /* parse 1*token-char ["?" 1*token-char] */ if (sip_uri_isTokenchar(&scan, uend)) { while (sip_uri_isTokenchar(&scan, uend)) ; if (scan < uend) { if (*scan != '?') return (0); ++scan; mark = scan; while (sip_uri_isTokenchar(&scan, uend)) ; if (mark == scan) return (0); } } else { /* parse quoted-string */ uri_hexValue = sip_uri_hexVal(scan, uend); if (uri_hexValue != 0x22) return (0); scan += 3; while (scan < uend && sip_uri_hexVal(scan, uend) != 0x22) { /* parse "\" CHAR */ if (sip_uri_hexVal(scan, uend) == 0x5c) { scan += 3; if (scan < uend) { if (SIP_URI_ISUNRESERVED(*scan) || SIP_URI_ISUSER(*scan)) { ++scan; } else if (sip_uri_hexVal(scan, uend) >= 0x00 && sip_uri_hexVal(scan, uend) <= 0x7f) { scan += 3; } else { return (0); } } else { return (0); } } else { if (SIP_URI_ISUNRESERVED(*scan) || SIP_URI_ISUSER(*scan)) { ++scan; } else { uri_hexValue = sip_uri_hexVal(scan, uend); if ((uri_hexValue >= 0x20 && uri_hexValue <= 0x21) || (uri_hexValue >= 0x23 && uri_hexValue <= 0x7e) || (uri_hexValue >= 0x80 && uri_hexValue <= 0xff)) { scan += 3; } else { return (0); } } } } if (scan == uend || (scan < uend && sip_uri_hexVal(scan, uend) != 0x22)) { return (0); } scan += 3; } if (scan < uend) return (0); return (1);}/* * Any characters allowed in RFC2806 tel URL that are not allowed in * the user part of the SIP URI MUST be escaped. * token-char = - _ . ! ~ * ' $ & + DIGIT ALPHA # % ^ ` | */static intsip_uri_isTokenchar(char **pscan, char *uend){ char *scan = *pscan; int uri_hexValue = 0; if (scan == uend) return (0); /* for ALPAH DIGIT - _ . ! ~ * ' $ & + */ if ((SIP_URI_ISUNRESERVED(*scan) && *scan != '(' && *scan != ')') || *scan == '$' || *scan == '&' || *scan == '+') { ++scan; *pscan = scan; return (1); } uri_hexValue = sip_uri_hexVal(scan, uend); if (uri_hexValue == 0x21 || uri_hexValue == 0x7c || uri_hexValue == 0x7e || (uri_hexValue >= 0x23 && uri_hexValue <= 0x27) || (uri_hexValue >= 0x2a && uri_hexValue <= 0x2b) || (uri_hexValue >= 0x2d && uri_hexValue <= 0x2e) || (uri_hexValue >= 0x30 && uri_hexValue <= 0x39) || (uri_hexValue >= 0x41 && uri_hexValue <= 0x5a) || (uri_hexValue >= 0x5e && uri_hexValue <= 0x7a)) { scan += 3; *pscan = scan; return (1); } return (0);}/* * '#' is not allowed in the telephone-subscriber part of SIP URI * it must be escaped */static intsip_uri_isEscapedPound(char **pscan, char *uend){ char *scan = *pscan; if (scan == uend) return (0); if (*scan == '%' && scan + 2 < uend && scan[1] == '2' && scan[2] == '3') { scan += 2; *pscan = scan; return (1); } return (0);}/* * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */static intsip_uri_parse_scheme(_sip_uri_t *outurl, char *scan, char *uend){ if (scan == uend) { outurl->sip_uri_errflags |= SIP_URIERR_SCHEME; return (0); } outurl->sip_uri_scheme.sip_str_ptr = scan; outurl->sip_uri_scheme.sip_str_len = uend - scan; if (scan < uend && SIP_URI_ISALPHA(*scan)) { ++scan; while (scan < uend && SIP_URI_ISSCHEME(*scan)) ++scan; } if (scan < uend) outurl->sip_uri_errflags |= SIP_URIERR_SCHEME; return (1);}/* * The format of params is supposed to be;XXX;XXX;XXX * uri-parameters = *(";" uri-parameter) * uri-parameter = transport-param / user-param / method-param * / ttl-param / maddr-param / lr-param / other-param * transport-param = "transport=" * ("udp" / "tcp" / "sctp" / "tls" / other-transport) * other-transport = token * user-param = "user=" ("phone" / "ip" / other-user) * other-user = token * method-param = "method=" Method * ttl-param = "ttl=" ttl * maddr-param = "maddr=" host * lr-param = "lr" * other-param = pname [ "=" pvalue ] * pname = 1*paramchar * pvalue = 1*paramchar * paramchar = param-unreserved / unreserved / escaped * param-unreserved = "[" / "]" / "/" / ":" / "&" / "+" / "$" */static voidsip_uri_parse_params(_sip_uri_t *outurl, char *scan, char *uend){ char *mark = (char *)0; char *equal = (char *)0; int i = 0; int ttl = 0; int paramleftlen = 0; int gothost = 0; sip_param_t *param = NULL; sip_param_t *new_param = NULL; if (scan == uend || *scan != ';' || scan + 1 == uend) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } while (scan < uend) { mark = ++scan; while (scan < uend && *scan != ';') ++scan; if (scan == mark) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } new_param = calloc(1, sizeof (sip_param_t)); if (new_param == NULL) { outurl->sip_uri_errflags |= SIP_URIERR_MEMORY; return; } if (param == NULL) outurl->sip_uri_params = new_param; else param->param_next = new_param; param = new_param; param->param_name.sip_str_ptr = mark; equal = memchr(mark, '=', scan - mark); if (equal == (char *)0) { param->param_name.sip_str_len = scan - mark; param->param_value.sip_str_ptr = NULL; param->param_value.sip_str_len = 0; while (mark < scan && (SIP_URI_ISPARAM(*mark) || SIP_URI_ISURLESCAPE(mark, scan))) { ++mark; } } else { param->param_name.sip_str_len = equal - mark; param->param_value.sip_str_ptr = equal + 1; param->param_value.sip_str_len = scan - equal - 1; if (mark == equal || equal + 1 == scan) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } paramleftlen = equal - mark + 1; if ((paramleftlen == 10 && !sip_uri_url_casecmp(mark, "transport=", 10)) || (paramleftlen == 5 && !sip_uri_url_casecmp(mark, "user=", 5)) || (paramleftlen == 7 && !sip_uri_url_casecmp(mark, "method=", 7))) { if (scan - equal == 1) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } mark = equal + 1; while (mark < scan && SIP_URI_ISTOKEN(*mark)) ++mark; } else if (paramleftlen == 4 && !sip_uri_url_casecmp(mark, "ttl=", 4)) { if (scan - equal == 1) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } mark = equal; for (i = 0; i < 3; ++i) { ++mark; if (mark < scan && SIP_URI_ISDIGIT(*mark)) { ttl = ttl * 10 + (*mark - '0'); } if (ttl > 255) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } } } else if (paramleftlen == 6 && !sip_uri_url_casecmp(mark, "maddr=", 6)) { gothost = 0; mark = equal + 1; if (mark < scan && SIP_URI_ISDIGIT(*mark)) { gothost = sip_uri_parse_ipv4(mark, scan); } /* * not valid syntax for a host or user name, * try IPv6 literal */ if (!gothost && mark < scan && *mark == '[') { gothost = sip_uri_parse_ipv6(mark, scan); } /* * look for a valid host name: * *(domainlabel ".") toplabel ["."] */ if (!gothost && mark < scan) { if (!(gothost = sip_uri_parse_hostname(mark, scan))) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; } } if (gothost) mark = scan; } else if (paramleftlen == 3 && !sip_uri_url_casecmp(mark, "lr=", 3)) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } else { while (mark < scan && (SIP_URI_ISPARAM(*mark) || SIP_URI_ISURLESCAPE(mark, scan) || mark == equal)) { ++mark; } } } if (mark < scan) { outurl->sip_uri_errflags |= SIP_URIERR_PARAM; return; } }}/* * The format of headers is supposed to be ?XXX&XXX&XXX * headers = "?" header *("&" header * header = hname "=" hvalue * hname = 1*(hnv-unreserved / unreserved / escaped * hvalue = *(hnv-unreserved / unreserved / escaped * hnv-unreserved = "[" / "]" / "/" / "?" / ":" / "+" / "$" */static voidsip_uri_parse_headers(_sip_uri_t *outurl, char *scan, char *uend){ char *mark = NULL; char *equal = NULL; if (scan == uend || *scan != '?' || scan + 1 == uend) { outurl->sip_uri_errflags |= SIP_URIERR_HEADER; return; } outurl->sip_uri_headers.sip_str_ptr = scan + 1; outurl->sip_uri_headers.sip_str_len = uend - (scan + 1); while (scan < uend) { mark = ++scan; while (scan < uend && *scan != '&') ++scan; if (scan == mark) { outurl->sip_uri_errflags |= SIP_URIERR_HEADER; return; } equal = memchr(mark, '=', scan - mark); if (equal == mark || equal == (char *)0) { outurl->sip_uri_errflags |= SIP_URIERR_HEADER; return; } while (mark < scan && (SIP_URI_ISHEADER(*mark) || SIP_URI_ISURLESCAPE(mark, scan) || mark == equal)) { ++mark; } if (mark < scan) { outurl->sip_uri_errflags |= SIP_URIERR_HEADER; return; } }}/* * opaque-part = uric-no-slash *uric * uric = reserved / unreserved / escaped * uric-no-slash = unreserved / escaped / ";" / "?" / ":" / "@" * / "&" / "=" / "+" / "$" / "," */static voidsip_uri_parse_abs_opaque(_sip_uri_t *outurl, char *scan, char *uend){ if (scan == uend) { outurl->sip_uri_errflags |= SIP_URIERR_OPAQUE; return; } outurl->sip_uri_opaque.sip_str_ptr = scan; outurl->sip_uri_opaque.sip_str_len = uend - scan; if (SIP_URI_ISUNRESERVED(*scan) || SIP_URI_ISURLESCAPE(scan, uend) || SIP_URI_ISOTHER(*scan) || *scan == ';' || *scan == '?' || *scan == ':' || *scan == '@' || *scan == '&') { ++scan; } else { outurl->sip_uri_errflags |= SIP_URIERR_OPAQUE; return; } while (scan < uend && (SIP_URI_ISRESERVED(*scan) || SIP_URI_ISUNRESERVED(*scan) || SIP_URI_ISURLESCAPE(scan, uend))) { ++scan; } if (scan < uend) outurl->sip_uri_errflags |= SIP_URIERR_OPAQUE;}/* * format of query is supposed to be ?XXX * query = *uric * uric = reserved / unreserved / escaped */static voidsip_uri_parse_abs_query(_sip_uri_t *outurl, char *scan, char *uend){ if (uend == scan || *scan != '?' || scan + 1 == uend) return; ++scan; outurl->sip_uri_query.sip_str_ptr = scan; outurl->sip_uri_query.sip_str_len = uend - scan; while (scan < uend && (SIP_URI_ISRESERVED(*scan) || SIP_URI_ISUNRESERVED(*scan) || SIP_URI_ISURLESCAPE(scan, uend))) { ++scan; } if (scan < uend) outurl->sip_uri_errflags |= SIP_URIERR_QUERY;}/* * the format of path is supposed to be /XXX;XXX/XXX; * abs-path = "/" path-segments * path-segments = segment *( "/" segment ) * segment = *pchar *( ";" param ) * param = *pchar * pchar = unreserved / escaped /
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -