96 lines
2.2 KiB
Go
96 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/gabriel-vasile/mimetype"
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func shortID(length int64) string {
|
|
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
|
ll := len(chars)
|
|
b := make([]byte, length)
|
|
rand.Read(b) // generates len(b) random bytes
|
|
for i := int64(0); i < length; i++ {
|
|
b[i] = chars[int(b[i])%ll]
|
|
}
|
|
return string(b)
|
|
}
|
|
|
|
func UploadHandler(w http.ResponseWriter, r *http.Request) {
|
|
// url_len sanitize
|
|
inpUrlLen := r.FormValue("url_len")
|
|
sanUrlLen, err := strconv.ParseInt(inpUrlLen, 10, 64)
|
|
if err != nil {
|
|
sanUrlLen = 24
|
|
}
|
|
if sanUrlLen < 5 || sanUrlLen > 64 {
|
|
w.Write([]byte("url_len needs to be between 5 and 64\n"))
|
|
return
|
|
}
|
|
|
|
// expiry sanitize
|
|
inpExpiry := r.FormValue("expiry")
|
|
sanExpiry, err := strconv.ParseInt(inpExpiry, 10, 64)
|
|
if err != nil {
|
|
sanExpiry = 86400
|
|
}
|
|
if sanExpiry < 5 || sanExpiry > 432000 {
|
|
w.Write([]byte("expiry needs to be between 5 and 432000\n"))
|
|
return
|
|
}
|
|
|
|
// mimetype check
|
|
file, _, err := r.FormFile("file")
|
|
if err != nil {
|
|
w.Write([]byte("error reading your file parameter\n"))
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
mtype, err := mimetype.DetectReader(file)
|
|
if err != nil {
|
|
w.Write([]byte("error detecting the mime type of your file\n"))
|
|
return
|
|
}
|
|
file.Seek(0, 0)
|
|
|
|
// ready for upload
|
|
name := shortID(sanUrlLen) + mtype.Extension()
|
|
|
|
log.Info().Str("mtype", mtype.String()).Str("ext", mtype.Extension()).Int64("expiry", sanExpiry).Int64("url_len", sanUrlLen).Msg("Writing new file")
|
|
|
|
f, err := os.OpenFile("data/"+name, os.O_WRONLY|os.O_CREATE, 0644)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Error opening a file for write")
|
|
w.Write([]byte("internal error\n"))
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
io.Copy(f, file)
|
|
|
|
w.Write([]byte("https://u.filehole.org/" + name + "\n"))
|
|
}
|
|
|
|
func main() {
|
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
|
|
r := mux.NewRouter()
|
|
r.HandleFunc("/", UploadHandler).Methods("POST")
|
|
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, "index.html")
|
|
}).Methods("GET")
|
|
http.Handle("/", r)
|
|
|
|
http.ListenAndServe("127.0.0.1:8000", r)
|
|
}
|