// View handles the file views func View(c *gin.Context) { var err error id := c.Param("uniuri") re := models.Resource{} if err = re.Get(id); err != nil || re.Key == "" { logger.InfoC(c, "server", "Not found", id) c.AbortWithStatus(http.StatusNotFound) return } re.LogFetched(c) f, err := os.Open(path.Join(conf.C.UploadDir, re.Key)) if err != nil { logger.ErrC(c, "server", fmt.Sprintf("Couldn't open %s", re.Key), err) c.AbortWithStatus(http.StatusInternalServerError) return } if conf.C.AlwaysDownload { c.Header("Content-Type", "application/octet-stream") } c.Header("Content-Disposition", "filename=\""+re.Name+"\"") io.Copy(c.Writer, f) if re.Once { re.Delete() re.LogDeleted(c) } }
// LogDeleted logs when a file is deleted (due to a one-time view) func (r Resource) LogDeleted(c *gin.Context) { e := fmt.Sprintf("%sDeleted%s %s - %s", logger.Red, logger.Reset, r.Key, utils.HumanBytes(uint64(r.Size))) if r.Once { e += " - once" } logger.InfoC(c, "server", e) }
// Index handles the main page func Index(c *gin.Context) { logger.InfoC(c, "server", "GET /") data := gin.H{ "fulldoc": conf.C.FullDoc, "size_limit": utils.HumanBytes(uint64(conf.C.SizeLimit * utils.MegaByte)), "sensitive_mode": conf.C.SensitiveMode, } if conf.C.Stats { data["total_size"] = utils.HumanBytes(models.S.TotalSize) data["total_files"] = models.S.TotalFiles } c.HTML(http.StatusOK, "index.html", data) }
// HeadC handles the head request for an encryptd file func HeadC(c *gin.Context) { var err error id := c.Param("uniuri") key := c.Param("key") re := models.Resource{} if err = re.Get(id); err != nil { logger.InfoC(c, "server", "Not found", id) c.AbortWithStatus(http.StatusNotFound) return } if re.Key == "" { logger.InfoC(c, "server", "Not found", id) c.AbortWithStatus(http.StatusNotFound) return } logger.InfoC(c, "server", "Head", fmt.Sprintf("%s - %s", re.Key, utils.HumanBytes(uint64(re.Size)))) f, err := os.Open(path.Join(conf.C.UploadDir, re.Key)) if err != nil { logger.ErrC(c, "server", fmt.Sprintf("Couldn't open %s", re.Key), err) c.AbortWithStatus(http.StatusInternalServerError) return } block, err := aes.NewCipher([]byte(key)) if err != nil { logger.ErrC(c, "server", "Couldn't create AES cipher", err) c.String(http.StatusInternalServerError, "Something went wrong on the server. Try again later.") c.AbortWithStatus(http.StatusInternalServerError) return } var iv [aes.BlockSize]byte stream := cipher.NewCFBDecrypter(block, iv[:]) reader := &cipher.StreamReader{S: stream, R: f} c.Header("Content-Disposition", "filename=\""+re.Name+"\"") io.Copy(c.Writer, reader) }
// ViewC handles the file views for encrypted files func ViewC(c *gin.Context) { var err error id := c.Param("uniuri") key := c.Param("key") re := models.Resource{} if err = re.Get(id); err != nil || re.Key == "" { logger.InfoC(c, "server", "Not found", id) c.AbortWithStatus(http.StatusNotFound) return } re.LogFetched(c) f, err := os.Open(path.Join(conf.C.UploadDir, re.Key)) if err != nil { logger.ErrC(c, "server", fmt.Sprintf("Couldn't open %s", re.Key), err) c.AbortWithStatus(http.StatusInternalServerError) return } block, err := aes.NewCipher([]byte(key)) if err != nil { logger.ErrC(c, "server", "Couldn't create AES cipher", err) c.String(http.StatusInternalServerError, "Something went wrong on the server. Try again later.") c.AbortWithStatus(http.StatusInternalServerError) return } var iv [aes.BlockSize]byte stream := cipher.NewCFBDecrypter(block, iv[:]) reader := &cipher.StreamReader{S: stream, R: f} if conf.C.AlwaysDownload { c.Header("Content-Type", "application/octet-stream") } c.Header("Content-Disposition", "filename=\""+re.Name+"\"") io.Copy(c.Writer, reader) if re.Once { re.Delete() re.LogDeleted(c) } }