package main import ( "fmt" "io" "io/ioutil" "log" "net/http" "os" ) var Info = log.New(os.Stdout, "\u001b[34mINFO: \u001B[0m", log.LstdFlags|log.Lshortfile) var Warning = log.New(os.Stdout, "\u001b[33mWARNING: \u001B[0m", log.LstdFlags|log.Lshortfile) var Error = log.New(os.Stdout, "\u001b[31mERROR: \u001b[0m", log.LstdFlags|log.Lshortfile) var Debug = log.New(os.Stdout, "\u001b[36mDEBUG: \u001B[0m", log.LstdFlags|log.Lshortfile) func upload_file(w http.ResponseWriter, req *http.Request) { file, fileHeader, err := req.FormFile("file") if err != nil { Error.Println(err) } defer file.Close() f, err := os.OpenFile(fmt.Sprintf("%v/%v", get_envvar_or_fatal("SFU_FILES_DIR"), fileHeader.Filename), os.O_WRONLY|os.O_CREATE, 0666) defer f.Close() io.Copy(f, file) } func list_uploaded_files(w http.ResponseWriter, req *http.Request) { files_dir := get_envvar_or_fatal("SFU_FILES_DIR") Info.Println(fmt.Sprintf("server: will list uploaded files on %v", files_dir)) files, err := ioutil.ReadDir(files_dir) if err != nil { Warning.Println(fmt.Sprintf("%v does not exist", files_dir)) Info.Println(fmt.Sprintf("will create %v", files_dir)) _ = os.Mkdir(files_dir, os.ModePerm) } for _, f := range files { fmt.Fprintf(w, "%v\n", f.Name()) } } func get_envvar_or_fatal(envvar_name string) string { envvar_value, isSet := os.LookupEnv(envvar_name) if !isSet { Error.Println(fmt.Sprintf("%v is not set", envvar_name)) os.Exit(1) } return envvar_value } func main() { http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { path := req.URL.Path Info.Println(fmt.Sprintf("received %v on %v", req.Method, path)) if path != "/" { err_msg := fmt.Sprintf("path %v does not exist", path) http.Error(w, err_msg, http.StatusNotFound) Warning.Println(err_msg) Error.Println(fmt.Sprintf("will return %v", http.StatusNotFound)) return } switch req.Method { case http.MethodGet: list_uploaded_files(w, req) case http.MethodPost: upload_file(w, req) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) Warning.Println(fmt.Sprintf("%v not allowed", req.Method)) Error.Println(fmt.Sprintf("will return %v", http.StatusMethodNotAllowed)) } }) port := fmt.Sprintf(":%v", get_envvar_or_fatal("SFU_PORT")) Info.Println(fmt.Sprintf("running SFU on port %v", port)) err := http.ListenAndServe(port, nil) if err != nil { Error.Println(fmt.Sprintf("%v port may not be available", port)) os.Exit(1) } }