diff --git a/.gitignore b/.gitignore index 580d0deb..dbc49e4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -src/uploads/* +uploads/* bin/* \ No newline at end of file diff --git a/README.md b/README.md index 35f5632e..f3b8fb54 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Set the password column of your user account in the database to what you want yo # Run the program -go run errors.go main.go pages.go reply.go routes.go topic.go user.go utils.go forum.go group.go config.go +go run errors.go main.go pages.go reply.go routes.go topic.go user.go utils.go forum.go group.go files.go config.go Alternatively, you could run the run.bat batch file on Windows. @@ -64,5 +64,3 @@ Revamp the system for serving static files to make it much faster. Tweak the CSS to make it responsive. Add a forum cache. - -Cache the static files in memory. diff --git a/build.bat b/build.bat new file mode 100644 index 00000000..363fa9f1 --- /dev/null +++ b/build.bat @@ -0,0 +1 @@ +go build \ No newline at end of file diff --git a/src/config.go b/config.go similarity index 100% rename from src/config.go rename to config.go diff --git a/src/data.sql b/data.sql similarity index 100% rename from src/data.sql rename to data.sql diff --git a/src/errors.go b/errors.go similarity index 87% rename from src/errors.go rename to errors.go index c0d12ad7..a66c7082 100644 --- a/src/errors.go +++ b/errors.go @@ -39,8 +39,7 @@ func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User } func LoginRequired(w http.ResponseWriter, r *http.Request, user User) { - errmsg := "You need to login to do that." - pi := Page{"Local Error","error",user,tList,errmsg} + pi := Page{"Local Error","error",user,tList,"You need to login to do that."} var b bytes.Buffer templates.ExecuteTemplate(&b,"error.html", pi) @@ -87,8 +86,7 @@ func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user User, is_js s } func Banned(w http.ResponseWriter, r *http.Request, user User) { - errmsg := "You have been banned, thus you do not permission to do that." - pi := Page{"Local Error","error",user,tList,errmsg} + pi := Page{"Banned","error",user,tList,"You have been banned from this site."} var b bytes.Buffer templates.ExecuteTemplate(&b,"error.html", pi) errpage := b.String() @@ -97,30 +95,28 @@ func Banned(w http.ResponseWriter, r *http.Request, user User) { } func BannedJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) { - errmsg := "You have been banned from this site." if is_js == "0" { - pi := Page{"Local Error","error",user,tList,errmsg} + pi := Page{"Banned","error",user,tList,"You have been banned from this site."} var b bytes.Buffer templates.ExecuteTemplate(&b,"error.html", pi) errpage := b.String() w.WriteHeader(403) fmt.Fprintln(w,errpage) } else { - http.Error(w,"{'errmsg': '" + errmsg + "'}",403) + http.Error(w,"{'errmsg': 'You have been banned from this site.'}",403) } } func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) { - errmsg := "You need to login to do that." if is_js == "0" { - pi := Page{"Local Error","error",user,tList,errmsg} + pi := Page{"Local Error","error",user,tList,"You need to login to do that."} var b bytes.Buffer templates.ExecuteTemplate(&b,"error.html", pi) errpage := b.String() w.WriteHeader(401) fmt.Fprintln(w,errpage) } else { - http.Error(w,"{'errmsg': '" + errmsg + "'}",401) + http.Error(w,"{'errmsg': 'You need to login to do that.'}",401) } } diff --git a/files.go b/files.go new file mode 100644 index 00000000..519f4f14 --- /dev/null +++ b/files.go @@ -0,0 +1,51 @@ +package main +import "io" +import "os" +import "errors" + +type SFile struct +{ + Data []byte + Pos int64 + Length int64 + Mimetype string + Info os.FileInfo + FormattedModTime string +} + +func (r SFile) Read(b []byte) (n int, err error) { + n = 0 + if r.Pos > r.Length { + return n, io.EOF + } + + size := cap(b) + if size > 0 { + for n < size { + b[n] = r.Data[r.Pos] + n++ + if r.Pos == r.Length { + break + } + r.Pos++ + } + } + return n, nil +} + +func (r SFile) Seek(offset int64, whence int) (int64, error) { + if offset < 0 { + return 0, errors.New("negative position") + } + switch whence { + case 0: + r.Pos = offset + case 1: + r.Pos += offset + case 2: + r.Pos = r.Length + offset + default: + return 0, errors.New("invalid whence") + } + return r.Pos, nil +} \ No newline at end of file diff --git a/src/forum.go b/forum.go similarity index 100% rename from src/forum.go rename to forum.go diff --git a/grosolo.exe b/grosolo.exe new file mode 100644 index 00000000..216a9b3f Binary files /dev/null and b/grosolo.exe differ diff --git a/src/group.go b/group.go similarity index 100% rename from src/group.go rename to group.go diff --git a/src/main.go b/main.go similarity index 91% rename from src/main.go rename to main.go index b89576a8..3ec3dca6 100644 --- a/src/main.go +++ b/main.go @@ -5,7 +5,9 @@ import ( "database/sql" _ "github.com/go-sql-driver/mysql" "log" + "mime" "path/filepath" + "io/ioutil" "html/template" ) @@ -46,6 +48,7 @@ var templates = template.Must(template.ParseGlob("templates/*")) var no_css_tmpl = template.CSS("") var staff_css_tmpl = template.CSS(staff_css) var groups map[int]Group = make(map[int]Group) +var static_files map[string]SFile = make(map[string]SFile) func init_database(err error) { if(dbpassword != ""){ @@ -216,9 +219,30 @@ func main(){ log.Fatal(err) } + log.Print("Loading the static files.") + files, err := ioutil.ReadDir("./public") + if err != nil { + log.Fatal(err) + } + + for _, f := range files { + if f.IsDir() { + continue + } + data, err := ioutil.ReadFile("./public/" + f.Name()) + if err != nil { + log.Fatal(err) + } + + log.Print("Added the '" + f.Name() + "' static file.") + static_files["/static/" + f.Name()] = SFile{data,0,int64(len(data)),mime.TypeByExtension(filepath.Ext(f.Name())),f,f.ModTime().UTC().Format(http.TimeFormat)} + } + // In a directory to stop it clashing with the other paths - fs_p := http.FileServer(http.Dir("./public")) - http.Handle("/static/", http.StripPrefix("/static/",fs_p)) + http.HandleFunc("/static/", route_static) + //http.HandleFunc("/static/", route_fstatic) + //fs_p := http.FileServer(http.Dir("./public")) + //http.Handle("/static/", http.StripPrefix("/static/",fs_p)) fs_u := http.FileServer(http.Dir("./uploads")) http.Handle("/uploads/", http.StripPrefix("/uploads/",fs_u)) diff --git a/src/pages.go b/pages.go similarity index 90% rename from src/pages.go rename to pages.go index 7b2b6af3..365ca4d9 100644 --- a/src/pages.go +++ b/pages.go @@ -14,6 +14,13 @@ type Page struct Something interface{} } +type PageSimple struct +{ + Title string + Name string + Something interface{} +} + func add_custom_page(path string, f os.FileInfo, err error) error { if err != nil { return err diff --git a/src/pages/test.html b/pages/test.html similarity index 100% rename from src/pages/test.html rename to pages/test.html diff --git a/src/public/global.js b/public/global.js similarity index 100% rename from src/public/global.js rename to public/global.js diff --git a/src/public/jquery-1.12.3.min.js b/public/jquery-1.12.3.min.js similarity index 100% rename from src/public/jquery-1.12.3.min.js rename to public/jquery-1.12.3.min.js diff --git a/src/public/main.css b/public/main.css similarity index 100% rename from src/public/main.css rename to public/main.css diff --git a/src/public/white-dot.jpg b/public/white-dot.jpg similarity index 100% rename from src/public/white-dot.jpg rename to public/white-dot.jpg diff --git a/src/reply.go b/reply.go similarity index 100% rename from src/reply.go rename to reply.go diff --git a/src/routes.go b/routes.go similarity index 96% rename from src/routes.go rename to routes.go index 12b9101d..99c27d35 100644 --- a/src/routes.go +++ b/routes.go @@ -6,6 +6,7 @@ import "strconv" import "bytes" import "regexp" import "strings" +import "time" import "io" import "os" import "net/http" @@ -19,6 +20,26 @@ import "golang.org/x/crypto/bcrypt" var tList map[int]interface{} // GET functions +func route_static(w http.ResponseWriter, r *http.Request){ + //name := r.URL.Path[len("/static/"):] + if t, err := time.Parse(http.TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && static_files[r.URL.Path].Info.ModTime().Before(t.Add(1*time.Second)) { + w.WriteHeader(http.StatusNotModified) + return + } + h := w.Header() + h.Set("Last-Modified", static_files[r.URL.Path].FormattedModTime) + h.Set("Content-Type", static_files[r.URL.Path].Mimetype) + h.Set("Content-Length", strconv.FormatInt(static_files[r.URL.Path].Length, 10)) + //http.ServeContent(w,r,r.URL.Path,static_files[r.URL.Path].Info.ModTime(),static_files[r.URL.Path]) + //w.Write(static_files[r.URL.Path].Data) + io.Copy(w, bytes.NewReader(static_files[r.URL.Path].Data)) + //io.CopyN(w, bytes.NewReader(static_files[r.URL.Path].Data), static_files[r.URL.Path].Length) +} + +func route_fstatic(w http.ResponseWriter, r *http.Request){ + http.ServeFile(w, r, r.URL.Path) +} + func route_overview(w http.ResponseWriter, r *http.Request){ user := SessionCheck(w,r) pi := Page{"Overview","overview",user,tList,0} @@ -1206,8 +1227,7 @@ func route_panel_forums(w http.ResponseWriter, r *http.Request){ return } - var forumList map[int]interface{} - forumList = make(map[int]interface{}) + var forumList map[int]interface{} = make(map[int]interface{}) currentID := 0 rows, err := db.Query("select fid, name from forums") diff --git a/run.bat b/run.bat new file mode 100644 index 00000000..97bf2c4c --- /dev/null +++ b/run.bat @@ -0,0 +1,3 @@ +go build +grosolo.exe +pause \ No newline at end of file diff --git a/src/run.bat b/src/run.bat deleted file mode 100644 index 0d459ee8..00000000 --- a/src/run.bat +++ /dev/null @@ -1,2 +0,0 @@ -go run errors.go main.go pages.go reply.go routes.go topic.go user.go utils.go config.go forum.go group.go -pause \ No newline at end of file diff --git a/src/templates/account-own-edit-avatar-success.html b/templates/account-own-edit-avatar-success.html similarity index 100% rename from src/templates/account-own-edit-avatar-success.html rename to templates/account-own-edit-avatar-success.html diff --git a/src/templates/account-own-edit-avatar.html b/templates/account-own-edit-avatar.html similarity index 100% rename from src/templates/account-own-edit-avatar.html rename to templates/account-own-edit-avatar.html diff --git a/src/templates/account-own-edit-success.html b/templates/account-own-edit-success.html similarity index 100% rename from src/templates/account-own-edit-success.html rename to templates/account-own-edit-success.html diff --git a/src/templates/account-own-edit-username.html b/templates/account-own-edit-username.html similarity index 100% rename from src/templates/account-own-edit-username.html rename to templates/account-own-edit-username.html diff --git a/src/templates/account-own-edit.html b/templates/account-own-edit.html similarity index 100% rename from src/templates/account-own-edit.html rename to templates/account-own-edit.html diff --git a/src/templates/create-topic.html b/templates/create-topic.html similarity index 100% rename from src/templates/create-topic.html rename to templates/create-topic.html diff --git a/src/templates/custom_page.html b/templates/custom_page.html similarity index 100% rename from src/templates/custom_page.html rename to templates/custom_page.html diff --git a/src/templates/edit-topic.html b/templates/edit-topic.html similarity index 100% rename from src/templates/edit-topic.html rename to templates/edit-topic.html diff --git a/src/templates/error.html b/templates/error.html similarity index 100% rename from src/templates/error.html rename to templates/error.html diff --git a/src/templates/footer.html b/templates/footer.html similarity index 100% rename from src/templates/footer.html rename to templates/footer.html diff --git a/src/templates/forum.html b/templates/forum.html similarity index 100% rename from src/templates/forum.html rename to templates/forum.html diff --git a/src/templates/forums.html b/templates/forums.html similarity index 100% rename from src/templates/forums.html rename to templates/forums.html diff --git a/src/templates/header.html b/templates/header.html similarity index 100% rename from src/templates/header.html rename to templates/header.html diff --git a/src/templates/login.html b/templates/login.html similarity index 100% rename from src/templates/login.html rename to templates/login.html diff --git a/src/templates/menu.html b/templates/menu.html similarity index 100% rename from src/templates/menu.html rename to templates/menu.html diff --git a/src/templates/overview.html b/templates/overview.html similarity index 100% rename from src/templates/overview.html rename to templates/overview.html diff --git a/src/templates/page.html b/templates/page.html similarity index 100% rename from src/templates/page.html rename to templates/page.html diff --git a/src/templates/panel-forums.html b/templates/panel-forums.html similarity index 100% rename from src/templates/panel-forums.html rename to templates/panel-forums.html diff --git a/src/templates/register.html b/templates/register.html similarity index 100% rename from src/templates/register.html rename to templates/register.html diff --git a/src/templates/topic.html b/templates/topic.html similarity index 100% rename from src/templates/topic.html rename to templates/topic.html diff --git a/src/templates/topics.html b/templates/topics.html similarity index 100% rename from src/templates/topics.html rename to templates/topics.html diff --git a/src/topic.go b/topic.go similarity index 100% rename from src/topic.go rename to topic.go diff --git a/src/user.go b/user.go similarity index 100% rename from src/user.go rename to user.go diff --git a/src/utils.go b/utils.go similarity index 100% rename from src/utils.go rename to utils.go