Home / File/ favicon.go — fiber Source File

favicon.go — fiber Source File

Architecture documentation for favicon.go, a go file in the fiber codebase. 1 imports, 0 dependents.

File go FiberCore Adapters 1 imports 2 functions 1 classes

Entity Profile

Dependency Diagram

graph LR
  3c25708a_7b43_d7ea_98a8_80dc1d4ca5c8["favicon.go"]
  adf3d4e8_4d86_86c1_e6cc_281d7b4104af["fmt"]
  3c25708a_7b43_d7ea_98a8_80dc1d4ca5c8 --> adf3d4e8_4d86_86c1_e6cc_281d7b4104af
  style 3c25708a_7b43_d7ea_98a8_80dc1d4ca5c8 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

package favicon

import (
	"fmt"
	"io"
	"io/fs"
	"os"
	"strconv"

	"github.com/gofiber/fiber/v3"
)

const (
	fPath  = "/favicon.ico"
	hType  = "image/x-icon"
	hAllow = "GET, HEAD, OPTIONS"
	hZero  = "0"
)

// New creates a new middleware handler
func New(config ...Config) fiber.Handler {
	cfg := configDefault(config...)

	// Load iconData if provided
	var (
		err           error
		iconData      []byte
		iconLenHeader string
		iconLen       int
		f             fs.File
	)
	if cfg.Data != nil {
		// use the provided favicon data
		iconData = cfg.Data
		iconLenHeader = strconv.Itoa(len(cfg.Data))
		iconLen = len(cfg.Data)
	} else if cfg.File != "" {
		// read from configured filesystem if present
		if cfg.FileSystem != nil {
			f, err = cfg.FileSystem.Open(cfg.File)
			if err != nil {
				panic(err)
			}
			defer func() {
				_ = f.Close() //nolint:errcheck // not needed
			}()
			if iconData, err = readLimited(f, cfg.MaxBytes); err != nil {
				panic(err)
			}
		} else {
			f, err = os.Open(cfg.File)
			if err != nil {
				panic(err)
			}
			defer func() {
				_ = f.Close() //nolint:errcheck // not needed
			}()
			if iconData, err = readLimited(f, cfg.MaxBytes); err != nil {
				panic(err)
			}
		}

		iconLenHeader = strconv.Itoa(len(iconData))
		iconLen = len(iconData)
	}

	// 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 c.Path() != cfg.URL {
			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 iconLen > 0 {
			c.Set(fiber.HeaderContentLength, iconLenHeader)
			c.Set(fiber.HeaderContentType, hType)
			c.Set(fiber.HeaderCacheControl, cfg.CacheControl)
			return c.Status(fiber.StatusOK).Send(iconData)
		}

		return c.SendStatus(fiber.StatusNoContent)
	}
}

func readLimited(reader io.Reader, maxBytes int64) ([]byte, error) {
	limit := maxBytes + 1
	data, err := io.ReadAll(io.LimitReader(reader, limit))
	if err != nil {
		return nil, fmt.Errorf("favicon: read limited: %w", err)
	}
	if int64(len(data)) > maxBytes {
		return nil, fmt.Errorf("favicon: file size exceeds max bytes %d", maxBytes)
	}
	return data, nil
}

Domain

Subdomains

Functions

Classes

Dependencies

  • fmt

Frequently Asked Questions

What does favicon.go do?
favicon.go is a source file in the fiber codebase, written in go. It belongs to the FiberCore domain, Adapters subdomain.
What functions are defined in favicon.go?
favicon.go defines 2 function(s): New, readLimited.
What does favicon.go depend on?
favicon.go imports 1 module(s): fmt.
Where is favicon.go in the architecture?
favicon.go is located at middleware/favicon/favicon.go (domain: FiberCore, subdomain: Adapters, directory: middleware/favicon).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free