mirror of https://github.com/gofiber/fiber.git
86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
package cors
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// matchScheme compares the scheme of the domain and pattern
|
|
func matchScheme(domain, pattern string) bool {
|
|
didx := strings.Index(domain, ":")
|
|
pidx := strings.Index(pattern, ":")
|
|
return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx]
|
|
}
|
|
|
|
// validateDomain checks if the domain matches the pattern
|
|
func validateDomain(domain, pattern string) bool {
|
|
// Directly compare the domain and pattern for an exact match.
|
|
if domain == pattern {
|
|
return true
|
|
}
|
|
|
|
// Normalize domain and pattern to exclude schemes and ports for matching purposes
|
|
normalizedDomain := normalizeDomain(domain)
|
|
normalizedPattern := normalizeDomain(pattern)
|
|
|
|
// Handling the case where pattern is a wildcard subdomain pattern.
|
|
if strings.HasPrefix(normalizedPattern, "*.") {
|
|
// Trim leading "*." from pattern for comparison.
|
|
trimmedPattern := normalizedPattern[2:]
|
|
|
|
// Check if the domain ends with the trimmed pattern.
|
|
if strings.HasSuffix(normalizedDomain, trimmedPattern) {
|
|
// Ensure that the domain is not exactly the base domain.
|
|
if normalizedDomain != trimmedPattern {
|
|
// Special handling to prevent "example.com" matching "*.example.com".
|
|
if strings.TrimSuffix(normalizedDomain, trimmedPattern) != "" {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// normalizeDomain removes the scheme and port from the input domain
|
|
func normalizeDomain(input string) string {
|
|
// Remove scheme
|
|
input = strings.TrimPrefix(strings.TrimPrefix(input, "http://"), "https://")
|
|
|
|
// Find and remove port, if present
|
|
if len(input) > 0 && input[0] != '[' {
|
|
if portIndex := strings.Index(input, ":"); portIndex != -1 {
|
|
input = input[:portIndex]
|
|
}
|
|
}
|
|
|
|
return input
|
|
}
|
|
|
|
// normalizeOrigin checks if the provided origin is in a correct format
|
|
// and normalizes it by removing any path or trailing slash.
|
|
// It returns a boolean indicating whether the origin is valid
|
|
// and the normalized origin.
|
|
func normalizeOrigin(origin string) (bool, string) {
|
|
parsedOrigin, err := url.Parse(origin)
|
|
if err != nil {
|
|
return false, ""
|
|
}
|
|
|
|
// Validate the scheme is either http or https
|
|
if parsedOrigin.Scheme != "http" && parsedOrigin.Scheme != "https" {
|
|
return false, ""
|
|
}
|
|
|
|
// Validate there is a host present. The presence of a path, query, or fragment components
|
|
// is checked, but a trailing "/" (indicative of the root) is allowed for the path and will be normalized
|
|
if parsedOrigin.Host == "" || (parsedOrigin.Path != "" && parsedOrigin.Path != "/") || parsedOrigin.RawQuery != "" || parsedOrigin.Fragment != "" {
|
|
return false, ""
|
|
}
|
|
|
|
// Normalize the origin by constructing it from the scheme and host.
|
|
// The path or trailing slash is not included in the normalized origin.
|
|
return true, strings.ToLower(parsedOrigin.Scheme + "://" + parsedOrigin.Host)
|
|
}
|