diff --git a/routes/attachments.go b/routes/attachments.go new file mode 100644 index 00000000..2bd2966c --- /dev/null +++ b/routes/attachments.go @@ -0,0 +1,86 @@ +package routes + +import ( + "database/sql" + "net/http" + "path/filepath" + "strconv" + "strings" + + "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/query_gen" +) + +type AttachmentStmts struct { + get *sql.Stmt +} + +var attachmentStmts AttachmentStmts + +// TODO: Abstract this with an attachment store +func init() { + common.DbInits.Add(func(acc *qgen.Accumulator) error { + attachmentStmts = AttachmentStmts{ + get: acc.Select("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path = ? AND sectionID = ? AND sectionTable = ?").Prepare(), + } + return acc.FirstError() + }) +} + +func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, filename string) common.RouteError { + filename = common.Stripslashes(filename) + var ext = filepath.Ext("./attachs/" + filename) + if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) { + return common.LocalError("Bad extension", w, r, user) + } + + sectionID, err := strconv.Atoi(r.FormValue("sectionID")) + if err != nil { + return common.LocalError("The sectionID is not an integer", w, r, user) + } + var sectionTable = r.FormValue("sectionType") + + var originTable string + var originID, uploadedBy int + err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename) + if err == sql.ErrNoRows { + return common.NotFound(w, r, nil) + } else if err != nil { + return common.InternalError(err, w, r) + } + + if sectionTable == "forums" { + _, ferr := common.SimpleForumUserCheck(w, r, &user, sectionID) + if ferr != nil { + return ferr + } + if !user.Perms.ViewTopic { + return common.NoPermissions(w, r, user) + } + } else { + return common.LocalError("Unknown section", w, r, user) + } + + if originTable != "topics" && originTable != "replies" { + return common.LocalError("Unknown origin", w, r, user) + } + + if !user.Loggedin { + w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(common.Year))) + } else { + guest := common.GuestUser + _, ferr := common.SimpleForumUserCheck(w, r, &guest, sectionID) + if ferr != nil { + return ferr + } + if guest.Perms.ViewTopic { + w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(common.Year))) + } else { + w.Header().Set("Cache-Control", "private") + } + } + + // TODO: Fix the problem where non-existent files aren't greeted with custom 404s on ServeFile()'s side + http.ServeFile(w, r, "./attachs/"+filename) + return nil +} diff --git a/routes/misc.go b/routes/misc.go index 560abb28..b2bcdd01 100644 --- a/routes/misc.go +++ b/routes/misc.go @@ -5,14 +5,12 @@ import ( "database/sql" "io" "net/http" - "path/filepath" "strconv" "strings" "time" "github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common/phrases" - "github.com/Azareal/Gosora/query_gen" ) var cacheControlMaxAge = "max-age=" + strconv.Itoa(int(common.Day)) // TODO: Make this a common.Config value @@ -86,80 +84,6 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, header return nil } -type AttachmentStmts struct { - get *sql.Stmt -} - -var attachmentStmts AttachmentStmts - -// TODO: Abstract this with an attachment store -func init() { - common.DbInits.Add(func(acc *qgen.Accumulator) error { - attachmentStmts = AttachmentStmts{ - get: acc.Select("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path = ? AND sectionID = ? AND sectionTable = ?").Prepare(), - } - return acc.FirstError() - }) -} - -func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, filename string) common.RouteError { - filename = common.Stripslashes(filename) - var ext = filepath.Ext("./attachs/" + filename) - if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) { - return common.LocalError("Bad extension", w, r, user) - } - - sectionID, err := strconv.Atoi(r.FormValue("sectionID")) - if err != nil { - return common.LocalError("The sectionID is not an integer", w, r, user) - } - var sectionTable = r.FormValue("sectionType") - - var originTable string - var originID, uploadedBy int - err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename) - if err == sql.ErrNoRows { - return common.NotFound(w, r, nil) - } else if err != nil { - return common.InternalError(err, w, r) - } - - if sectionTable == "forums" { - _, ferr := common.SimpleForumUserCheck(w, r, &user, sectionID) - if ferr != nil { - return ferr - } - if !user.Perms.ViewTopic { - return common.NoPermissions(w, r, user) - } - } else { - return common.LocalError("Unknown section", w, r, user) - } - - if originTable != "topics" && originTable != "replies" { - return common.LocalError("Unknown origin", w, r, user) - } - - if !user.Loggedin { - w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(common.Year))) - } else { - guest := common.GuestUser - _, ferr := common.SimpleForumUserCheck(w, r, &guest, sectionID) - if ferr != nil { - return ferr - } - if guest.Perms.ViewTopic { - w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(common.Year))) - } else { - w.Header().Set("Cache-Control", "private") - } - } - - // TODO: Fix the problem where non-existent files aren't greeted with custom 404s on ServeFile()'s side - http.ServeFile(w, r, "./attachs/"+filename) - return nil -} - // TODO: Set the cookie domain func ChangeTheme(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { //headerLite, _ := SimpleUserCheck(w, r, &user)