1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-24 17:03:57 +00:00
fiber/middleware/favicon/favicon.go
Roman 5a3edb9011 🔥add the option to set a custom Cache-Control value for a favicon response
Right now, each favicon response sets the `Cache-Control` header to
`public, max-age=31536000` (1 year). In some cases this could be a
little bit high if you are changing it etc. and the header is not
replaced by a reverse proxy.

With this change, the favicon middleware allows the configuration of the
`Cache-Control` header. The default behavior is to keep the setting of
`max-age=31536000 `, but you could fine-tune it.
2020-10-05 08:35:29 +02:00

110 lines
2.3 KiB
Go

package favicon
import (
"io/ioutil"
"strconv"
"github.com/gofiber/fiber/v2"
)
// Config defines the config for middleware.
type Config struct {
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool
// File holds the path to an actual favicon that will be cached
//
// Optional. Default: ""
File string
// CacheControl defines how the Cache-Control header in the response should be set
//
// Optional. Default: "public, max-age=31536000"
CacheControl string
}
// ConfigDefault is the default config
var ConfigDefault = Config{
Next: nil,
File: "",
CacheControl: "public, max-age=31536000",
}
const (
hType = "image/x-icon"
hAllow = "GET, HEAD, OPTIONS"
hZero = "0"
)
// New creates a new middleware handler
func New(config ...Config) fiber.Handler {
// Set default config
cfg := ConfigDefault
// Override config if provided
if len(config) > 0 {
cfg = config[0]
// Set default values
if cfg.Next == nil {
cfg.Next = ConfigDefault.Next
}
if cfg.File == "" {
cfg.File = ConfigDefault.File
}
if cfg.CacheControl == "" {
cfg.CacheControl = ConfigDefault.CacheControl
}
}
// Load icon if provided
var (
err error
icon []byte
iconLen string
)
if cfg.File != "" {
if icon, err = ioutil.ReadFile(cfg.File); err != nil {
panic(err)
}
iconLen = strconv.Itoa(len(icon))
}
// Return new handler
return func(c *fiber.Ctx) error {
// Don't execute middleware if Next returns true
if cfg.Next != nil && cfg.Next(c) {
return c.Next()
}
// Only respond to favicon requests
if len(c.Path()) != 12 || c.Path() != "/favicon.ico" {
return c.Next()
}
// Only allow GET, HEAD and OPTIONS requests
if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead {
if c.Method() != fiber.MethodOptions {
c.Status(fiber.StatusMethodNotAllowed)
} else {
c.Status(fiber.StatusOK)
}
c.Set(fiber.HeaderAllow, hAllow)
c.Set(fiber.HeaderContentLength, hZero)
return nil
}
// Serve cached favicon
if len(icon) > 0 {
c.Set(fiber.HeaderContentLength, iconLen)
c.Set(fiber.HeaderContentType, hType)
c.Set(fiber.HeaderCacheControl, cfg.CacheControl)
return c.Status(fiber.StatusOK).Send(icon)
}
return c.SendStatus(fiber.StatusNoContent)
}
}