diff --git a/webserver/webserver.go b/webserver/webserver.go index c435cf4..4105135 100644 --- a/webserver/webserver.go +++ b/webserver/webserver.go @@ -300,24 +300,38 @@ func parseGroupName(prefix string, p string) string { return name[1:] } +func splitPath(pth string) (string, string, string) { + index := strings.Index(pth, "/.") + if index < 0 { + return pth, "", "" + } + + index2 := strings.Index(pth[index+1:], "/") + if index2 < 0 { + return pth[:index], pth[index+1:], "" + } + return pth[:index], pth[index+1 : index+1+index2], pth[index+1+index2:] +} + func groupHandler(w http.ResponseWriter, r *http.Request) { if redirect(w, r) { return } - if strings.HasSuffix(r.URL.Path, "/.status.json") { + _, kind, rest := splitPath(r.URL.Path) + if kind == ".status.json" && rest == "" { groupStatusHandler(w, r) return - } - - dir, id := parseWhip(r.URL.Path) - if dir != "" { - if id == "" { + } else if kind == ".whip" { + if rest == "" { whipEndpointHandler(w, r) } else { whipResourceHandler(w, r) } return + } else if kind != "" { + notFound(w) + return } name := parseGroupName("/group/", r.URL.Path) @@ -369,7 +383,11 @@ func groupBase(r *http.Request) (string, error) { } func groupStatusHandler(w http.ResponseWriter, r *http.Request) { - pth := path.Dir(r.URL.Path) + pth, kind, rest := splitPath(r.URL.Path) + if kind != ".status.json" || rest != "" { + http.Error(w, "Internal server error", + http.StatusInternalServerError) + } name := parseGroupName("/group/", pth) if name == "" { notFound(w) diff --git a/webserver/webserver_test.go b/webserver/webserver_test.go index e918620..4b223b9 100644 --- a/webserver/webserver_test.go +++ b/webserver/webserver_test.go @@ -22,42 +22,34 @@ func TestParseGroupName(t *testing.T) { } for _, pg := range a { - t.Run(pg.p, func(t *testing.T) { - g := parseGroupName("/group/", pg.p) - if g != pg.g { - t.Errorf("Path %v, got %v, expected %v", - pg.p, g, pg.g) - } - }) + g := parseGroupName("/group/", pg.p) + if g != pg.g { + t.Errorf("Path %v, got %v, expected %v", + pg.p, g, pg.g) + } } } -func TestParseWhip(t *testing.T) { - a := []struct{ p, d, b string }{ - {"", "", ""}, - {"/", "", ""}, - {"/foo", "", ""}, - {"/foo/", "", ""}, - {"/foo/bar", "", ""}, - {"/foo/bar/", "", ""}, - {"/foo/bar/baz", "", ""}, - {"/foo/bar/baz/", "", ""}, - {"/foo/.whip", "/foo/", ""}, - {"/foo/.whip/", "/foo/", ""}, - {"/foo/.whip/bar", "/foo/", "bar"}, - {"/foo/.whip/bar/", "/foo/", "bar"}, - {"/foo/.whip/bar/baz", "", ""}, - {"/foo/.whip/bar/baz/", "", ""}, +func TestParseSplit(t *testing.T) { + a := []struct{ p, a, b, c string }{ + {"", "", "", ""}, + {"/a", "/a", "", ""}, + {"/a/.b", "/a", ".b", ""}, + {"/a/.b/", "/a", ".b", "/"}, + {"/a/.b/c", "/a", ".b", "/c"}, + {"/a/.b/c/", "/a", ".b", "/c/"}, + {"/a/.b/c/d", "/a", ".b", "/c/d"}, + {"/a/.b/c/d/", "/a", ".b", "/c/d/"}, + {"/a/.b/c/d./", "/a", ".b", "/c/d./"}, } - for _, pdb := range a { - t.Run(pdb.p, func(t *testing.T) { - d, b := parseWhip(pdb.p) - if d != pdb.d || b != pdb.b { - t.Errorf("Path %v, got %v %v, expected %v %v", - pdb.p, d, b, pdb.d, pdb.b) - } - }) + for _, pabc := range(a) { + a, b, c := splitPath(pabc.p) + if pabc.a != a || pabc.b != b || pabc.c != c { + t.Errorf("Path %v, got %v, %v, %v, expected %v, %v, %v", + pabc.p, a, b, c, pabc.a, pabc.b, pabc.c, + ) + } } } @@ -79,14 +71,12 @@ func TestParseBearerToken(t *testing.T) { } for _, ab := range a { - t.Run(ab.a, func(t *testing.T) { - b := parseBearerToken(ab.a) - if b != ab.b { - t.Errorf("Bearer token %v, got %v, expected %v", - ab.a, b, ab.b, - ) - } - }) + b := parseBearerToken(ab.a) + if b != ab.b { + t.Errorf("Bearer token %v, got %v, expected %v", + ab.a, b, ab.b, + ) + } } } diff --git a/webserver/whip.go b/webserver/whip.go index 92d4638..2c75c10 100644 --- a/webserver/whip.go +++ b/webserver/whip.go @@ -23,23 +23,6 @@ import ( "github.com/jech/galene/rtpconn" ) -func parseWhip(pth string) (string, string) { - if pth != "/" { - pth = strings.TrimSuffix(pth, "/") - } - dir := path.Dir(pth) - base := path.Base(pth) - if base == ".whip" { - return dir + "/", "" - } - - if path.Base(dir) == ".whip" { - return path.Dir(dir) + "/", base - } - - return "", "" -} - var idSecret []byte var idCipher cipher.Block @@ -163,8 +146,8 @@ func whipEndpointHandler(w http.ResponseWriter, r *http.Request) { return } - pth, pthid := parseWhip(r.URL.Path) - if pthid != "" { + pth, kind, pthid := splitPath(r.URL.Path) + if kind != ".whip" || pthid != "/" { http.Error(w, "Internal server error", http.StatusInternalServerError) return @@ -282,13 +265,13 @@ func whipEndpointHandler(w http.ResponseWriter, r *http.Request) { } func whipResourceHandler(w http.ResponseWriter, r *http.Request) { - pth, obfuscated := parseWhip(r.URL.Path) - if pth == "" || obfuscated == "" { + pth, kind, rest := splitPath(r.URL.Path) + if kind != ".whip" || rest == "" { http.Error(w, "Internal server error", http.StatusInternalServerError) return } - id, err := deobfuscate(obfuscated) + id, err := deobfuscate(rest[1:]) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError)