repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
db58021
parent
0492352
author
Eric Bower
date
2024-09-11 02:31:19 +0000 UTC
fix(pgs): redirects
2 files changed,  +85, -19
M pgs/calc_route.go
+31, -7
 1@@ -74,7 +74,7 @@ func checkIsRedirect(status int) bool {
 2 	return status >= 300 && status <= 399
 3 }
 4 
 5-func correlatePlaceholder(orig, pattern string) string {
 6+func correlatePlaceholder(orig, pattern string) (string, string) {
 7 	origList := splitFp(orig)
 8 	patternList := splitFp(pattern)
 9 	nextList := []string{}
10@@ -89,7 +89,17 @@ func correlatePlaceholder(orig, pattern string) string {
11 			nextList = append(nextList, origList[idx])
12 		}
13 	}
14-	return filepath.Join(nextList...)
15+
16+	_type := "none"
17+	if len(nextList) > 0 && len(nextList) == len(patternList) {
18+		_type = "match"
19+	} else if strings.Contains(pattern, "*") {
20+		_type = "wildcard"
21+	} else if strings.Contains(pattern, ":") {
22+		_type = "variable"
23+	}
24+
25+	return filepath.Join(nextList...), _type
26 }
27 
28 func splitFp(str string) []string {
29@@ -179,9 +189,22 @@ func calcRoutes(projectName, fp string, userRedirects []*RedirectRule) []*HttpRe
30 
31 		// hack: make suffix `/` optional when matching
32 		from := filepath.Clean(redirect.From)
33-		fromMatcher := correlatePlaceholder(fp, from)
34-		rr := regexp.MustCompile(fromMatcher)
35-		match := rr.FindStringSubmatch(fp)
36+		match := []string{}
37+		fromMatcher, matcherType := correlatePlaceholder(fp, from)
38+		switch matcherType {
39+		case "match":
40+			fallthrough
41+		case "wildcard":
42+			fallthrough
43+		case "variable":
44+			rr := regexp.MustCompile(fromMatcher)
45+			match = rr.FindStringSubmatch(fp)
46+		case "none":
47+			fallthrough
48+		default:
49+			break
50+		}
51+
52 		if len(match) > 0 {
53 			isRedirect := checkIsRedirect(redirect.Status)
54 			if !isRedirect && !hasProtocol(redirect.To) {
55@@ -221,8 +244,9 @@ func calcRoutes(projectName, fp string, userRedirects []*RedirectRule) []*HttpRe
56 		}
57 	}
58 
59-	// filename without extension mean we might have a directory
60-	// so add a trailing slash with a 301
61+	// we might have a directory so add a trailing slash with a 301
62+	// we can't check for file extention because route could have a dot
63+	// and ext parsing gets confused
64 	if fp != "" && !strings.HasSuffix(fp, "/") {
65 		redirectRoute := shared.GetAssetFileName(&utils.FileEntry{
66 			Filepath: fp + "/",
M pgs/calc_route_test.go
+54, -12
  1@@ -103,7 +103,7 @@ func TestCalcRoutes(t *testing.T) {
  2 			},
  3 		},
  4 		{
  5-			Name: "redirectRule",
  6+			Name: "redirect-rule",
  7 			Actual: calcRoutes(
  8 				"test",
  9 				"/wow",
 10@@ -124,7 +124,7 @@ func TestCalcRoutes(t *testing.T) {
 11 			},
 12 		},
 13 		{
 14-			Name: "redirectToPico",
 15+			Name: "redirect-to-pico",
 16 			Actual: calcRoutes(
 17 				"test",
 18 				"/tester1",
 19@@ -155,7 +155,7 @@ func TestCalcRoutes(t *testing.T) {
 20 			},
 21 		},
 22 		{
 23-			Name: "redirectToRoot",
 24+			Name: "redirect-to-root",
 25 			Actual: calcRoutes(
 26 				"test",
 27 				"/wow/",
 28@@ -194,7 +194,7 @@ func TestCalcRoutes(t *testing.T) {
 29 			},
 30 		},
 31 		{
 32-			Name: "redirectFullUrl",
 33+			Name: "redirect-full-url",
 34 			Actual: calcRoutes(
 35 				"test",
 36 				"/wow.html",
 37@@ -208,11 +208,12 @@ func TestCalcRoutes(t *testing.T) {
 38 			),
 39 			Expected: []*HttpReply{
 40 				{Filepath: "test/wow.html", Status: 200},
 41-				{Filepath: "https://pico.sh", Status: 301},
 42+				{Filepath: "/wow.html/", Status: 301},
 43+				{Filepath: "test/404.html", Status: 404},
 44 			},
 45 		},
 46 		{
 47-			Name: "redirectFullUrlDirectory",
 48+			Name: "redirect-full-url-directory",
 49 			Actual: calcRoutes(
 50 				"test",
 51 				"/wow",
 52@@ -231,7 +232,7 @@ func TestCalcRoutes(t *testing.T) {
 53 			},
 54 		},
 55 		{
 56-			Name: "redirectDirectory",
 57+			Name: "redirect-directory",
 58 			Actual: calcRoutes(
 59 				"public",
 60 				"/xyz",
 61@@ -252,7 +253,7 @@ func TestCalcRoutes(t *testing.T) {
 62 			},
 63 		},
 64 		{
 65-			Name: "redirectSubDirectory",
 66+			Name: "redirect-sub-directory",
 67 			Actual: calcRoutes(
 68 				"public",
 69 				"/folder2",
 70@@ -274,7 +275,7 @@ func TestCalcRoutes(t *testing.T) {
 71 			},
 72 		},
 73 		{
 74-			Name: "redirectFromAndToSame",
 75+			Name: "redirect-from-and-to-same",
 76 			Actual: calcRoutes(
 77 				"public",
 78 				"/folder2",
 79@@ -294,7 +295,7 @@ func TestCalcRoutes(t *testing.T) {
 80 			},
 81 		},
 82 		{
 83-			Name: "redirectNoTrailingSlash",
 84+			Name: "redirect-no-trailing-slash",
 85 			Actual: calcRoutes(
 86 				"public",
 87 				"/space/",
 88@@ -313,7 +314,7 @@ func TestCalcRoutes(t *testing.T) {
 89 			},
 90 		},
 91 		{
 92-			Name: "redirectWithTrailingSlash",
 93+			Name: "redirect-with-trailing-slash",
 94 			Actual: calcRoutes(
 95 				"public",
 96 				"/space",
 97@@ -334,7 +335,7 @@ func TestCalcRoutes(t *testing.T) {
 98 			},
 99 		},
100 		{
101-			Name: "directoryWithExtension",
102+			Name: "directory-with-extension",
103 			Actual: calcRoutes(
104 				"public",
105 				"/space.nvim",
106@@ -423,6 +424,47 @@ func TestCalcRoutes(t *testing.T) {
107 				{Filepath: "public/404.html", Status: 404},
108 			},
109 		},
110+		{
111+			Name: "302-redirect",
112+			Actual: calcRoutes(
113+				"public",
114+				"/pages/chem351.html",
115+				[]*RedirectRule{
116+					{
117+						From:   "/pages/chem351.html",
118+						To:     "/pages/chem351",
119+						Status: 302,
120+						Force:  true,
121+					},
122+				},
123+			),
124+			Expected: []*HttpReply{
125+				{Filepath: "/pages/chem351", Status: 302},
126+				{Filepath: "/pages/chem351.html/", Status: 301},
127+				{Filepath: "public/404.html", Status: 404},
128+			},
129+		},
130+		{
131+			Name: "302-redirect-non-match",
132+			Actual: calcRoutes(
133+				"public",
134+				"/pages/chem351",
135+				[]*RedirectRule{
136+					{
137+						From:   "/pages/chem351.html",
138+						To:     "/pages/chem351",
139+						Status: 302,
140+						Force:  true,
141+					},
142+				},
143+			),
144+			Expected: []*HttpReply{
145+				{Filepath: "public/pages/chem351", Status: 200},
146+				{Filepath: "public/pages/chem351.html", Status: 200},
147+				{Filepath: "/pages/chem351/", Status: 301},
148+				{Filepath: "public/404.html", Status: 404},
149+			},
150+		},
151 	}
152 
153 	for _, fixture := range fixtures {