Skip to content

Commit

Permalink
Etags (#23)
Browse files Browse the repository at this point in the history
* Calculate font file md5 on load

* etag header

* Support for a single If-None_Match header

* Support multiple If-None-Match headers
  • Loading branch information
Dave Ross authored May 24, 2020
1 parent e7da231 commit bfb4f4b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
22 changes: 21 additions & 1 deletion fonts/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package fonts

import (
"crypto/sha256"
"crypto/md5"
"encoding/hex"
"errors"
"log"
"os"
"io"
"path"
"regexp"
"strings"
Expand All @@ -21,6 +23,7 @@ type FontFileData struct {
FileName string
Extension string
CSSFormat string
MD5 string
}

// FontVariant describes a variant (ex: "Black", "Italic") of a font
Expand Down Expand Up @@ -101,12 +104,13 @@ func LoadFont(filePath string, config adrianConfig.Config) {
Variants: make(map[string]FontVariant),
}
}

fontFileData := FontFileData{
Name: fontName,
CSSFormat: fontCSSFormat(fontFormat),
Extension: fontFormat,
Path: filePath,
MD5: calcFileMD5(filePath),
}

fontVariant, ok := fontData.Variants[fontName]
Expand Down Expand Up @@ -162,6 +166,22 @@ func calcUniqueID(fontVariant FontVariant, config adrianConfig.Config) string {
return fontVariant.Name
}

// calcFileMD5 calculates the MD5 hash of a file
func calcFileMD5(filepath string) string {
file, err := os.Open(filepath)
if err != nil {
log.Fatal(err)
}
defer file.Close()

hash := md5.New()
if _, err := io.Copy(hash, file); err != nil {
log.Fatal(err)
}

return hex.EncodeToString(hash.Sum(nil))
}

// fontCSSFormat determines the appropriate CSS font format given a FontData struct with Type set
func fontCSSFormat(fileType string) string {
switch fileType {
Expand Down
12 changes: 12 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,25 @@ func outputFont(c echo.Context, mimeType string) error {
log.Fatal("Invalid font format" + adrianFonts.GetCanonicalExtension(filename))
}

for i := range c.Request().Header["If-None-Match"] {
individualHashes := strings.Split(c.Request().Header["If-None-Match"][i], (", "))
for j := range individualHashes {
if individualHashes[j] == fontFileData.MD5 {
status := make(map[string]string)
status["message"] = "Not Modified"
return c.JSON(http.StatusNotModified, status)
}
}
}

fontBinary, err := ioutil.ReadFile(fontFileData.Path) // just pass the file name
if err != nil {
log.Fatal("Can't read font file " + fontFileData.FileName)
}

c.Response().Header().Set("Content-Transfer-Encoding", "binary")
c.Response().Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
c.Response().Header().Set("ETag", fontFileData.MD5)
return c.Blob(http.StatusOK, mimeType, fontBinary)

}
Expand Down

0 comments on commit bfb4f4b

Please sign in to comment.