http/static/static.go

Summary

Maintainability
A
0 mins
Test Coverage
// Package static provides static file serving with HTTP cache support.
package static

import (
    "net/http"
    "os"
    "path/filepath"
    "strings"

    "github.com/apex/up"
)

// New static handler.
func New(c *up.Config) http.Handler {
    return http.FileServer(http.Dir(c.Static.Dir))
}

// NewDynamic static handler for dynamic apps.
func NewDynamic(c *up.Config, next http.Handler) http.Handler {
    prefix := normalizePrefix(c.Static.Prefix)
    dir := c.Static.Dir

    if dir == "" {
        return next
    }

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        var skip bool
        path := r.URL.Path

        // prefix
        if prefix != "" {
            if strings.HasPrefix(path, prefix) {
                path = strings.Replace(path, prefix, "/", 1)
            } else {
                skip = true
            }
        }

        // convert
        path = filepath.FromSlash(path)

        // file exists, serve it
        if !skip {
            file := filepath.Join(dir, path)
            info, err := os.Stat(file)
            if !os.IsNotExist(err) && !info.IsDir() {
                http.ServeFile(w, r, file)
                return
            }
        }

        // delegate
        next.ServeHTTP(w, r)
    })
}

// normalizePrefix returns a prefix path normalized with leading and trailing "/".
func normalizePrefix(s string) string {
    if !strings.HasPrefix(s, "/") {
        s = "/" + s
    }

    if !strings.HasSuffix(s, "/") {
        s = s + "/"
    }

    return s
}