diff --git a/srt/srt.go b/srt/srt.go index 78c5bbca..73a8ba10 100644 --- a/srt/srt.go +++ b/srt/srt.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "net" + "regexp" "strings" "sync" "time" @@ -365,6 +366,59 @@ type streamInfo struct { func parseStreamId(streamid string) (streamInfo, error) { si := streamInfo{} + if strings.HasPrefix(streamid, "#!:") { + return parseOldStreamId(streamid) + } + + re := regexp.MustCompile(`,(token|mode):(.+)`) + + results := map[string]string{} + + idEnd := -1 + value := streamid + key := "" + + for { + matches := re.FindStringSubmatchIndex(value) + if matches == nil { + break + } + + if idEnd < 0 { + idEnd = matches[2] - 1 + } + + if len(key) != 0 { + results[key] = value[:matches[2]-1] + } + + key = value[matches[2]:matches[3]] + value = value[matches[4]:matches[5]] + + results[key] = value + } + + if idEnd < 0 { + idEnd = len(streamid) + } + + si.resource = streamid[:idEnd] + if token, ok := results["token"]; ok { + si.token = token + } + + if mode, ok := results["mode"]; ok { + si.mode = mode + } else { + si.mode = "request" + } + + return si, nil +} + +func parseOldStreamId(streamid string) (streamInfo, error) { + si := streamInfo{} + if !strings.HasPrefix(streamid, "#!:") { return si, fmt.Errorf("unknown streamid format") } @@ -373,7 +427,7 @@ func parseStreamId(streamid string) (streamInfo, error) { kvs := strings.Split(streamid, ",") - split := func(s, sep string) (string, string, error) { + splitFn := func(s, sep string) (string, string, error) { splitted := strings.SplitN(s, sep, 2) if len(splitted) != 2 { @@ -384,7 +438,7 @@ func parseStreamId(streamid string) (streamInfo, error) { } for _, kv := range kvs { - key, value, err := split(kv, "=") + key, value, err := splitFn(kv, "=") if err != nil { continue } diff --git a/srt/srt_test.go b/srt/srt_test.go index b4b2d843..91ae7ed1 100644 --- a/srt/srt_test.go +++ b/srt/srt_test.go @@ -8,7 +8,25 @@ import ( func TestParseStreamId(t *testing.T) { streamids := map[string]streamInfo{ - "bla": {}, + "bla": {resource: "bla", mode: "request"}, + "bla,mode:publish": {resource: "bla", mode: "publish"}, + "123456789": {resource: "123456789", mode: "request"}, + "bla,token:foobar": {resource: "bla", token: "foobar", mode: "request"}, + "bla,token:foo,bar": {resource: "bla", token: "foo,bar", mode: "request"}, + "123456789,mode:publish,token:foobar": {resource: "123456789", token: "foobar", mode: "publish"}, + "mode:publish": {resource: "mode:publish", mode: "request"}, + } + + for streamid, wantsi := range streamids { + si, err := parseStreamId(streamid) + + require.NoError(t, err) + require.Equal(t, wantsi, si) + } +} + +func TestParseOldStreamId(t *testing.T) { + streamids := map[string]streamInfo{ "#!:": {}, "#!:key=value": {}, "#!:m=publish": {mode: "publish"}, @@ -19,7 +37,7 @@ func TestParseStreamId(t *testing.T) { } for streamid, wantsi := range streamids { - si, _ := parseStreamId(streamid) + si, _ := parseOldStreamId(streamid) require.Equal(t, wantsi, si) }