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 }