diff --git a/internal/darkstormtech/app.go b/internal/darkstormtech/app.go new file mode 100644 index 0000000..224d449 --- /dev/null +++ b/internal/darkstormtech/app.go @@ -0,0 +1,95 @@ +package darkstormtech + +import ( + "context" + "io/fs" + "log" + "net/http" + "os" + "strings" + "time" + + "github.com/CalebQ42/stupid-backend" + "github.com/CalebQ42/stupid-backend/pkg/defaultapp" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type DarkstormTech struct { + *defaultapp.App + filesFolder string +} + +func NewDarkstormTech(c *mongo.Client, filesFolder string) *DarkstormTech { + return &DarkstormTech{ + App: defaultapp.NewDefaultApp(c.Database("darkstormtech")), + filesFolder: filesFolder, + } +} + +func (d *DarkstormTech) Extension(req *stupid.Request) bool { + if req.Path[0] != "page" { + return false + } + if len(req.Path) == 1 { + req.Resp.WriteHeader(http.StatusBadRequest) + return true + } + if req.Path[1] == "files" { + return d.handleFiles(req) + } + res := d.DB.Collection("pages").FindOne(context.TODO(), bson.M{"_id": strings.Join(req.Path[1:], "/")}, options.FindOne().SetProjection(bson.M{"_id": 0, "content": 1})) + if res.Err() == mongo.ErrNoDocuments { + req.Resp.WriteHeader(http.StatusNotFound) //TODO: Give some sort of default page. + return true + } else if res.Err() != nil { + log.Println("Error while getting page:", res.Err()) + req.Resp.WriteHeader(http.StatusInternalServerError) + return true + } + pag := struct { //TODO: Add favicon and title support. + Content string + }{} + err := res.Decode(&pag) + if err != nil { + log.Println("Error while decoding page:", err) + req.Resp.WriteHeader(http.StatusInternalServerError) + return true + } + _, err = req.Resp.Write([]byte(pag.Content)) + if err != nil { + log.Println("Error while writing response:", err) + req.Resp.WriteHeader(http.StatusInternalServerError) + } + return true +} + +func (d *DarkstormTech) handleFiles(req *stupid.Request) bool { + fils, err := os.ReadDir(d.filesFolder) + if err != nil { + log.Println("Error while getting files:", err) + req.Resp.WriteHeader(http.StatusInternalServerError) + return true + } + out := "" + var inf fs.FileInfo + for _, f := range fils { + if f.IsDir() { + continue + } + inf, err = f.Info() + if err != nil { + log.Println("Error while getting FileInfo for", f.Name(), err) + req.Resp.WriteHeader(http.StatusInternalServerError) + return true + } + out += "

" + f.Name() + " " + inf.ModTime().Round(time.Minute).String() + "

\n" + } + _, err = req.Resp.Write([]byte(out)) + if err != nil { + log.Println("Error while writing output:", err) + req.Resp.WriteHeader(http.StatusInternalServerError) + } + return true +} diff --git a/stupid.go b/stupid.go index b0e8369..18015b7 100644 --- a/stupid.go +++ b/stupid.go @@ -2,11 +2,14 @@ package main import ( "context" + "flag" "io" "log" "net/http" "os" + "path/filepath" + "github.com/CalebQ42/darkstorm-server/internal/darkstormtech" "github.com/CalebQ42/stupid-backend" "github.com/CalebQ42/stupid-backend/pkg/db" "github.com/CalebQ42/stupid-backend/pkg/defaultapp" @@ -28,7 +31,7 @@ func setupStupid(keyPath, mongoStr string) error { stupid := stupid.NewStupidBackend(db.NewMongoTable(client.Database("stupid").Collection("keys")), map[string]stupid.App{ "swassistant": defaultapp.NewDefaultApp(client.Database("swassistant")), "cdr": defaultapp.NewDefaultApp(client.Database("cdr")), - "darkstormtech": defaultapp.NewUnauthorizedDataApp(client.Database("darkstormtech")), + "darkstormtech": darkstormtech.NewDarkstormTech(client, filepath.Join(flag.Arg(0), "files")), }) users := true var pub, priv []byte @@ -57,7 +60,7 @@ func setupStupid(keyPath, mongoStr string) error { if users { stupid.EnableUserAuth(db.NewMongoTable(client.Database("stupid").Collection("keys")), pub, priv) } - stupid.SetHeaderValues(map[string]string{"Access-Control-Allow-Origin": "https://darkstorm.tech"}) + stupid.SetHeaderValues(map[string]string{"Access-Control-Allow-Origin": "*"}) http.Handle("api.darkstorm.tech/", stupid) return nil } diff --git a/web.go b/web.go index 40aeb7a..ac01353 100644 --- a/web.go +++ b/web.go @@ -3,7 +3,6 @@ package main import ( "crypto/tls" "flag" - "fmt" "log" "net/http" "net/http/httputil" @@ -62,75 +61,25 @@ type fileOrIndexHandler struct { appFolders []string } -func (f *fileOrIndexHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) { - reqPath := strings.Split(strings.TrimPrefix(path.Clean(req.URL.Path), "/"), "/") - if len(reqPath) == 0 { - reqPath = []string{"index.html"} - } - fils, err := os.ReadDir(f.baseFolder) - if err != nil { - if os.IsNotExist(err) { - writer.WriteHeader(http.StatusNotFound) - } else { - log.Println("Error while ReadDir:", err) - writer.WriteHeader(http.StatusInternalServerError) - } +func (f *fileOrIndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + reqPath := strings.TrimPrefix(path.Clean(r.URL.Path), "/") + if reqPath == "" || reqPath == "index.html" { + http.ServeFile(w, r, path.Join(f.baseFolder, "index.html")) return } - filename := path.Clean(f.baseFolder) - var found bool -outer: - for pathI := 0; pathI < len(reqPath); pathI++ { - found = false - for filI := range fils { - if strings.EqualFold(strings.ToLower(fils[filI].Name()), reqPath[pathI]) { - found = true - filename = path.Join(filename, fils[filI].Name()) - if pathI == len(reqPath)-1 { - if fils[filI].IsDir() { - reqPath = append(reqPath, "index.html") - } - break - } else if !fils[filI].IsDir() { - break outer - } else { - fils, err = os.ReadDir(filename) - if err != nil { - log.Println("Error while ReadDir:", err) - writer.WriteHeader(http.StatusInternalServerError) - return - } - } - break - } - } - if !found { - break - } - } - if !found { - for _, a := range f.appFolders { - if strings.EqualFold(reqPath[0], a) { - http.ServeFile(writer, req, path.Join(f.baseFolder, a, "index.html")) - return - } - } - } - fil, err := os.Open(filename) - if err != nil { - writer.WriteHeader(http.StatusInternalServerError) - return - } - st, _ := fil.Stat() - if st.IsDir() { - var subFil *os.File - subFil, err = os.Open(path.Join(filename, "index.html")) - if os.IsNotExist(err) { - fmt.Println("file server for", filename) - http.FileServer(http.Dir(filename)).ServeHTTP(writer, req) + reqPath = path.Join(f.baseFolder, reqPath) + if fil, err := os.Open(reqPath); err == nil { + inf, _ := fil.Stat() + if !inf.IsDir() { + http.ServeFile(w, r, reqPath) return } - fil = subFil } - http.ServeFile(writer, req, fil.Name()) + for _, a := range f.appFolders { + if strings.HasPrefix(reqPath, path.Join(f.baseFolder, a)) { + http.ServeFile(w, r, path.Join(f.baseFolder, a, "index.html")) + return + } + } + http.ServeFile(w, r, path.Join(f.baseFolder, "index.html")) }