Migrated all http mechanics to a central handler, changed static
content to all be front-loaded and thread safe
This commit is contained in:
@ -12,14 +12,58 @@ import (
|
||||
)
|
||||
|
||||
type StaticContent struct {
|
||||
ContentType string
|
||||
Content string
|
||||
ContentType string
|
||||
ETag string
|
||||
GZIPContent []byte
|
||||
GZIPETag string
|
||||
DisableGZIP bool
|
||||
}
|
||||
|
||||
func (ctx *StaticContent) Init() error {
|
||||
// Do we have a content type? If not, initialize it
|
||||
if ctx.ContentType == "" {
|
||||
ext := path.Ext(ctx.Content)
|
||||
ctx.ContentType = mime.TypeByExtension(ext)
|
||||
// Fallback to default mime type
|
||||
if ctx.ContentType == "" {
|
||||
ctx.ContentType = "application/octet-stream"
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have an etag? If not, generate one
|
||||
if ctx.ETag == "" {
|
||||
ctx.ETag = fmt.Sprintf("%x", md5.Sum(Assets[ctx.Content]))
|
||||
}
|
||||
|
||||
// If gzip is allowed and we have no gzip etag, generate
|
||||
// gzip content and etag
|
||||
if !ctx.DisableGZIP && ctx.GZIPETag == "" {
|
||||
var buf bytes.Buffer
|
||||
gz, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
|
||||
defer gz.Close()
|
||||
|
||||
if _, err := gz.Write(Assets[ctx.Content]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gz.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if GZIP actually resulted in a smaller file
|
||||
if buf.Len() < len(Assets[ctx.Content]) {
|
||||
ctx.GZIPContent = buf.Bytes()
|
||||
ctx.GZIPETag = fmt.Sprintf("%x", md5.Sum(Assets[ctx.Content]))
|
||||
} else {
|
||||
// If gzip turns out to be ineffective, disable it
|
||||
ctx.DisableGZIP = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *StaticContent) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// By default, don't use gzip
|
||||
useGZIP := false
|
||||
@ -29,45 +73,11 @@ func (ctx *StaticContent) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
useGZIP = strings.Contains(r.Header.Get("Accept-Encoding"), "gzip")
|
||||
}
|
||||
|
||||
// If gzip is enabled, and there's no gzip etag,
|
||||
// generate the gzip'd content plus the etag
|
||||
if useGZIP && len(ctx.GZIPETag) == 0 {
|
||||
var buf bytes.Buffer
|
||||
|
||||
gz, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
|
||||
defer gz.Close()
|
||||
|
||||
if _, err := gz.Write(Assets[ctx.Content]); err != nil {
|
||||
http.Error(w, fmt.Sprintf("GZIP write error: %s", err.Error()),
|
||||
http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := gz.Flush(); err != nil {
|
||||
http.Error(w, fmt.Sprintf("GZIP flush error: %s", err.Error()),
|
||||
http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if GZIP actually resulted in a smaller file
|
||||
if buf.Len() < len(Assets[ctx.Content]) {
|
||||
ctx.GZIPContent = buf.Bytes()
|
||||
ctx.GZIPETag = fmt.Sprintf("%x", md5.Sum(Assets[ctx.Content]))
|
||||
} else {
|
||||
// If gzip turns out to be ineffective, disable it
|
||||
ctx.DisableGZIP = true
|
||||
useGZIP = false
|
||||
}
|
||||
}
|
||||
|
||||
// Use the correct etag
|
||||
var localETag string
|
||||
if useGZIP {
|
||||
localETag = ctx.GZIPETag
|
||||
} else {
|
||||
// Generate an ETag for content if necessary
|
||||
if ctx.ETag == "" {
|
||||
ctx.ETag = fmt.Sprintf("%x", md5.Sum(Assets[ctx.Content]))
|
||||
}
|
||||
localETag = ctx.ETag
|
||||
}
|
||||
|
||||
@ -79,17 +89,6 @@ func (ctx *StaticContent) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
w.Header().Set("ETag", localETag)
|
||||
|
||||
// Check the content type, if we don't already
|
||||
// have one, make one
|
||||
if ctx.ContentType == "" {
|
||||
ext := path.Ext(ctx.Content)
|
||||
ctx.ContentType = mime.TypeByExtension(ext)
|
||||
// Fallback to default mime type
|
||||
if ctx.ContentType == "" {
|
||||
ctx.ContentType = "application/octet-stream"
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", ctx.ContentType)
|
||||
|
||||
// Finally, write our content
|
||||
|
Reference in New Issue
Block a user