- commit
- db58021
- parent
- 0492352
- author
- Eric Bower
- date
- 2024-09-11 02:31:19 +0000 UTC
fix(pgs): redirects
2 files changed,
+85,
-19
+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 + "/",
+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 {