diff --git a/main.go b/main.go new file mode 100644 index 0000000..d04c3d7 --- /dev/null +++ b/main.go @@ -0,0 +1,86 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "local/args" + "local/logb" + "local/storage" + "net/http" +) + +type server struct { + db storage.DBStream +} + +func main() { + as := args.NewArgSet() + as.Append(args.INT, "p", "port", 8121) + as.Append(args.STRING, "db", "db type", "mapstream") + as.Append(args.STRING, "dbaddr", "db addr", "/tmp/db") + if err := as.Parse(); err != nil { + panic(err) + } + + db, err := storage.New(storage.TypeFromString(as.GetString("db")), as.GetString("dbaddr")) + if err != nil { + panic(err) + } + dbs := db.(storage.DBStream) + + server := server{ + db: dbs, + } + addr := fmt.Sprintf(":%d", as.GetInt("p")) + + logb.Infof("listening: %s with %+v", addr, server) + if err := http.ListenAndServe(addr, server); err != nil { + panic(err) + } +} + +func (server server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + fileServer := http.FileServer(http.Dir("./")) + switch r.URL.Path { + case "/api": + if err := server.apiHandler(w, r); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + default: + fileServer.ServeHTTP(w, r) + } +} + +func (server server) apiHandler(w http.ResponseWriter, r *http.Request) error { + key := r.URL.Query().Get("key") + switch r.Method { + case http.MethodGet: + switch key { + case "": + db := server.db.(storage.DB) + keys, err := db.List(nil) + if err != nil { + return err + } + return json.NewEncoder(w).Encode(keys) + default: + v, err := server.db.GetStream(key) + if err == storage.ErrNotFound { + return nil + } + if err != nil { + return err + } + _, err = io.Copy(w, v) + return err + } + case http.MethodPost: + return server.db.SetStream(key, r.Body) + case http.MethodDelete: + return server.db.SetStream(key, nil) + default: + http.NotFound(w, r) + } + return nil +}