photoprism/pkg/header/cors.go

73 lines
2.4 KiB
Go

package header
import (
"net/http"
"strings"
)
// Cross-Origin Resource Sharing (CORS) headers.
const (
AccessControlAllowOrigin = "Access-Control-Allow-Origin" // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
AccessControlAllowHeaders = "Access-Control-Allow-Headers" // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
AccessControlAllowMethods = "Access-Control-Allow-Methods" // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
AccessControlMaxAge = "Access-Control-Max-Age" // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
)
// CORS header defaults.
var (
DefaultAccessControlAllowOrigin = ""
CorsHeaders = []string{Accept, AcceptRanges, ContentDisposition, ContentEncoding, ContentRange, Location}
DefaultAccessControlAllowHeaders = strings.Join(CorsHeaders, ", ")
CorsMethods = []string{http.MethodGet, http.MethodHead, http.MethodOptions}
DefaultAccessControlAllowMethods = strings.Join(CorsMethods, ", ")
DefaultAccessControlMaxAge = "3600"
)
// CorsExt contains all static asset extensions for which a CORS header may be added automatically.
var CorsExt = map[string]bool{
".ttf": true,
".ttc": true,
".otf": true,
".eot": true,
".woff": true,
".woff2": true,
".css": true,
".js": true, // Required for the MapLibre GL RTL text plugin.
".json": true, // Required for static frontend configuration files.
".svg": true, // Required for SVG icons that depend on additional styles or fonts.
}
// AllowCORS checks if CORS headers can be safely used based on a request's file path.
// See: https://www.w3.org/TR/css-fonts-3/#font-fetching-requirements
func AllowCORS(path string) bool {
// Return false if path is empty.
if path == "" {
return false
}
// Extract extension from path.
var ext string
l := len(path) - 1
for i := l; i >= 0 && path[i] != '/'; i-- {
if path[i] == '.' {
ext = path[i:]
if l-len(ext) < 0 {
// Return false if there is no filename.
return false
} else if r := path[i-1]; (r < '0' || r > '9') && (r < 'A' || r > 'Z') && (r < 'a' || r > 'z') {
// Return false if the filename is invalid.
return false
}
break
}
}
// Return false if path does not include an extension.
if ext == "" {
return false
}
// Check list of allowed extensions.
return CorsExt[ext]
}