repos / pico

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

commit
1a30037
parent
a7b907a
author
Eric Bower
date
2024-04-04 03:32:14 +0000 UTC
fix(pgs): add trailing slash even with extension
3 files changed,  +37, -5
M pgs/api.go
+14, -0
 1@@ -152,6 +152,11 @@ func createRssHandler(by string) http.HandlerFunc {
 2 	}
 3 }
 4 
 5+func hasProtocol(url string) bool {
 6+	isFullUrl := strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://")
 7+	return isFullUrl
 8+}
 9+
10 func (h *AssetHandler) handle(w http.ResponseWriter, r *http.Request) {
11 	var redirects []*RedirectRule
12 	redirectFp, _, _, err := h.Storage.GetObject(h.Bucket, filepath.Join(h.ProjectDir, "_redirects"))
13@@ -180,6 +185,15 @@ func (h *AssetHandler) handle(w http.ResponseWriter, r *http.Request) {
14 	attempts := []string{}
15 	for _, fp := range routes {
16 		if checkIsRedirect(fp.Status) {
17+			// hack: check to see if there's an index file in the requested directory
18+			// before redirecting, this saves a hop that will just end up a 404
19+			if !hasProtocol(fp.Filepath) && strings.HasSuffix(fp.Filepath, "/") {
20+				next := filepath.Join(h.ProjectDir, fp.Filepath, "index.html")
21+				_, _, _, err := h.Storage.GetObject(h.Bucket, next)
22+				if err != nil {
23+					continue
24+				}
25+			}
26 			h.Logger.Info(
27 				"redirecting request",
28 				"bucket", h.Bucket.Name,
M pgs/cal_route.go
+1, -5
 1@@ -74,7 +74,6 @@ func checkIsRedirect(status int) bool {
 2 }
 3 
 4 func calcRoutes(projectName, fp string, userRedirects []*RedirectRule) []*HttpReply {
 5-	fext := filepath.Ext(fp)
 6 	rts := []*HttpReply{}
 7 	// add route as-is without expansion
 8 	if fp != "" && !strings.HasSuffix(fp, "/") {
 9@@ -132,7 +131,7 @@ func calcRoutes(projectName, fp string, userRedirects []*RedirectRule) []*HttpRe
10 
11 	// filename without extension mean we might have a directory
12 	// so add a trailing slash with a 301
13-	if fp != "" && !strings.HasSuffix(fp, "/") && fext == "" {
14+	if fp != "" && !strings.HasSuffix(fp, "/") {
15 		redirectRoute := shared.GetAssetFileName(&utils.FileEntry{
16 			Filepath: fp + "/",
17 		})
18@@ -140,9 +139,6 @@ func calcRoutes(projectName, fp string, userRedirects []*RedirectRule) []*HttpRe
19 			rts,
20 			&HttpReply{Filepath: redirectRoute, Status: http.StatusMovedPermanently},
21 		)
22-		// 301 is always actived so anything after this branch will never
23-		// be executed ... so return early
24-		// return rts
25 	}
26 
27 	notFound := &HttpReply{
M pgs/calc_route_test.go
+22, -0
 1@@ -19,6 +19,7 @@ func TestCalcRoutes(t *testing.T) {
 2 			Actual: calcRoutes("test", "/index.html", []*RedirectRule{}),
 3 			Expected: []*HttpReply{
 4 				{Filepath: "test/index.html", Status: 200},
 5+				{Filepath: "/index.html/", Status: 301},
 6 				{Filepath: "test/404.html", Status: 404},
 7 			},
 8 		},
 9@@ -27,6 +28,7 @@ func TestCalcRoutes(t *testing.T) {
10 			Actual: calcRoutes("test", "/index.txt", []*RedirectRule{}),
11 			Expected: []*HttpReply{
12 				{Filepath: "test/index.txt", Status: 200},
13+				{Filepath: "/index.txt/", Status: 301},
14 				{Filepath: "test/404.html", Status: 404},
15 			},
16 		},
17@@ -35,6 +37,7 @@ func TestCalcRoutes(t *testing.T) {
18 			Actual: calcRoutes("test", "/wow.html", []*RedirectRule{}),
19 			Expected: []*HttpReply{
20 				{Filepath: "test/wow.html", Status: 200},
21+				{Filepath: "/wow.html/", Status: 301},
22 				{Filepath: "test/404.html", Status: 404},
23 			},
24 		},
25@@ -43,6 +46,7 @@ func TestCalcRoutes(t *testing.T) {
26 			Actual: calcRoutes("test", "/nice/index.html", []*RedirectRule{}),
27 			Expected: []*HttpReply{
28 				{Filepath: "test/nice/index.html", Status: 200},
29+				{Filepath: "/nice/index.html/", Status: 301},
30 				{Filepath: "test/404.html", Status: 404},
31 			},
32 		},
33@@ -51,6 +55,7 @@ func TestCalcRoutes(t *testing.T) {
34 			Actual: calcRoutes("test", "/nice/wow.html", []*RedirectRule{}),
35 			Expected: []*HttpReply{
36 				{Filepath: "test/nice/wow.html", Status: 200},
37+				{Filepath: "/nice/wow.html/", Status: 301},
38 				{Filepath: "test/404.html", Status: 404},
39 			},
40 		},
41@@ -84,6 +89,7 @@ func TestCalcRoutes(t *testing.T) {
42 			Expected: []*HttpReply{
43 				{Filepath: "test/nice.html", Status: 200},
44 				{Filepath: "test/index.html", Status: 200},
45+				{Filepath: "/index.html/", Status: 301},
46 				{Filepath: "test/404.html", Status: 404},
47 			},
48 		},
49@@ -92,6 +98,7 @@ func TestCalcRoutes(t *testing.T) {
50 			Actual: calcRoutes("test", "/index.xml", []*RedirectRule{}),
51 			Expected: []*HttpReply{
52 				{Filepath: "test/index.xml", Status: 200},
53+				{Filepath: "/index.xml/", Status: 301},
54 				{Filepath: "test/404.html", Status: 404},
55 			},
56 		},
57@@ -204,6 +211,7 @@ func TestCalcRoutes(t *testing.T) {
58 			Expected: []*HttpReply{
59 				{Filepath: "test/wow.html", Status: 200},
60 				{Filepath: "https://pico.sh", Status: 301},
61+				{Filepath: "/wow.html/", Status: 301},
62 				{Filepath: "test/404.html", Status: 404},
63 			},
64 		},
65@@ -331,6 +339,20 @@ func TestCalcRoutes(t *testing.T) {
66 				{Filepath: "public/404.html", Status: 404},
67 			},
68 		},
69+		{
70+			Name: "directoryWithExtension",
71+			Actual: calcRoutes(
72+				"public",
73+				"/space.nvim",
74+				[]*RedirectRule{},
75+			),
76+			Expected: []*HttpReply{
77+				{Filepath: "public/space.nvim", Status: 200},
78+				{Filepath: "public/space.nvim.html", Status: 200},
79+				{Filepath: "/space.nvim/", Status: 301},
80+				{Filepath: "public/404.html", Status: 404},
81+			},
82+		},
83 	}
84 
85 	for _, fixture := range fixtures {