commit 630140521ee9695ef43630a4d857f0915a7b17f6 Author: cătălin Date: Mon Jun 27 21:41:37 2022 +0200 feat: add basic impl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc23fb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.env +.vscode/ +files/ +main/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0da2d38 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM golang:1.17.11-alpine3.16 + +ENV APP_ROOT /opt/sfu + +RUN mkdir -p "$APP_ROOT" +WORKDIR "$APP_ROOT" + +COPY go.mod . +COPY main.go . + +RUN go build \ + && rm -r go.mod main.go +ENTRYPOINT [ "/bin/sh", "-c", "$APP_ROOT/main"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..456d0b5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +--- +version: "3.9" +services: + app: + build: + context: . + ports: + - "8080:80" + env_file: + - .env \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c0ecf8b --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module main + +go 1.17 diff --git a/main b/main new file mode 100755 index 0000000..146088b Binary files /dev/null and b/main differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..8b11de7 --- /dev/null +++ b/main.go @@ -0,0 +1,81 @@ +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) + } +}