ABNF 規範是一些如下推導規則的集合,以 crlf 換行結束
rule = definition ;comment crlf
- rule:規則名稱,不分大小寫,以字母開始
- definition:規則定義,可能包含一個或多個規則名稱、或數值的組合。
- comment:需要的話,「;」開始為註解。
規則最後解析成一串值,值可用「%」表示法,二進位前置「%b」、十進位前置「%d」、十六進位前置「%x」。多個值串接可用一個前置,後面好幾個數字用「.」連接。一串值也可以用類似 C 語言字串前後加「"」表示,但在 ABNF 的字串是不分大小寫的。如果要分大小寫需要使用「%」表示法。
定義中使用的 Operator,依照 Precedence 高低
- Value Range Alternatives (範圍):%c##-##
- Repetition (重複)
- *Rule:Rule 重複 0 次以上,* 前後可分別加上數字表示最少及最多的重複次數。
- nRule:n 是數字,重複 n 次
- Sequence Group (群組):(Rule1 Rule2)
- Optional Sequence (選擇性的):[RULE]
- Concatenation (串接):Rule1 Rule2
- Alternatives (或者):Rule1 / Rule2
- Incremental Alternatives (新增或者):Rule1 =/ Rule2
基本規則
US ASCII coded 字元集定義在 ANSI X3.4-1986,等同於國際標準 ISO 646。DIGIT | = | %x30-39 | ; 0-9,數字 |
ALPHA | = | %x41-5A / %x61-7A | ; A-Z / a-z,英文字母 |
alphanum | = | ALPHA / DIGIT | ; 英文字母和數字 |
| 一些規則採自 RFC 2396 但更新為 RFC 2234 相容,包括: | |||
reserved | = | ";" / "/" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / "," | ; |
unreserved | = | alphanum / mark | |
mark | = | "-" / "_" / "." / "!" / "~" / "*" / "'" / "(" / ")" | ;mark 意思? |
escaped | = | "%" HEXDIG HEXDIG | |
HEXDIG | = | DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | ;十六進位數字不分大小寫 |
LHEX | = | DIGIT / %x61-66 | ;十六進位數字限制小寫。 |
| ASCII 中的可列印字元,除了 reserved (10 字元)、unreserved (71 字元)、%、和 SP 外,剩下 "#[\]^`{|}<> 12 字元。 | |||
| SWS 是選擇性的 LWS,一般用在 token 和 separators 間。 | |||
LF = %x0A ;linefeed CR = %x0D ;carriage return CRLF = CR LF ;換行 HTAB = %x09 ;horizontal tab SP = %x20 WSP = SP / HTAB ;white space LWS = [*WSP CRLF] 1*WSP ;linear whitespace ;方便拆行顯示,語意和一個 SP 一樣。 ;一個或連續 WSP,前面可有一個換行,換行前可有連續 WSP。 ;接收或轉送可取代為 SP (和 HTTP/1.1 行為一致)。 SWS = [LWS] ;sep whitespace,選擇性的 LWS。信頭的名稱和值。 規則 TEXT-UTF8-TRIM 用在描述性的欄位內容,並不打算給訊息解析器解釋,字元來自 UTF-8 字元集,不能是「quoted-string」,其中開頭和結束 LWS 是無意義的。
TEXT-UTF8-TRIM = 1*TEXT-UTF8char *(*LWS TEXT-UTF8char) TEXT-UTF8char = %x21-7E / UTF8-NONASCII UTF8-NONASCII = %xC0-DF 1UTF8-CONT / %xE0-EF 2UTF8-CONT / %xF0-F7 3UTF8-CONT / %xF8-Fb 4UTF8-CONT / %xFC-FD 5UTF8-CONT UTF8-CONT = %x80-BF
TEXT-UTF8-TRIM 只在 LWS 使用 CRLF 作為折行,LWS 會換成一個 SP 來解釋。
註:HTTP 使用 ISO 8859-1 字元集,以 ASCII 為基礎,在空置的 0xA0-0xFF 加入 96 個字母及符號,藉以供使用附加符號的拉丁字母語言使用。
許多 SIP 欄位包含來自「token」的字元,用 LWS 或「separators 」分隔的字。除非特別提到,「token」是不分大小寫 (case-insensitive)。在參數值如需要用到這些分隔字元,必須在「quoted-string」裡面。「word」特別用在 Call-ID,可使用「token」和大部分分隔字元。
token = 1*(alphanum / "-" / "." / "!" / "%" / "*"
/ "_" / "+" / "`" / "'" / "~" )
DQUOTE = %x22 ; " (Double Quote)
separators = "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / DQUOTE /
"/" / "[" / "]" / "?" / "=" /
"{" / "}" / SP / HTAB
word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
"_" / "+" / "`" / "'" / "~" /
"(" / ")" / "<" / ">" /
":" / "\" / DQUOTE /
"/" / "[" / "]" / "?" /
"{" / "}" )
當分隔字元用在 token 間,這些字元前後常可以允許 whitespace:STAR = SWS "*" SWS ; 星號
SLASH = SWS "/" SWS ; slash
EQUAL = SWS "=" SWS ; 等號
LPAREN = SWS "(" SWS ; 左括號, %x28
RPAREN = SWS ")" SWS ; 右括號, %x29
RAQUOT = ">" SWS ; 左角括號
LAQUOT = SWS "<" ; 右角括號
SEMI = SWS ";" SWS ; 分號
LDQUOT = SWS DQUOTE ; 雙引號開始
RDQUOT = DQUOTE SWS ; 雙引號結束
comment 的內容用 () 括號包起來,只用在少數 header 欄位值。
其它欄位,括號是參數值的一部分。
comment = LPAREN *(ctext / quoted-pair / comment) RPAREN ctext = %x21-27 / %x2A-5B / %x5D-7E / UTF8-NONASCII / LWS ; 所有字元,除了左右括號和反斜線。用雙引號 quoted 的文字串解析為單一字,裡面的雙引號和反斜線要 escaped。
quoted-string = SWS DQUOTE *(qdtext / quoted-pair ) DQUOTE
qdtext = LWS / %x21 / %x23-5B / %x5D-7E
/ UTF8-NONASCII ; 不含雙引號和反斜線。
backslash 字元 ("\") 只用在「quoted-string」和「comment 」作單字元 quoting 機制。為避免與折行和 header separation 衝突,CR 和 LF 不能用此機制 escaped。註:HTTP/1.1 可以 escape CR 和 LF。
quoted-pair = "\" (%x00-09 / %x0B-0C
/ %x0E-7F) ; 不含 CR 和 LF
任何字元用在 message-bodyOCTET = %x00-FF ; 8 bits of data註:規則名稱雖然不分大小寫,特殊基本規則多用大寫。
| alphanum ! ' * - . _ ~ | unreserved | token | word |
|---|---|---|---|
| ( ) | unreserved | sep | word |
| $ & | reserved | - | - |
| + | reserved | token | word |
| , ; = @ | reserved | sep | - |
| / : ? | reserved | sep | word |
| " <> [] {} \ | - | sep | word |
| # ^ | | - | - | - |
| % ` | - | token | word |
| SP, HTAB | - | sep | - |
- unreserved 和 reserved 沒有重疊。在有些欄位,unreserved 會擴充,例如 user-unreserved (擴充只取自 reserved?)。word 包含全部 unreserved。
- token 則不含 unreserved 的 (),但多了 % 和 `、及 reserved 中的 +。
- token 和 separators 沒有重疊。
URI 格式
SIP-message = Request / Response ; SIP 訊息 只有兩種,Request 和 Response。 Request = Request-Line *( message-header ) CRLF [ message-body ] Response = Status-Line *( message-header ) CRLF [ message-body ] message-header = (Accept / Accept-Encoding / Accept-Language / Alert-Info / Allow / Authentication-Info / Authorization / Call-ID / Call-Info / Contact / Content-Disposition / Content-Encoding / Content-Language / Content-Length / Content-Type / CSeq / Date / Error-Info / Expires / From / In-Reply-To / Max-Forwards / MIME-Version / Min-Expires / Organization / Priority / Proxy-Authenticate / Proxy-Authorization / Proxy-Require / Record-Route / Reply-To / Require / Retry-After / Route / Server / Subject / Supported / Timestamp / To / Unsupported / User-Agent / Via / Warning / WWW-Authenticate / extension-header) CRLF INVITEm = %x49.4E.56.49.54.45 ; INVITE in caps ACKm = %x41.43.4B ; ACK in caps OPTIONSm = %x4F.50.54.49.4F.4E.53 ; OPTIONS in caps BYEm = %x42.59.45 ; BYE in caps CANCELm = %x43.41.4E.43.45.4C ; CANCEL in caps REGISTERm = %x52.45.47.49.53.54.45.52 ; REGISTER in caps Method = INVITEm / ACKm / OPTIONSm / BYEm / CANCELm / REGISTERm ; 以上是大寫的 method 名稱,實際上不分大小寫。 / extension-method extension-method = token Response = Status-Line *( message-header ) CRLF [ message-body ] Accept = "Accept" HCOLON [ accept-range *(COMMA accept-range) ] accept-range = media-range *(SEMI accept-param) media-range = ( "*/*" / ( m-type SLASH "*" ) / ( m-type SLASH m-subtype ) ) *( SEMI m-parameter ) accept-param = ("q" EQUAL qvalue) / generic-param qvalue = ( "0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] ) generic-param = token [ EQUAL gen-value ] gen-value = token / host / quoted-string Accept-Encoding = "Accept-Encoding" HCOLON [ encoding *(COMMA encoding) ] encoding = codings *(SEMI accept-param) codings = content-coding / "*" content-coding = token Accept-Language = "Accept-Language" HCOLON [ language *(COMMA language) ] language = language-range *(SEMI accept-param) language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*" ) Alert-Info = "Alert-Info" HCOLON alert-param *(COMMA alert-param) alert-param = LAQUOT absoluteURI RAQUOT *( SEMI generic-param ) Allow = "Allow" HCOLON [Method *(COMMA Method)] Authorization = "Authorization" HCOLON credentials credentials = ("Digest" LWS digest-response) / other-response digest-response = dig-resp *(COMMA dig-resp) dig-resp = username / realm / nonce / digest-uri / dresponse / algorithm / cnonce / opaque / message-qop / nonce-count / auth-param username = "username" EQUAL username-value username-value = quoted-string digest-uri = "uri" EQUAL LDQUOT digest-uri-value RDQUOT digest-uri-value = request-uri ; Equal to request-uri as specified by HTTP/1.1 message-qop = "qop" EQUAL qop-value cnonce = "cnonce" EQUAL cnonce-value cnonce-value = nonce-value nonce-count = "nc" EQUAL nc-value nc-value = 8LHEX dresponse = "response" EQUAL request-digest request-digest = LDQUOT 32LHEX RDQUOT auth-param = auth-param-name EQUAL ( token / quoted-string ) auth-param-name = token other-response = auth-scheme LWS auth-param *(COMMA auth-param) auth-scheme = token Authentication-Info = "Authentication-Info" HCOLON ainfo *(COMMA ainfo) ainfo = nextnonce / message-qop / response-auth / cnonce / nonce-count nextnonce = "nextnonce" EQUAL nonce-value response-auth = "rspauth" EQUAL response-digest response-digest = LDQUOT *LHEX RDQUOT Call-ID = ( "Call-ID" / "i" ) HCOLON callid callid = word [ "@" word ] Call-Info = "Call-Info" HCOLON info *(COMMA info) info = LAQUOT absoluteURI RAQUOT *( SEMI info-param) info-param = ( "purpose" EQUAL ( "icon" / "info" / "card" / token ) ) / generic-param delta-seconds = 1*DIGIT Content-Disposition = "Content-Disposition" HCOLON disp-type *( SEMI disp-param ) disp-type = "render" / "session" / "icon" / "alert" / disp-extension-token disp-param = handling-param / generic-param handling-param = "handling" EQUAL ( "optional" / "required" / other-handling ) other-handling = token disp-extension-token = token Content-Encoding = ( "Content-Encoding" / "e" ) HCOLON content-coding *(COMMA content-coding) Content-Language = "Content-Language" HCOLON language-tag *(COMMA language-tag) language-tag = primary-tag *( "-" subtag ) primary-tag = 1*8ALPHA subtag = 1*8ALPHA Content-Length = ( "Content-Length" / "l" ) HCOLON 1*DIGIT Content-Type = ( "Content-Type" / "c" ) HCOLON media-type media-type = m-type SLASH m-subtype *(SEMI m-parameter) m-type = discrete-type / composite-type discrete-type = "text" / "image" / "audio" / "video" / "application" / extension-token composite-type = "message" / "multipart" / extension-token extension-token = ietf-token / x-token ietf-token = token x-token = "x-" token m-subtype = extension-token / iana-token iana-token = token m-parameter = m-attribute EQUAL m-value m-attribute = token m-value = token / quoted-string CSeq = "CSeq" HCOLON 1*DIGIT LWS Method Date = "Date" HCOLON SIP-date SIP-date = rfc1123-date rfc1123-date = wkday "," SP date1 SP time SP "GMT" date1 = 2DIGIT SP month SP 4DIGIT ; day month year (e.g., 02 Jun 1982) time = 2DIGIT ":" 2DIGIT ":" 2DIGIT ; 00:00:00 - 23:59:59 wkday = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" Error-Info = "Error-Info" HCOLON error-uri *(COMMA error-uri) error-uri = LAQUOT absoluteURI RAQUOT *( SEMI generic-param ) Expires = "Expires" HCOLON delta-seconds In-Reply-To = "In-Reply-To" HCOLON callid *(COMMA callid) Max-Forwards = "Max-Forwards" HCOLON 1*DIGIT MIME-Version = "MIME-Version" HCOLON 1*DIGIT "." 1*DIGIT Min-Expires = "Min-Expires" HCOLON delta-seconds Organization = "Organization" HCOLON [TEXT-UTF8-TRIM] Priority = "Priority" HCOLON priority-value priority-value = "emergency" / "urgent" / "normal" / "non-urgent" / other-priority other-priority = token Proxy-Authenticate = "Proxy-Authenticate" HCOLON challenge challenge = ("Digest" LWS digest-cln *(COMMA digest-cln)) / other-challenge other-challenge = auth-scheme LWS auth-param *(COMMA auth-param) digest-cln = realm / domain / nonce / opaque / stale / algorithm / qop-options / auth-param realm = "realm" EQUAL realm-value realm-value = quoted-string domain = "domain" EQUAL LDQUOT URI *( 1*SP URI ) RDQUOT URI = absoluteURI / abs-path nonce = "nonce" EQUAL nonce-value nonce-value = quoted-string opaque = "opaque" EQUAL quoted-string stale = "stale" EQUAL ( "true" / "false" ) algorithm = "algorithm" EQUAL ( "MD5" / "MD5-sess" / token ) qop-options = "qop" EQUAL LDQUOT qop-value *("," qop-value) RDQUOT qop-value = "auth" / "auth-int" / token Proxy-Authorization = "Proxy-Authorization" HCOLON credentials Proxy-Require = "Proxy-Require" HCOLON option-tag *(COMMA option-tag) option-tag = token Require = "Require" HCOLON option-tag *(COMMA option-tag) Retry-After = "Retry-After" HCOLON delta-seconds [ comment ] *( SEMI retry-param ) retry-param = ("duration" EQUAL delta-seconds) / generic-param Server = "Server" HCOLON server-val *(LWS server-val) server-val = product / comment product = token [SLASH product-version] product-version = token Subject = ( "Subject" / "s" ) HCOLON [TEXT-UTF8-TRIM] Supported = ( "Supported" / "k" ) HCOLON [option-tag *(COMMA option-tag)] Timestamp = "Timestamp" HCOLON 1*(DIGIT) [ "." *(DIGIT) ] [ LWS delay ] delay = *(DIGIT) [ "." *(DIGIT) ] Unsupported = "Unsupported" HCOLON option-tag *(COMMA option-tag) User-Agent = "User-Agent" HCOLON server-val *(LWS server-val) Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm) via-parm = sent-protocol LWS sent-by *( SEMI via-params ) ia-params = via-ttl / via-maddr / via-received / via-branch / via-extension via-ttl = "ttl" EQUAL ttl via-maddr = "maddr" EQUAL host via-received = "received" EQUAL (IPv4address / IPv6address) via-branch = "branch" EQUAL token via-extension = generic-param sent-protocol = protocol-name SLASH protocol-version SLASH transport protocol-name = "SIP" / token protocol-version = token transport = "UDP" / "TCP" / "TLS" / "SCTP" / other-transport sent-by = host [ COLON port ] ttl = 1*3DIGIT ; 0 to 255 Warning = "Warning" HCOLON warning-value *(COMMA warning-value) warning-value = warn-code SP warn-agent SP warn-text warn-code = 3DIGIT warn-agent = hostport / pseudonym ; the name or pseudonym of the server adding ; the Warning header, for use in debugging arn-text = quoted-string pseudonym = token WWW-Authenticate = "WWW-Authenticate" HCOLON challenge extension-header = header-name HCOLON header-value header-name = token header-value = *(TEXT-UTF8char / UTF8-CONT / LWS) message-body = *OCTET ; 任何長度任何字元Request-URI = SIP-URI / SIPS-URI / absoluteURI
absoluteURI = scheme ":" ( hier-part / opaque-part )
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
- Request-URI 較複雜一點,基本結構都會有「:」,之前的部份稱 scheme,之後依照 scheme 解釋。
Header 欄位
message-header = (Accept / Accept-Encoding / Accept-Language / Alert-Info / Allow / Authentication-Info / Authorization / Call-ID / Call-Info / Contact / Content-Disposition / Content-Encoding / Content-Language / Content-Length / Content-Type / CSeq / Date / Error-Info / Expires / From / In-Reply-To / Max-Forwards / MIME-Version / Min-Expires / Organization / Priority / Proxy-Authenticate / Proxy-Authorization / Proxy-Require / Record-Route / Reply-To / Require / Retry-After / Route / Server / Subject / Supported / Timestamp / To / Unsupported / User-Agent / Via / Warning / WWW-Authenticate / extension-header) CRLFextension-header = header-name HCOLON header-value
- 把各種 header 都列出來了,最終都有 CRLF。
Contact、From、Reply-To、和 To 的格式都是 name-addr 或 addr-spec 加上參數,另外 name-addr 也用在 Record-Route 和 Route。 name-addr 含有用 angle bracket 包起來的 addr-spec,所以 addr-spec 可以看成是 name-addr 的簡化,只有在沒有 display-name 且 addr-spec 沒有 「,」、「?」、「;」時使用。「;」為了跟信頭參數的區別。
name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
display-name = *(token LWS)/ quoted-string
addr-spec = SIP-URI / SIPS-URI / absoluteURI
angle bracket 前後可有 LWS
沒有留言:
張貼留言