SIP 最基本的 URI scheme 是 sip:,TLS 加密用 sips:,像 email 格式,用在 SIP 請求行及批頭值等,整個會使拆著 4 個部份:
其中只有主機的 host 是必要的。URI 可作為 addr-spec,但有 URI 參數時,需要整個用 <> 包起來成為 name-addr,才能區別「批頭參數」。
ABNF 格式:
SIP-URI = "sip:" [ userinfo ] hostport uri-parameters [ headers ]
SIPS-URI = "sips:" [ userinfo ] hostport uri-parameters [ headers ]
有「@」表示在主機有帳號,「@」之前就是帳號部份,分大小寫,可用 user 或 telephone-subscriber。帳號內如果有「:」表示含有密碼 password,毋過有安全問題不建議用。
userinfo = ( user / telephone-subscriber ) [ ":" password ] "@"
user 大多字元都可以使用,即使「,」「;」「?」也可以。「@」區別帳號不能使用,「:」表示有密碼也不行,可用「% 跳脫」。
user = 1*( unreserved / escaped / user-unreserved )
user-unreserved = "&" / "=" / "+" / "$" / "," / ";" / "?" / "/"
telephone-subscriber 是電話號碼,由 tel URI 來,可視為 user 的特例,可用 URI 參數 user=phone 明確表示用電話號碼。電話號碼本身可能包括「;」開頭的參數,這是出現在「@」之前,和主機之後的 URI 參數是不同的。電話號碼參數在 tel URI 是不分大小寫的,且不同順序是相同的。轉遮 SIP/SIPS URI 愛換遮小寫,isub 排頭前,賰的照字母順序排,這樣比較才會一致。例如:
tel:+358-555-1234567;tsp=a.b;phone-context=5
變成
sip:+358-555-1234567;phone-context=5;tsp=a.b@foo.com;user=phone
密碼也大多字元都可以使用,只比 user 少了「;」「?」和「/」。(為什麼需要少這 3 個?)
password = *( unreserved / escaped /
"&" / "=" / "+" / "$" / "," )
主機可以是網域名稱或 IP 網址,如果有「:」表示含有 port。
hostport = host [ ":" port ]
host = hostname / IPv4address / IPv6reference
hostname = *( domainlabel "." ) toplabel [ "." ]
domainlabel = alphanum / alphanum *( alphanum / "-" ) alphanum
toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
IPv6reference = "[" IPv6address "]"
IPv6address = hexpart [ ":" IPv4address ]
hexpart = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ]
hexseq = hex4 *( ":" hex4)
hex4 = 1*4HEXDIG
port = 1*DIGIT
URI 參數可有多個,每個以「;」開始,格式是 名稱=值,名稱不能重複,有 transport、maddr、ttl、user、method、lr 等。和批頭參數是不同的東西。整個 URI 可作為 addr-spec,可用到「,」、「?」、和「;」,但為了跟信頭參數的「;」區別,整個 URI 需要用 <> 包起來成為 name-addr 。
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 = "[" / "]" / "/" / ":" / "&" / "+" / "$"
headers = "?" header *( "&" header )
header = hname "=" hvalue
hname = 1*( hnv-unreserved / unreserved / escaped )
hvalue = *( hnv-unreserved / unreserved / escaped )
hnv-unreserved = "[" / "]" / "/" / "?" / ":" / "+" / "$"
其它 scheme URI,可以是網路路徑、絕對路徑等。
absoluteURI = scheme ":" ( hier-part / opaque-part )
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
hier-part = ( net-path / abs-path ) [ "?" query ]
net-path = "//" authority [ abs-path ]
authority = srvr / reg-name
srvr = [ [ userinfo "@" ] hostport ]
reg-name = 1*( unreserved / escaped / "$" / ","
/ ";" / ":" / "@" / "&" / "=" / "+" )
query = *uric
abs-path = "/" path-segments
opaque-part = uric-no-slash *uric
uric = reserved / unreserved / escaped
uric-no-slash = unreserved / escaped / ";" / "?" / ":" / "@"
/ "&" / "=" / "+" / "$" / ","
path-segments = segment *( "/" segment )
segment = *pchar *( ";" *pchar )
pchar = unreserved / escaped /
":" / "@" / "&" / "=" / "+" / "$" / ","
參考
- RFC3261 §19.1
- SIP/SIPS URL follow RFC3986 guideline