server.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package main
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "encoding/hex"
  6. "encoding/json"
  7. "fmt"
  8. "io"
  9. "log"
  10. "net/http"
  11. "os"
  12. "path"
  13. )
  14. type Config struct {
  15. Listen string `json:"listen"`
  16. StaticKey string `json:"static_key"`
  17. DeleteKey string `json:"static_delete_key"`
  18. MaxFileSize int64 `json:"maximum_file_size"`
  19. }
  20. var config Config
  21. type ErrorMessage struct {
  22. Error string `json:"error"`
  23. Code int `json:"code"`
  24. }
  25. type SuccessMessage struct {
  26. Delkey string `json:"delkey"`
  27. }
  28. func readConfig() Config {
  29. file, _ := os.Open("server.conf")
  30. decoder := json.NewDecoder(file)
  31. config := Config{}
  32. err := decoder.Decode(&config)
  33. if err != nil {
  34. fmt.Println("Error reading config: ", err)
  35. }
  36. return config
  37. }
  38. func makeDelkey(ident string) string {
  39. key := []byte(config.DeleteKey)
  40. h := hmac.New(sha256.New, key)
  41. h.Write([]byte(ident))
  42. return hex.EncodeToString(h.Sum(nil))
  43. }
  44. func index(w http.ResponseWriter, r *http.Request) {
  45. if r.URL.Path == "/" {
  46. http.ServeFile(w, r, "index.html")
  47. } else {
  48. http.NotFound(w, r)
  49. }
  50. }
  51. func upload(w http.ResponseWriter, r *http.Request) {
  52. if r.ContentLength > config.MaxFileSize {
  53. msg, _ := json.Marshal(&ErrorMessage{Error: "File size too large", Code: 1})
  54. w.Write(msg)
  55. return
  56. }
  57. r.ParseMultipartForm(50000000)
  58. file, _, err := r.FormFile("file")
  59. if err != nil {
  60. msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 5})
  61. w.Write(msg)
  62. return
  63. }
  64. defer file.Close()
  65. privkey := r.FormValue("privkey")
  66. if privkey != config.StaticKey {
  67. msg, _ := json.Marshal(&ErrorMessage{Error: "Static key doesn't match", Code: 2})
  68. w.Write(msg)
  69. return
  70. }
  71. ident := r.FormValue("ident")
  72. if len(ident) != 22 {
  73. msg, _ := json.Marshal(&ErrorMessage{Error: "Ident filename length is incorrect", Code: 3})
  74. w.Write(msg)
  75. return
  76. }
  77. identPath := path.Join("i", ident)
  78. if _, err := os.Stat(identPath); err == nil {
  79. msg, _ := json.Marshal(&ErrorMessage{Error: "Ident is already taken.", Code: 4})
  80. w.Write(msg)
  81. return
  82. }
  83. out, err := os.Create(identPath)
  84. if err != nil {
  85. msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 6})
  86. w.Write(msg)
  87. return
  88. }
  89. defer out.Close()
  90. _, err = io.Copy(out, file)
  91. if err != nil {
  92. msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 7})
  93. w.Write(msg)
  94. return
  95. }
  96. delkey := makeDelkey(ident)
  97. result, err := json.Marshal(&SuccessMessage{Delkey: delkey})
  98. if err != nil {
  99. msg, _ := json.Marshal(&ErrorMessage{Error: err.Error(), Code: 8})
  100. w.Write(msg)
  101. }
  102. w.Write(result)
  103. }
  104. func delfile(w http.ResponseWriter, r *http.Request) {
  105. ident := r.FormValue("ident")
  106. delkey := r.FormValue("delkey")
  107. if len(ident) != 22 {
  108. msg, _ := json.Marshal(&ErrorMessage{Error: "Ident filename length is incorrect", Code: 3})
  109. w.Write(msg)
  110. return
  111. }
  112. identPath := path.Join("i", ident)
  113. if _, err := os.Stat(identPath); os.IsNotExist(err) {
  114. msg, _ := json.Marshal(&ErrorMessage{Error: "Ident does not exist.", Code: 9})
  115. w.Write(msg)
  116. return
  117. }
  118. if delkey != makeDelkey(ident) {
  119. msg, _ := json.Marshal(&ErrorMessage{Error: "Incorrect delete key", Code: 10})
  120. w.Write(msg)
  121. return
  122. }
  123. os.Remove(identPath)
  124. http.Redirect(w, r, "/", 301)
  125. }
  126. func main() {
  127. http.HandleFunc("/", index)
  128. http.HandleFunc("/up", upload)
  129. http.HandleFunc("/del", delfile)
  130. http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("static"))))
  131. http.Handle("/i/", http.StripPrefix("/i", http.FileServer(http.Dir("i"))))
  132. config = readConfig()
  133. fmt.Printf("Listening on %s\n", config.Listen)
  134. log.Fatal(http.ListenAndServe(config.Listen, nil))
  135. }