package handlers import ( "archive/zip" "encoding/json" "fmt" "lash" "lash/internal/errx" "net/http" "strconv" ) type FileHandler struct { Ctx *lash.LashContext FileData []FileData } type FileData struct { Contents []byte FileName string } type ValidateRequest struct { Token string } var sent int = 0 func (h FileHandler) APIHandler(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var t ValidateRequest err := decoder.Decode(&t) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if t.Token != lash.Token { http.Error(w, "Invalid Token", http.StatusUnauthorized) return } http.Redirect(w, r, fmt.Sprintf("/%s", lash.ShareLinkToken), http.StatusTemporaryRedirect) } func (h FileHandler) FileHandler(w http.ResponseWriter, r *http.Request) { if sent >= h.Ctx.N && h.Ctx.N != -1 { http.Error(w, "Too many requests", http.StatusTooManyRequests) return } filename := h.FileData[0].FileName if len(h.FileData) > 1 { filename = "lash.zip" } w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) w.Header().Set("Content-Type", "application/octet-stream") if len(h.FileData) == 1 { w.Header().Set("Content-Length", strconv.Itoa(len(h.FileData[0].Contents))) w.WriteHeader(http.StatusOK) _, _ = w.Write(h.FileData[0].Contents) } else { w.WriteHeader(http.StatusOK) zw := zip.NewWriter(w) defer zw.Close() for _, f := range h.FileData { fw, err := zw.Create(f.FileName) if err != nil { errx.FatalPerror(err) } _, err = fw.Write(f.Contents) if err != nil { errx.FatalPerror(err) } } } sent++ }