package helpers import ( "fmt" "net/http" "os" "strconv" "time" "github.com/labstack/echo" ) func SendSong(ctx echo.Context, Filename string) error { fmt.Println("Client requests: " + Filename) //Check if file exists and open openFile, err := os.Open(Filename) if err != nil { //File not found, send 404 //http.Error(ctx.Writer, "Song not found.", 404) return ctx.String(http.StatusNotFound, "Song not found.") } defer func(openFile *os.File) { _ = openFile.Close() }(openFile) //Close after function return //File is found, create and send the correct headers //Get the Content-Type of the file //Create a buffer to store the header of the file in FileHeader := make([]byte, 512) //Copy the headers into the FileHeader buffer _, _ = openFile.Read(FileHeader) //Get content type of file //FileContentType := http.DetectContentType(FileHeader) //Get the file size FileStat, _ := openFile.Stat() //Get info from file FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string //Send the headers //writer.Header().Set("Content-Disposition", "attachment; filename="+Filename) ctx.Response().Header().Set("Content-Type", "audio/mpeg") ctx.Response().Header().Set("Content-Length", FileSize) ctx.Response().Header().Set("Expires", "Tue, 03 Jul 2001 06:00:00 GMT") ctx.Response().Header().Set("Last-Modified", time.Now().String()+" GMT") ctx.Response().Header().Set("Cache-Control", "no-cache, no-store, private, max-age=0") ctx.Response().Header().Set("Pragma", "no-cache") ctx.Response().Header().Set("X-Accel-Expires", "0") var etagHeaders = []string{ "ETag", "If-Modified-Since", "If-Match", "If-None-Match", "If-Range", "If-Unmodified-Since", } for _, v := range etagHeaders { if ctx.Request().Header.Get(v) != "" { ctx.Request().Header.Del(v) } } //Send the file //We read 512 bytes from the file already, so we reset the offset back to 0 _, _ = openFile.Seek(0, 0) //_, _ = io.Copy(ctx.Writer, openFile) //'Copy' the file to the client return ctx.Stream(http.StatusOK, "audio/mpeg", openFile) }