Performance improvements, custom 404+500, -nologs, PUT uploads fix

This commit is contained in:
andreimarcu 2015-09-25 12:00:14 -04:00
parent b617d99746
commit d98b63e8bd
9 changed files with 65 additions and 20 deletions

View File

@ -11,36 +11,40 @@ import (
"github.com/zenazn/goji/web" "github.com/zenazn/goji/web"
) )
var imageTpl = pongo2.Must(pongo2.FromCache("templates/display/image.html"))
var videoTpl = pongo2.Must(pongo2.FromCache("templates/display/video.html"))
var fileTpl = pongo2.Must(pongo2.FromCache("templates/display/file.html"))
func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) { func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) {
fileName := c.URLParams["name"] fileName := c.URLParams["name"]
filePath := path.Join(Config.filesDir, fileName) filePath := path.Join(Config.filesDir, fileName)
fileInfo, err := os.Stat(filePath) fileInfo, err := os.Stat(filePath)
if os.IsNotExist(err) { if os.IsNotExist(err) {
http.Error(w, http.StatusText(404), 404) notFoundHandler(c, w, r)
return return
} }
if err := magicmime.Open(magicmime.MAGIC_MIME_TYPE | if err := magicmime.Open(magicmime.MAGIC_MIME_TYPE |
magicmime.MAGIC_SYMLINK | magicmime.MAGIC_SYMLINK |
magicmime.MAGIC_ERROR); err != nil { magicmime.MAGIC_ERROR); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) oopsHandler(c, w, r)
} }
defer magicmime.Close() defer magicmime.Close()
mimetype, err := magicmime.TypeByFile(filePath) mimetype, err := magicmime.TypeByFile(filePath)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) oopsHandler(c, w, r)
} }
var tpl *pongo2.Template var tpl *pongo2.Template
if strings.HasPrefix(mimetype, "image/") { if strings.HasPrefix(mimetype, "image/") {
tpl = pongo2.Must(pongo2.FromCache("templates/display/image.html")) tpl = imageTpl
} else if strings.HasPrefix(mimetype, "video/") { } else if strings.HasPrefix(mimetype, "video/") {
tpl = pongo2.Must(pongo2.FromCache("templates/display/video.html")) tpl = videoTpl
} else { } else {
tpl = pongo2.Must(pongo2.FromCache("templates/display/file.html")) tpl = fileTpl
} }
err = tpl.ExecuteWriter(pongo2.Context{ err = tpl.ExecuteWriter(pongo2.Context{
@ -50,6 +54,6 @@ func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) {
}, w) }, w)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) oopsHandler(c, w, r)
} }
} }

View File

@ -14,7 +14,7 @@ func fileServeHandler(c web.C, w http.ResponseWriter, r *http.Request) {
_, err := os.Stat(filePath) _, err := os.Stat(filePath)
if os.IsNotExist(err) { if os.IsNotExist(err) {
http.Error(w, http.StatusText(404), 404) notFoundHandler(c, w, r)
return return
} }

View File

@ -7,11 +7,28 @@ import (
"github.com/zenazn/goji/web" "github.com/zenazn/goji/web"
) )
func indexHandler(c web.C, w http.ResponseWriter, r *http.Request) { var indexTpl = pongo2.Must(pongo2.FromCache("templates/index.html"))
indexTpl := pongo2.Must(pongo2.FromCache("templates/index.html")) var notFoundTpl = pongo2.Must(pongo2.FromCache("templates/404.html"))
var oopsTpl = pongo2.Must(pongo2.FromCache("templates/oops.html"))
func indexHandler(c web.C, w http.ResponseWriter, r *http.Request) {
err := indexTpl.ExecuteWriter(pongo2.Context{}, w) err := indexTpl.ExecuteWriter(pongo2.Context{}, w)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }
func notFoundHandler(c web.C, w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
err := notFoundTpl.ExecuteWriter(pongo2.Context{}, w)
if err != nil {
oopsHandler(c, w, r)
}
}
func oopsHandler(c web.C, w http.ResponseWriter, r *http.Request) {
err := oopsTpl.ExecuteWriter(pongo2.Context{}, w)
if err != nil {
oopsHandler(c, w, r)
}
}

View File

@ -9,11 +9,13 @@ import (
"github.com/flosch/pongo2" "github.com/flosch/pongo2"
"github.com/zenazn/goji" "github.com/zenazn/goji"
"github.com/zenazn/goji/web/middleware"
) )
var Config struct { var Config struct {
bind string bind string
filesDir string filesDir string
noLogs bool
siteName string siteName string
siteURL string siteURL string
} }
@ -23,14 +25,17 @@ func main() {
"host to bind to (default: 127.0.0.1:8080)") "host to bind to (default: 127.0.0.1:8080)")
flag.StringVar(&Config.filesDir, "filespath", "files/", flag.StringVar(&Config.filesDir, "filespath", "files/",
"path to files directory (default: files/)") "path to files directory (default: files/)")
flag.BoolVar(&Config.noLogs, "nologs", false,
"remove stdout output for each request")
flag.StringVar(&Config.siteName, "sitename", "linx", flag.StringVar(&Config.siteName, "sitename", "linx",
"name of the site") "name of the site")
flag.StringVar(&Config.siteURL, "siteurl", "http://"+Config.bind+"/", flag.StringVar(&Config.siteURL, "siteurl", "http://"+Config.bind+"/",
"site base url (including trailing slash)") "site base url (including trailing slash)")
flag.Parse() flag.Parse()
// Disable template caching -- keep until out of pre-alpha if Config.noLogs {
pongo2.DefaultSet.Debug = true // will keep this until out of pre-alpha goji.Abandon(middleware.Logger)
}
// Template Globals // Template Globals
pongo2.DefaultSet.Globals["sitename"] = Config.siteName pongo2.DefaultSet.Globals["sitename"] = Config.siteName
@ -40,12 +45,17 @@ func main() {
selifRe := regexp.MustCompile(`^/selif/(?P<name>[a-z0-9-\.]+)$`) selifRe := regexp.MustCompile(`^/selif/(?P<name>[a-z0-9-\.]+)$`)
goji.Get("/", indexHandler) goji.Get("/", indexHandler)
goji.Post("/upload", uploadPostHandler) goji.Post("/upload", uploadPostHandler)
goji.Post("/upload/", http.RedirectHandler("/upload", 301))
goji.Put("/upload", uploadPutHandler) goji.Put("/upload", uploadPutHandler)
goji.Put("/upload/:name", uploadPutHandler)
goji.Get("/static/*", http.StripPrefix("/static/", goji.Get("/static/*", http.StripPrefix("/static/",
http.FileServer(http.Dir("static/")))) http.FileServer(http.Dir("static/"))))
goji.Get(nameRe, fileDisplayHandler) goji.Get(nameRe, fileDisplayHandler)
goji.Get(selifRe, fileServeHandler) goji.Get(selifRe, fileServeHandler)
goji.NotFound(notFoundHandler)
listener, err := net.Listen("tcp", Config.bind) listener, err := net.Listen("tcp", Config.bind)
if err != nil { if err != nil {

BIN
static/images/404.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

5
templates/404.html Normal file
View File

@ -0,0 +1,5 @@
{% extends "base.html" %}
{% block content %}
<a href="/"><img style="border:0;" src='/static/images/404.jpg' width='400'></a>
{% endblock %}

View File

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block main %} {% block main %}
<div class="normal"> <div class="normal" style="width: 500px;">
<p class="center">You are requesting <a href="/selif/{{ filename }}">{{ filename }}</a>, <a href="/selif/{{ filename }}">>click here</a> to download.</p> <p class="center">You are requesting <a href="/selif/{{ filename }}">{{ filename }}</a>, <a href="/selif/{{ filename }}">click here</a> to download.</p>
</div> </div>
{% endblock %} {% endblock %}

10
templates/oops.html Normal file
View File

@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block content %}
<div id="main">
<div id='inner_content' style='width: 400px'>
<p>{{ error_message|default:"Oops! Something went wrong." }}</p>
</div>
</div>
{% endblock %}

View File

@ -2,7 +2,6 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@ -39,6 +38,7 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
} else { } else {
file, headers, err := r.FormFile("file") file, headers, err := r.FormFile("file")
if err != nil { if err != nil {
oopsHandler(c, w, r)
return return
} }
defer file.Close() defer file.Close()
@ -49,7 +49,7 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
upload, err := processUpload(upReq) upload, err := processUpload(upReq)
if err != nil { if err != nil {
fmt.Fprintf(w, "Failed to upload: %v", err) oopsHandler(c, w, r)
return return
} }
@ -72,15 +72,16 @@ func uploadPutHandler(c web.C, w http.ResponseWriter, r *http.Request) {
upReq := UploadRequest{} upReq := UploadRequest{}
defer r.Body.Close() defer r.Body.Close()
upReq.filename = c.URLParams["name"]
upReq.src = r.Body upReq.src = r.Body
upload, err := processUpload(upReq) upload, err := processUpload(upReq)
if err != nil { if err != nil {
fmt.Fprintf(w, "Failed to upload") oopsHandler(c, w, r)
return return
} }
fmt.Fprintf(w, "File %s uploaded successfully.", upload.Filename) fmt.Fprintf(w, Config.siteURL+upload.Filename)
} }
func processUpload(upReq UploadRequest) (upload Upload, err error) { func processUpload(upReq UploadRequest) (upload Upload, err error) {
@ -106,12 +107,10 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) {
if err != nil { if err != nil {
return return
} else if bytes == 0 { } else if bytes == 0 {
err = errors.New("Empty file")
return return
} }
upload.Size = bytes upload.Size = bytes
return return
} }