1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-16 07:56:24 -07:00

fixed manage login redirect issue in Firefox, uploads (almost) working

This commit is contained in:
Joshua Merrell 2013-06-02 14:04:34 -07:00
parent 71981085bd
commit 64b76018ff
6 changed files with 214 additions and 86 deletions

View file

@ -12,6 +12,7 @@ import (
"time"
)
type ManageFunction struct {
Permissions int // 0 -> non-staff, 1 => janitor, 2 => moderator, 3 => administrator
Callback func() string //return string of html output
@ -231,10 +232,15 @@ var manage_functions = map[string]ManageFunction{
Callback: func() (html string) {
username := request.FormValue("username")
password := request.FormValue("password")
redirect_action := request.FormValue("action")
if redirect_action == "" {
redirect_action = "announcements"
}
fmt.Println(redirect_action)
if username == "" || password == "" {
//assume that they haven't logged in
html = "\t<form method=\"POST\" action=\"/manage?action=login\" class=\"loginbox\">\n" +
"\t\t<input type=\"hidden\" name=\"redirect\" value=\""+redirect_action+"\" />\n" +
"\t\t<input type=\"text\" name=\"username\" class=\"logindata\" /><br />\n" +
"\t\t<input type=\"password\" name=\"password\" class=\"logindata\" /> <br />\n" +
"\t\t<input type=\"submit\" value=\"Login\" />\n" +
@ -242,7 +248,7 @@ var manage_functions = map[string]ManageFunction{
} else {
key := md5_sum(request.RemoteAddr+username+password+config.RandomSeed+generateSalt())[0:10]
createSession(key,username,password,&request,&writer)
redirect(path.Join(config.SiteWebfolder,"/manage?action=announcements"))
redirect(path.Join(config.SiteWebfolder,"/manage?action="+request.FormValue("redirect")))
}
return
}},
@ -436,6 +442,11 @@ var manage_functions = map[string]ManageFunction{
if err != nil {
return err.Error()
}
err = os.Mkdir(path.Join(config.DocumentRoot,dir,"thumb"),0777)
if err != nil {
return err.Error()
}
err = os.Mkdir(path.Join(config.DocumentRoot,dir,"src"),0777)
if err != nil {

View file

@ -3,15 +3,25 @@ package main
import (
"net/http"
"io/ioutil"
"errors"
"fmt"
"image"
"image/jpeg"
"image/gif"
"image/png"
"math/rand"
"os"
"path"
"./lib/resize"
"strconv"
"strings"
"syscall"
"time"
)
var (
UnsupportedFiletypeError = errors.New("Upload filetype not supported")
FileWriteError = errors.New("Couldn't write file.")
)
func generateTripCode(input string) string {
@ -29,7 +39,6 @@ func buildThread(op_post PostTable) (err error) {
board_arr := getBoardArr("")
sections_arr := getSectionArr("")
op_id := strconv.Itoa(op_post.ID)
var board_dir string
for _,board_i := range board_arr {
@ -61,79 +70,109 @@ func buildThread(op_post PostTable) (err error) {
return
}
// checks to see if the poster's tripcode/name is banned, if the IP is banned, or if the file checksum is banned
func checkBannedStatus(post PostTable) bool {
return false
}
func createThumbnail(w http.ResponseWriter, input string, output string) bool {
type ThumbnailPre struct {
Filename_old string
Filename_new string
Filepath string
Width int
Height int
Obj image.Image
ThumbObj image.Image
}
func loadImage(file *os.File) (image.Image,error) {
filetype := file.Name()[len(file.Name())-3:len(file.Name())]
var image_obj image.Image
failed := false
handle,err := os.Open(input)
var err error
if err != nil {
return false
}
defer func() {
if _, ok := recover().(error); ok {
handle.Close()
failed = true
}
}()
if failed {
error_log.Write("Failed to create thumbnail")
return false
}
filetype := input[len(input)-3:len(input)]
if filetype == "gif" {
image_obj,_ = gif.Decode(handle)
image_obj,err = gif.Decode(file)
} else if filetype == "jpeg" || filetype == "jpg" {
image_obj,_ = jpeg.Decode(handle)
image_obj,err = jpeg.Decode(file)
} else if filetype == "png" {
image_obj,_ = png.Decode(handle)
image_obj,err = png.Decode(file)
} else {
exitWithErrorPage(w, "Upload file type not supported")
image_obj = nil
err = UnsupportedFiletypeError
}
return image_obj,err
}
old_rect := image_obj.Bounds()
defer func() {
if _, ok := recover().(error); ok {
//serverError()
exitWithErrorPage(w, "lel, internet")
}
}()
if config.ThumbWidth >= old_rect.Max.X && config.ThumbHeight >= old_rect.Max.Y {
err := syscall.Symlink(input,output)
if err != nil {
error_log.Write(fmt.Sprintf("Error, couldn't create symlink to %s, %s", input, err.Error()))
return false
func saveImage(path string, image_obj *image.Image) error {
outwriter,err := os.OpenFile(path, os.O_RDWR|os.O_CREATE,0777)
if err == nil {
filetype := path[len(path)-4:len(path)]
if filetype == ".gif" {
//because Go doesn't come with a GIF writer :c
jpeg.Encode(outwriter, *image_obj, &jpeg.Options{Quality: 80})
} else if filetype == ".jpg" || filetype == "jpeg" {
jpeg.Encode(outwriter, *image_obj, &jpeg.Options{Quality: 80})
} else if filetype == ".png" {
png.Encode(outwriter, *image_obj)
} else {
return true
return UnsupportedFiletypeError
}
}
return err
}
func createThumbnail(image_obj image.Image, size string) image.Image {
var thumb_width int
var thumb_height int
switch {
case size == "op":
thumb_width = config.ThumbWidth
thumb_height = config.ThumbHeight
case size == "reply":
thumb_width = config.ThumbWidth_reply
thumb_height = config.ThumbHeight_reply
case size == "catalog":
thumb_width = config.ThumbWidth_catalog
thumb_height = config.ThumbHeight_catalog
}
old_rect := image_obj.Bounds()
if thumb_width >= old_rect.Max.X && thumb_height >= old_rect.Max.Y {
return image_obj
}
thumb_w,thumb_h := getThumbnailSize(old_rect.Max.X,old_rect.Max.Y)
image_obj = resize.Resize(image_obj, image.Rect(0,0,old_rect.Max.X,old_rect.Max.Y), thumb_w,thumb_h)
outwriter,_ := os.OpenFile(output, os.O_RDWR|os.O_CREATE,0777)
if filetype == "gif" {
//because Go doesn't come with a GIF writer :c
jpeg.Encode(outwriter, image_obj, &jpeg.Options{Quality: 80})
} else if filetype == "jpg" || filetype == "jpeg" {
jpeg.Encode(outwriter,image_obj, &jpeg.Options{Quality: 80})
} else if filetype == "png" {
png.Encode(outwriter,image_obj)
}
return false
return image_obj
}
//find out what out thumbnail's width and height should be, partially ripped from Kusaba X
func getFiletype(name string) string {
filetype := strings.ToLower(name[len(name)-4:len(name)])
if filetype == ".gif" {
return "gif"
} else if filetype == ".jpg" || filetype == "jpeg" {
return "jpg"
} else if filetype == ".png" {
return "png"
} else {
return name[len(name)-3:len(name)]
}
}
func getNewFilename() string {
now := time.Now().Unix()
rand.Seed(now)
return strconv.Itoa(int(now))+strconv.Itoa(int(rand.Intn(98)+1))
}
// find out what out thumbnail's width and height should be, partially ripped from Kusaba X
func getThumbnailSize(w int, h int) (new_w int, new_h int) {
if w == h {
new_w = config.ThumbWidth
new_h = config.ThumbWidth
} else {
var percent float32
if (w > h) {
percent = float32(config.ThumbWidth) / float32(w)
} else {
@ -141,13 +180,40 @@ func getThumbnailSize(w int, h int) (new_w int, new_h int) {
}
new_w = int(float32(w) * percent)
new_h = int(float32(h) * percent)
//fmt.Printf("Old width: %d\nOld height: %d\nPercent: %f\nWidth: %d\nHeight: %d\n",w,h,percent*100,new_w,new_h)
}
return
}
// inserts prepared post object into the SQL table so that it can be rendered
func insertPost(post PostTable) {
post = sanitizePost(post)
post_sql_str := "INSERT INTO `"+config.DBprefix+"posts` (`boardid`,`parentid`,`name`,`tripcode`,`email`,`subject`,`message`,`password`"
if post.Filename != "" {
post_sql_str += ",`filename`,`filename_original`,`file_checksum`,`filesize`,`image_w`,`image_h`,`thumb_w`,`thumb_h`"
}
post_sql_str += ",`ip`"
post_sql_str += ",`timestamp`,`poster_authority`,`stickied`,`locked`) VALUES("+strconv.Itoa(post.BoardID)+","+strconv.Itoa(post.ParentID)+",'"+post.Name+"','"+post.Tripcode+"','"+post.Email+"','"+post.Subject+"','"+post.Message+"','"+post.Password+"'"
if post.Filename != "" {
post_sql_str += ",'"+post.Filename+"','"+post.FilenameOriginal+"','"+post.FileChecksum+"',"+strconv.Itoa(int(post.Filesize))+","+strconv.Itoa(post.ImageW)+","+strconv.Itoa(post.ImageH)+","+strconv.Itoa(post.ThumbW)+","+strconv.Itoa(post.ThumbH)
}
post_sql_str += ",'"+post.IP+"','"+post.Timestamp+"',"+strconv.Itoa(post.PosterAuthority)+","
if post.Stickied {
post_sql_str += "1,"
} else {
post_sql_str += "0,"
}
if post.Locked {
post_sql_str += "1);"
} else {
post_sql_str += "0);"
}
fmt.Println(post_sql_str)
//_,err := db.Start(post_sql_str)
}
// calls db.Escape() on relevant post members to prevent SQL injection
func sanitizePost(post PostTable) PostTable {
return post
}
func shortenPostForBoardPage(post *string) {
@ -157,33 +223,88 @@ func shortenPostForBoardPage(post *string) {
func makePost(w http.ResponseWriter, r *http.Request) {
request = *r
writer = w
file,handler,err := request.FormFile("file")
/*threadid := db.Escape(request.FormValue("threadid"))
boardid := db.Escape(request.FormValue("boardid"))
postname := db.Escape(request.FormValue("postname"))
postemail := db.Escape(request.FormValue("postemail"))
postmsg := db.Escape(request.FormValue("postmsg"))
imagefile := db.Escape(request.FormValue("imagefile"))*/
request.ParseForm()
var post PostTable
post.IName = "post"
post.ParentID,_ = strconv.Atoi(request.FormValue("threadid"))
post.BoardID,_ = strconv.Atoi(request.FormValue("boardid"))
post.Name = db.Escape(request.FormValue("postname"))
post.Email = db.Escape(request.FormValue("postemail"))
post.Subject = db.Escape(request.FormValue("postsubject"))
post.Message = db.Escape(request.FormValue("postmsg"))
// TODO: change this to a checksum
post.Password = db.Escape(request.FormValue("postpassword"))
post.IP = request.RemoteAddr
post.Timestamp = getSQLDateTime()
post.PosterAuthority = getStaffRank()
post.Bumped = post.Timestamp
post.Stickied = request.FormValue("modstickied") == "on"
post.Locked = request.FormValue("modlocked") == "on"
//post has no referrer, or has a referrer from a different domain, probably a spambot
if request.Referer() == "" || request.Referer()[7:len(config.Domain)+7] != config.Domain {
access_log.Write("Rejected post from possible spambot @ : "+request.RemoteAddr)
//TODO: insert post into temporary post table and add to report list
}
//no file was uploaded
if err != nil {
file,handler,uploaderr := request.FormFile("imagefile")
if uploaderr != nil {
// no file was uploaded
fmt.Println(uploaderr.Error())
post.Filename = ""
access_log.Write("Receiving post from "+request.RemoteAddr+", referred from: "+request.Referer())
} else {
data,err := ioutil.ReadAll(file)
if err != nil {
exitWithErrorPage(w,"Couldn't read file")
} else {
access_log.Write("Receiving post with image: "+handler.Filename+" from "+request.RemoteAddr+", referrer: "+request.Referer())
err = ioutil.WriteFile(handler.Filename, data, 0777)
createThumbnail(w, handler.Filename,"output")
post.FilenameOriginal = handler.Filename
filetype := post.FilenameOriginal[len(post.FilenameOriginal)-3:len(post.FilenameOriginal)]
post.Filename = getNewFilename()+"."+getFiletype(post.FilenameOriginal)
file_path := path.Join(config.DocumentRoot,"/"+getBoardArr("`id` = "+request.FormValue("boardid"))[0].(BoardsTable).Dir+"/src/",post.Filename)
thumb_path := path.Join(config.DocumentRoot,"/"+getBoardArr("`id` = "+request.FormValue("boardid"))[0].(BoardsTable).Dir+"/thumb/",strings.Replace(post.Filename,"."+filetype,"t."+filetype,-1))
err := ioutil.WriteFile(file_path, data, 0777)
if err != nil {
exitWithErrorPage(w,"Couldn't write file")
exitWithErrorPage(w,"Couldn't write file.")
}
image_file,err := os.OpenFile(file_path, os.O_RDONLY, 0)
if err != nil {
exitWithErrorPage(w,"Couldn't read saved file")
}
img,err := loadImage(image_file)
if err != nil {
exitWithErrorPage(w,err.Error())
} else {
//post.FileChecksum string
stat,err := image_file.Stat()
if err != nil {
exitWithErrorPage(w,err.Error())
} else {
post.Filesize = int(stat.Size())
}
post.ThumbW,post.ThumbH = getThumbnailSize(post.ImageW,post.ImageH)
access_log.Write("Receiving post with image: "+handler.Filename+" from "+request.RemoteAddr+", referrer: "+request.Referer())
if config.ThumbWidth >= img.Bounds().Max.X && config.ThumbHeight >= img.Bounds().Max.Y {
err := syscall.Symlink(file_path,thumb_path)
if err != nil {
exitWithErrorPage(w,err.Error())
}
} else {
thumbnail := createThumbnail(img,"op")
err = saveImage(thumb_path, &thumbnail)
if err != nil {
exitWithErrorPage(w,err.Error())
} else {
http.Redirect(writer,&request,"/test/res/1.html",http.StatusFound)
}
}
}
}
}

View file

@ -49,10 +49,6 @@ func fileHandle(w http.ResponseWriter, r *http.Request) {
filepath := path.Join(config.DocumentRoot, request_url)
results,err := os.Stat(filepath)
if !strings.Contains(request.Header.Get("Accept-Encoding"), "gzip") {
}
if err == nil {
//the file exists, or there is a folder here
if results.IsDir() {
@ -96,16 +92,16 @@ func makeHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
}
}
func exitWithErrorPage(err string) {
func exitWithErrorPage(w http.ResponseWriter, err string) {
error_page_bytes,_ := ioutil.ReadFile("templates/error.html")
error_page := string(error_page_bytes)
error_page = strings.Replace(error_page,"{ERRORTEXT}", err,-1)
fmt.Fprintf(writer,error_page)
fmt.Fprintf(w,error_page)
exit_error = true
}
func redirect(location string) {
//http.Redirect(writer,&request,location,http.StatusMovedTemporarily)
http.Redirect(writer,&request,location,http.StatusFound)
}
func error404() {

View file

@ -169,7 +169,7 @@ type PostTable struct {
Filename string
FilenameOriginal string
FileChecksum string
Filesize string
Filesize int
ImageW int
ImageH int
ThumbW int
@ -188,9 +188,9 @@ type PostTable struct {
}
type TempPostTable struct {
ID uint
Boarid uint8
Parentid uint
ID int
Boarid int
Parentid int
Name string
Tripcode string
Email string
@ -200,16 +200,16 @@ type TempPostTable struct {
Filename string
FilenameOriginal string
FileChecksum string
Filesize string
ImageW uint16
ImageH uint16
ThumbW uint16
ThumbH uint16
Filesize int
ImageW int
ImageH int
ThumbW int
ThumbH int
IP string
Tag string
Timestamp string
Autosage uint8
PosterAuthority uint8
Autosage int
PosterAuthority int
DeletedTimestamp string
Bumped string
Stickied bool

View file

@ -138,7 +138,7 @@ func getPostArr(where string) (posts []interface{}) {
post.Filename = string(row[9].([]byte))
post.FilenameOriginal = string(row[10].([]byte))
post.FileChecksum = string(row[11].([]byte))
post.Filesize = string(row[12].([]byte))
post.Filesize,_ = strconv.Atoi(string(row[12].([]byte)))
post.ImageW,_ = strconv.Atoi(string(row[13].([]byte)))
post.ImageH,_ = strconv.Atoi(string(row[14].([]byte)))
post.ThumbW,_ = strconv.Atoi(string(row[15].([]byte)))

View file

@ -44,7 +44,7 @@
<div id="postbox-area">
<center>
<a href="#">Open Quick Reply box</a>
<form name="postform" action="/post" method="POST">
<form name="postform" action="/post" method="POST" enctype="multipart/form-data">
<table id="postbox-static">
<input type="hidden" name="threadid" value="{{$op.ID}}" />
<input type="hidden" name="boardid" value="{{$op.BoardID}}" />