Search code examples
rtsprfcbnf

Understanding BNF notation for an RTSP request


According to RTSP documentation page 21 https://www.rfc-editor.org/rfc/rfc2326, an RTSP response is:

   Request      =       Request-Line          ; Section 6.1
                *(      general-header        ; Section 5
                |       request-header        ; Section 6.2
                |       entity-header )       ; Section 8.1
                        CRLF
                        [ message-body ]      ; Section 4.3

The *, as far as I know and according to https://www.w3.org/Notation.html, means "1 or more of the thing after it". So I'm interpreting the thing above as

*(general-header|request-header|entity-header)CRLF

This would explain this example below, where the headers are of the type general-header \r\n, like this: Cseq: 2\r\nContent-Base: rtsp://example.com/media.mp4\r\nContent-Type: application/sdp\r\nContent-Length: 360\r\n:

S->C: RTSP/1.0 200 OK
      CSeq: 2
      Content-Base: rtsp://example.com/media.mp4
      Content-Type: application/sdp
      Content-Length: 460

      m=video 0 RTP/AVP 96
      a=control:streamid=0
      a=range:npt=0-7.741000
      a=length:npt=7.741000
      a=rtpmap:96 MP4V-ES/5544
      a=mimetype:string;"video/MP4V-ES"
      a=AvgBitRate:integer;304018
      a=StreamName:string;"hinted video track"
      m=audio 0 RTP/AVP 97
      a=control:streamid=1
      a=range:npt=0-7.712000
      a=length:npt=7.712000
      a=rtpmap:97 mpeg4-generic/32000/2
      a=mimetype:string;"audio/mpeg4-generic"
      a=AvgBitRate:integer;65790
      a=StreamName:string;"hinted audio track"

The headers are in the form general-header \r\n (where \r\n is CRLF). But what about that extra white line (a \r\n) before the message body? This is not explained by the repetition.

I think I'm interpreting something wrong.


Solution

  • This interpretation is correct:

    Request = Request-Line *(general-header|request-header|entity-header) CRLF [message-body]
    

    Although the example given is a response, which has this similar grammar:

    Response = Status-Line *(general-header|response-header|entity-header) CRLF [message-body]
    

    In either case, the set of headers is separated from the message-body by a CRLF (\r\n), which is NOT repeated. In the example:

    RTSP/1.0 200 OK                             # This is the Status-Line
    CSeq: 2                                     # general-header (see Section 12)
    Content-Base: rtsp://example.com/media.mp4  # entity-header (see Section 8.1, 12.11)
    Content-Type: application/sdp               # entity-header (see Section 8.1, 12.16)
    Content-Length: 460                         # entity-header (see Section 8.1, 12.14)
                                                # the CRLF marking the end of headers
    m=video 0 RTP/AVP 96                        # the message body follows
    ...
    

    "The thing after the *" is the parenthesis block, without the CRLF. Each header ends with a CRLF because the grammar for message headers includes that. See Section 4.2, which refers to Section 4.2 of RFC 2068:

    message-header = field-name ":" [ field-value ] CRLF