From 834af5d3cfb6a6220b6be212959bf85edee9c54c Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Mon, 2 Jan 2023 06:16:33 +0600 Subject: [PATCH] :sparkles: Added urlutil package with ShiftPath helper --- internal/urlutil/shift_path.go | 22 ++++++++++++++++++++ internal/urlutil/shift_path_test.go | 31 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 internal/urlutil/shift_path.go create mode 100644 internal/urlutil/shift_path_test.go diff --git a/internal/urlutil/shift_path.go b/internal/urlutil/shift_path.go new file mode 100644 index 0000000..39dbf71 --- /dev/null +++ b/internal/urlutil/shift_path.go @@ -0,0 +1,22 @@ +package urlutil + +import ( + "path" + "strings" +) + +// ShiftPath splits off the first component of p, which will be cleaned of +// relative components before processing. head will never contain a slash and +// tail will always be a rooted path without trailing slash. +// +// See: https://blog.merovius.de/posts/2017-06-18-how-not-to-use-an-http-router/ +func ShiftPath(p string) (head, tail string) { + p = path.Clean("/" + p) + + i := strings.Index(p[1:], "/") + 1 + if i <= 0 { + return p[1:], "/" + } + + return p[1:i], p[i:] +} diff --git a/internal/urlutil/shift_path_test.go b/internal/urlutil/shift_path_test.go new file mode 100644 index 0000000..4b20f36 --- /dev/null +++ b/internal/urlutil/shift_path_test.go @@ -0,0 +1,31 @@ +package urlutil_test + +import ( + "testing" + + "source.toby3d.me/toby3d/auth/internal/urlutil" +) + +func TestShiftPath(t *testing.T) { + t.Parallel() + + for in, out := range map[string][2]string{ + "/": {"", "/"}, + "/foo": {"foo", "/"}, + "/foo/": {"foo", "/"}, + "/foo/bar": {"foo", "/bar"}, + "/foo/bar/": {"foo", "/bar"}, + } { + in, out := in, out + + t.Run(in, func(t *testing.T) { + t.Parallel() + + head, path := urlutil.ShiftPath(in) + + if out[0] != head || out[1] != path { + t.Errorf("ShiftPath(%s) = '%s', '%s', want '%s', '%s'", in, head, path, out[0], out[1]) + } + }) + } +}