diff options
-rw-r--r-- | main.go | 33 |
1 files changed, 30 insertions, 3 deletions
@@ -7,6 +7,7 @@ import ( "log" "net" "net/http" + "net/url" "os" "strings" "time" @@ -29,6 +30,27 @@ func printHelp() { fmt.Println(" HTTP_PORT - HTTP port to listen on (default: 8080)") } +// URL to NATS subject conversion +func URLToNATS(urlPath string) (string, error) { + segments := strings.Split(strings.Trim(urlPath, "/"), "/") + for i, seg := range segments { + // Decode existing encoding first to prevent double-encoding + unescaped, err := url.PathUnescape(seg) + if err != nil { + return "", fmt.Errorf("failed to unescape segment: %w", err) + } + + // Encode special NATS-sensitive characters + encoded := url.PathEscape(unescaped) + encoded = strings.ReplaceAll(encoded, ".", "%2E") // Critical for token separation + encoded = strings.ReplaceAll(encoded, "*", "%2A") // Wildcard protection + encoded = strings.ReplaceAll(encoded, ">", "%3E") // Wildcard protection + + segments[i] = encoded + } + return strings.Join(segments, "."), nil +} + func main() { helpFlag := flag.Bool("help", false, "Display help information about available environment variables") flag.Parse() @@ -103,9 +125,14 @@ func main() { domainParts := strings.ReplaceAll(host, ".", "_") // Process path component - path := strings.TrimPrefix(r.URL.Path, "/") - // Replace all "." with "_" and then all "/" with ".". - subjectPath := strings.ReplaceAll(strings.ReplaceAll(path, ".", "_"), "/", ".") + path := strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, "/"), "/") + subjectPath, err := URLToNATS(path) + if err != nil { + http.Error(w, "Error converting endpoint to NATS subject", http.StatusInternalServerError) + log.Println("Could not convert endpoint to NATS subject", err) + return + + } // Build final subject subjectBase := "http" |