Update to fiber 3
Change-Id: I18a7b3ed55aef5cae67db6a613ec14e0f8a9281e
diff --git a/config/config.go b/config/config.go
index 9347994..e024c76 100644
--- a/config/config.go
+++ b/config/config.go
@@ -109,7 +109,7 @@
ServiceURL string `yaml:"serviceURL,omitempty"`
CookieName string `yaml:"cookieName,omitempty"`
BasePath string `yaml:"basePath,omitempty"` // restricts config file loading to this directory tree
- AllowOrigins string `yaml:"allowOrigins,omitempty"` // comma-separated list of allowed CORS origins
+ AllowOrigins []string `yaml:"allowOrigins,omitempty"`
Port int `yaml:"port,omitempty"`
LogLevel string `yaml:"loglevel,omitempty"`
RateLimit int `yaml:"rateLimit,omitempty"` // max requests per minute per IP (0 = use default 100)
@@ -117,6 +117,28 @@
Lists []MappingList `yaml:"lists,omitempty"`
}
+// UnmarshalYAML rejects the deprecated comma-separated string format for
+// allowOrigins and requires a YAML list instead.
+func (m *MappingConfig) UnmarshalYAML(value *yaml.Node) error {
+ if value.Kind == yaml.MappingNode {
+ for i := 0; i < len(value.Content)-1; i += 2 {
+ if value.Content[i].Value == "allowOrigins" && value.Content[i+1].Kind == yaml.ScalarNode {
+ return fmt.Errorf(
+ "allowOrigins must be a YAML list, not a comma-separated string; update your config:\n" +
+ " allowOrigins:\n" +
+ " - \"https://example.com\"")
+ }
+ }
+ }
+ type plain MappingConfig
+ var p plain
+ if err := value.Decode(&p); err != nil {
+ return err
+ }
+ *m = MappingConfig(p)
+ return nil
+}
+
// AllowedBasePath restricts file loading to a specific directory tree.
// When set, all file paths must resolve to a location at or below this
// directory (or under the system temp directory). Defaults to the CWD at
@@ -206,6 +228,8 @@
seenIDs[list.ID] = true
}
allLists = append(allLists, globalConfig.Lists...)
+ } else if strings.Contains(err.Error(), "allowOrigins must be") {
+ return nil, fmt.Errorf("failed to parse config file '%s': %w", configFile, err)
} else {
// Fall back to old format (direct list)
var lists []MappingList
@@ -309,8 +333,8 @@
// AllowOrigins defaults to the Server value. This avoids duplicating
// the server URL string and keeps CORS in sync with the deployment.
- if config.AllowOrigins == "" {
- config.AllowOrigins = config.Server
+ if len(config.AllowOrigins) == 0 {
+ config.AllowOrigins = []string{config.Server}
}
config.AllowOrigins = normalizeOrigins(config.AllowOrigins)
@@ -322,21 +346,24 @@
}
}
-// normalizeOrigins takes a comma-separated list of origin URLs and strips
-// any path components, returning only scheme + host (+ port when present).
-// The CORS middleware requires bare origins without paths; URLs like
+// normalizeOrigins strips path components from origin URLs, returning only
+// scheme + host (+ port when present). The CORS middleware requires bare
+// origins without paths; URLs like
// "https://example.com/instance/test" are pruned to "https://example.com".
-func normalizeOrigins(raw string) string {
- parts := strings.Split(raw, ",")
- for i, part := range parts {
- part = strings.TrimSpace(part)
- if u, err := url.Parse(part); err == nil && u.Host != "" {
- parts[i] = u.Scheme + "://" + u.Host
+func normalizeOrigins(origins []string) []string {
+ result := make([]string, 0, len(origins))
+ for _, origin := range origins {
+ origin = strings.TrimSpace(origin)
+ if origin == "" {
+ continue
+ }
+ if u, err := url.Parse(origin); err == nil && u.Host != "" {
+ result = append(result, u.Scheme+"://"+u.Host)
} else {
- parts[i] = strings.TrimRight(part, "/")
+ result = append(result, strings.TrimRight(origin, "/"))
}
}
- return strings.Join(parts, ",")
+ return result
}
// ApplyEnvOverrides overrides configuration fields from environment variables.
@@ -344,14 +371,13 @@
// Non-empty environment values override any previously loaded config values.
func ApplyEnvOverrides(config *MappingConfig) {
envMappings := map[string]*string{
- "KORAL_MAPPER_SERVER": &config.Server,
- "KORAL_MAPPER_SDK": &config.SDK,
- "KORAL_MAPPER_STYLESHEET": &config.Stylesheet,
- "KORAL_MAPPER_SERVICE_URL": &config.ServiceURL,
- "KORAL_MAPPER_COOKIE_NAME": &config.CookieName,
- "KORAL_MAPPER_LOG_LEVEL": &config.LogLevel,
- "KORAL_MAPPER_BASE_PATH": &config.BasePath,
- "KORAL_MAPPER_ALLOW_ORIGINS": &config.AllowOrigins,
+ "KORAL_MAPPER_SERVER": &config.Server,
+ "KORAL_MAPPER_SDK": &config.SDK,
+ "KORAL_MAPPER_STYLESHEET": &config.Stylesheet,
+ "KORAL_MAPPER_SERVICE_URL": &config.ServiceURL,
+ "KORAL_MAPPER_COOKIE_NAME": &config.CookieName,
+ "KORAL_MAPPER_LOG_LEVEL": &config.LogLevel,
+ "KORAL_MAPPER_BASE_PATH": &config.BasePath,
}
for envKey, field := range envMappings {
@@ -360,6 +386,10 @@
}
}
+ if val := os.Getenv("KORAL_MAPPER_ALLOW_ORIGINS"); val != "" {
+ config.AllowOrigins = strings.Split(val, ",")
+ }
+
if val := os.Getenv("KORAL_MAPPER_PORT"); val != "" {
if port, err := strconv.Atoi(val); err == nil {
config.Port = port