repos / pico

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

commit
707a530
parent
06d4bdd
author
Eric Bower
date
2023-08-14 14:22:30 +0000 UTC
fix: better object detection and route detection
2 files changed,  +68, -36
M pgs/api.go
+60, -35
  1@@ -21,15 +21,41 @@ import (
  2 )
  3 
  4 type AssetHandler struct {
  5-	Username  string
  6-	Subdomain string
  7-	Filepath  string
  8-	Cfg       *shared.ConfigSite
  9-	Dbpool    db.DB
 10-	Storage   storage.ObjectStorage
 11-	Logger    *zap.SugaredLogger
 12-	Cache     *gocache.Cache
 13-	UserID    string
 14+	Username   string
 15+	Subdomain  string
 16+	Filepath   string
 17+	ProjectDir string
 18+	Cfg        *shared.ConfigSite
 19+	Dbpool     db.DB
 20+	Storage    storage.ObjectStorage
 21+	Logger     *zap.SugaredLogger
 22+	Cache      *gocache.Cache
 23+	UserID     string
 24+}
 25+
 26+func calcPossibleRoutes(projectName, fp string) []string {
 27+	fname := filepath.Base(fp)
 28+	fdir := filepath.Dir(fp)
 29+	fext := filepath.Ext(fp)
 30+
 31+	// hack: we need to accommodate routes that are just directories
 32+	// and point the user to the index.html of each root dir.
 33+	if fname == "." || fext == "" {
 34+		return []string{
 35+			shared.GetAssetFileName(&utils.FileEntry{
 36+				Filepath: filepath.Join(projectName, fp, "index.html"),
 37+			}),
 38+		}
 39+	}
 40+
 41+	return []string{
 42+		shared.GetAssetFileName(&utils.FileEntry{
 43+			Filepath: filepath.Join(projectName, fdir, fname),
 44+		}),
 45+		shared.GetAssetFileName(&utils.FileEntry{
 46+			Filepath: filepath.Join(projectName, fp, "index.html"),
 47+		}),
 48+	}
 49 }
 50 
 51 func assetHandler(w http.ResponseWriter, h *AssetHandler) {
 52@@ -40,22 +66,30 @@ func assetHandler(w http.ResponseWriter, h *AssetHandler) {
 53 		return
 54 	}
 55 
 56-	fname := shared.GetAssetFileName(&utils.FileEntry{Filepath: h.Filepath})
 57+	routes := calcPossibleRoutes(h.ProjectDir, h.Filepath)
 58+	var contents storage.ReaderAtCloser
 59+	assetFilepath := ""
 60+	for _, fp := range routes {
 61+		c, err := h.Storage.GetFile(bucket, fp)
 62+		if err == nil {
 63+			contents = c
 64+			assetFilepath = fp
 65+			break
 66+		}
 67+	}
 68 
 69-	contents, err := h.Storage.GetFile(bucket, fname)
 70-	if err != nil {
 71+	if assetFilepath == "" {
 72 		h.Logger.Infof(
 73 			"asset not found in bucket: bucket:[%s], file:[%s]",
 74 			bucket.Name,
 75-			fname,
 76+			h.Filepath,
 77 		)
 78 		http.Error(w, err.Error(), http.StatusInternalServerError)
 79 		return
 80 	}
 81 	defer contents.Close()
 82 
 83-	contentType := shared.GetMimeType(fname)
 84-
 85+	contentType := shared.GetMimeType(assetFilepath)
 86 	w.Header().Add("Content-Type", contentType)
 87 	_, err = io.Copy(w, contents)
 88 
 89@@ -94,7 +128,6 @@ func serveAsset(subdomain string, w http.ResponseWriter, r *http.Request) {
 90 		http.Error(w, err.Error(), http.StatusNotFound)
 91 		return
 92 	}
 93-	projectDir := props.ProjectName
 94 
 95 	user, err := dbpool.FindUserForName(props.Username)
 96 	if err != nil {
 97@@ -102,31 +135,23 @@ func serveAsset(subdomain string, w http.ResponseWriter, r *http.Request) {
 98 		http.Error(w, "user not found", http.StatusNotFound)
 99 		return
100 	}
101+	projectDir := props.ProjectName
102 	project, err := dbpool.FindProjectByName(user.ID, props.ProjectName)
103 	if err == nil {
104 		projectDir = project.ProjectDir
105 	}
106 
107-	fname := filepath.Base(floc)
108-	fdir := filepath.Dir(floc)
109-	// hack: we need to accommodate routes that are just directories
110-	// and point the user to the index.html of each root dir.
111-	if fname == "." || filepath.Ext(floc) == "" {
112-		fname = "index.html"
113-		fdir = floc
114-	}
115-	fpath := filepath.Join(projectDir, fdir, fname)
116-
117 	assetHandler(w, &AssetHandler{
118-		Username:  props.Username,
119-		UserID:    user.ID,
120-		Subdomain: subdomain,
121-		Filepath:  fpath,
122-		Cfg:       cfg,
123-		Dbpool:    dbpool,
124-		Storage:   st,
125-		Logger:    logger,
126-		Cache:     cache,
127+		Username:   props.Username,
128+		UserID:     user.ID,
129+		Subdomain:  subdomain,
130+		ProjectDir: projectDir,
131+		Filepath:   floc,
132+		Cfg:        cfg,
133+		Dbpool:     dbpool,
134+		Storage:    st,
135+		Logger:     logger,
136+		Cache:      cache,
137 	})
138 }
139 
M shared/storage/minio.go
+8, -1
 1@@ -125,7 +125,14 @@ func (s *StorageMinio) DeleteBucket(bucket Bucket) error {
 2 }
 3 
 4 func (s *StorageMinio) GetFile(bucket Bucket, fpath string) (ReaderAtCloser, error) {
 5-	obj, err := s.Client.GetObject(context.TODO(), bucket.Name, fpath, minio.GetObjectOptions{})
 6+	// we have to stat the object first to see if it exists
 7+	// https://github.com/minio/minio-go/issues/654
 8+	_, err := s.Client.StatObject(context.Background(), bucket.Name, fpath, minio.StatObjectOptions{})
 9+	if err != nil {
10+		return nil, err
11+	}
12+
13+	obj, err := s.Client.GetObject(context.Background(), bucket.Name, fpath, minio.GetObjectOptions{})
14 	if err != nil {
15 		return nil, err
16 	}