lib/assets: Allow assets to remain uncompressed (#6661)
This commit is contained in:
+16
-9
@@ -22,11 +22,13 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Asset is the type of arguments to Serve.
|
||||
// An Asset is an embedded file to be served over HTTP.
|
||||
type Asset struct {
|
||||
ContentGz string // gzipped contents of asset.
|
||||
Filename string // Original filename, determines Content-Type.
|
||||
Modified time.Time // Determines ETag and Last-Modified.
|
||||
Content string // Contents of asset, possibly gzipped.
|
||||
Gzipped bool
|
||||
Length int // Length of (decompressed) Content.
|
||||
Filename string // Original filename, determines Content-Type.
|
||||
Modified time.Time // Determines ETag and Last-Modified.
|
||||
}
|
||||
|
||||
// Serve writes a gzipped asset to w.
|
||||
@@ -53,14 +55,19 @@ func Serve(w http.ResponseWriter, r *http.Request, asset Asset) {
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
||||
switch {
|
||||
case !asset.Gzipped:
|
||||
header.Set("Content-Length", strconv.Itoa(len(asset.Content)))
|
||||
io.WriteString(w, asset.Content)
|
||||
case strings.Contains(r.Header.Get("Accept-Encoding"), "gzip"):
|
||||
header.Set("Content-Encoding", "gzip")
|
||||
header.Set("Content-Length", strconv.Itoa(len(asset.ContentGz)))
|
||||
io.WriteString(w, asset.ContentGz)
|
||||
} else {
|
||||
header.Set("Content-Length", strconv.Itoa(len(asset.Content)))
|
||||
io.WriteString(w, asset.Content)
|
||||
default:
|
||||
header.Set("Content-Length", strconv.Itoa(asset.Length))
|
||||
// gunzip for browsers that don't want gzip.
|
||||
var gr *gzip.Reader
|
||||
gr, _ = gzip.NewReader(strings.NewReader(asset.ContentGz))
|
||||
gr, _ = gzip.NewReader(strings.NewReader(asset.Content))
|
||||
io.Copy(w, gr)
|
||||
gr.Close()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -38,15 +39,23 @@ func decompress(p []byte) (out []byte) {
|
||||
return out
|
||||
}
|
||||
|
||||
func TestServe(t *testing.T) {
|
||||
indexHTML := `<html>Hello, world!</html>`
|
||||
indexGz := compress(indexHTML)
|
||||
func TestServe(t *testing.T) { testServe(t, false) }
|
||||
func TestServeGzip(t *testing.T) { testServe(t, true) }
|
||||
|
||||
func testServe(t *testing.T, gzip bool) {
|
||||
const indexHTML = `<html>Hello, world!</html>`
|
||||
content := indexHTML
|
||||
if gzip {
|
||||
content = compress(indexHTML)
|
||||
}
|
||||
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
Serve(w, r, Asset{
|
||||
ContentGz: indexGz,
|
||||
Filename: r.URL.Path[1:],
|
||||
Modified: time.Unix(0, 0),
|
||||
Content: content,
|
||||
Gzipped: gzip,
|
||||
Length: len(indexHTML),
|
||||
Filename: r.URL.Path[1:],
|
||||
Modified: time.Unix(0, 0),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -73,7 +82,17 @@ func TestServe(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
if acceptGzip {
|
||||
|
||||
// Content-Length is the number of bytes in the encoded (compressed) body
|
||||
// (https://stackoverflow.com/a/3819303).
|
||||
n, err := strconv.Atoi(res.Header.Get("Content-Length"))
|
||||
if err != nil {
|
||||
t.Errorf("malformed Content-Length %q", res.Header.Get("Content-Length"))
|
||||
} else if n != len(body) {
|
||||
t.Errorf("wrong Content-Length %d, should be %d", n, len(body))
|
||||
}
|
||||
|
||||
if gzip && acceptGzip {
|
||||
body = decompress(body)
|
||||
}
|
||||
if string(body) != indexHTML {
|
||||
|
||||
Reference in New Issue
Block a user