Static files are now served from memory. This feature's a little experimental, so it will need a lot of testing i.i

Added an executable file. Only works on Windows, if it doesn't work, then try building it for yourself with build.bat or go build
Tweaked run.bat to make it more firewall friendly. It now generates an executable.
Moved the files around to make it more organised.
Added build.bat which you can use to build the program for you and install the libraries the software depends on.
This commit is contained in:
Azareal 2016-12-05 07:21:17 +00:00
parent dc77c43996
commit 689b1a804b
45 changed files with 118 additions and 20 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
src/uploads/*
uploads/*
bin/*

View File

@ -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.

1
build.bat Normal file
View File

@ -0,0 +1 @@
go build

View File

@ -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)
}
}

51
files.go Normal file
View File

@ -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
}

BIN
grosolo.exe Normal file

Binary file not shown.

View File

@ -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))

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 539 B

View File

@ -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")

3
run.bat Normal file
View File

@ -0,0 +1,3 @@
go build
grosolo.exe
pause

View File

@ -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