123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- package main
- import (
- "crypto/hmac"
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "io"
- "log"
- "net/http"
- "os"
- "path"
- )
- type Config struct {
- Listen string `json:"listen"`
- StaticKey string `json:"static_key"`
- DeleteKey string `json:"static_delete_key"`
- MaxFileSize int64 `json:"maximum_file_size"`
- }
- var config Config
- type ErrorMessage struct {
- Error string `json:"error"`
- Code int `json:"code"`
- }
- type SuccessMessage struct {
- Delkey string `json:"delkey"`
- }
- func readConfig() Config {
- file, _ := os.Open("server.conf")
- decoder := json.NewDecoder(file)
- config := Config{}
- err := decoder.Decode(&config)
- if err != nil {
- fmt.Println("Error reading config: ", err)
- }
- return config
- }
- func makeDelkey(ident string) string {
- key := []byte(config.DeleteKey)
- h := hmac.New(sha256.New, key)
- h.Write([]byte(ident))
- return hex.EncodeToString(h.Sum(nil))
- }
- func index(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path == "/" {
- http.ServeFile(w, r, "index.html")
- } else {
- http.NotFound(w, r)
- }
- }
- func upload(w http.ResponseWriter, r *http.Request) {
- if r.ContentLength > config.MaxFileSize {
- msg, _ := json.Marshal(&ErrorMessage{Error: "File size too large", Code: 1})
- w.Write(msg)
- return
- }
- r.ParseMultipartForm(50000000)
- file, _, err := r.FormFile("file")
- if err != nil {
- msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 5})
- w.Write(msg)
- return
- }
- defer file.Close()
- privkey := r.FormValue("privkey")
- if privkey != config.StaticKey {
- msg, _ := json.Marshal(&ErrorMessage{Error: "Static key doesn't match", Code: 2})
- w.Write(msg)
- return
- }
- ident := r.FormValue("ident")
- if len(ident) != 22 {
- msg, _ := json.Marshal(&ErrorMessage{Error: "Ident filename length is incorrect", Code: 3})
- w.Write(msg)
- return
- }
- identPath := path.Join("i", ident)
- if _, err := os.Stat(identPath); err == nil {
- msg, _ := json.Marshal(&ErrorMessage{Error: "Ident is already taken.", Code: 4})
- w.Write(msg)
- return
- }
- out, err := os.Create(identPath)
- if err != nil {
- msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 6})
- w.Write(msg)
- return
- }
- defer out.Close()
- _, err = io.Copy(out, file)
- if err != nil {
- msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 7})
- w.Write(msg)
- return
- }
- delkey := makeDelkey(ident)
- result, err := json.Marshal(&SuccessMessage{Delkey: delkey})
- if err != nil {
- msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 8})
- w.Write(msg)
- }
- w.Write(result)
- }
- func delfile(w http.ResponseWriter, r *http.Request) {
- ident := r.FormValue("ident")
- delkey := r.FormValue("delkey")
- if len(ident) != 22 {
- msg, _ := json.Marshal(&ErrorMessage{Error: "Ident filename length is incorrect", Code: 3})
- w.Write(msg)
- return
- }
- identPath := path.Join("i", ident)
- if _, err := os.Stat(identPath); os.IsNotExist(err) {
- msg, _ := json.Marshal(&ErrorMessage{Error: "Ident does not exist.", Code: 9})
- w.Write(msg)
- return
- }
- if delkey != makeDelkey(ident) {
- msg, _ := json.Marshal(&ErrorMessage{Error: "Incorrect delete key", Code: 10})
- w.Write(msg)
- return
- }
- os.Remove(identPath)
- http.Redirect(w, r, "/", 301)
- }
- func main() {
- http.HandleFunc("/", index)
- http.HandleFunc("/up", upload)
- http.HandleFunc("/del", delfile)
- http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("static"))))
- http.Handle("/i/", http.StripPrefix("/i", http.FileServer(http.Dir("i"))))
- config = readConfig()
- fmt.Printf("Listening on %s\n", config.Listen)
- log.Fatal(http.ListenAndServe(config.Listen, nil))
- }
|