diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 41 |
1 files changed, 26 insertions, 15 deletions
@@ -12,16 +12,16 @@ import ( ) func main() { - // Connect to NATS server + // Connect to the NATS server nc, err := nats.Connect(nats.DefaultURL) if err != nil { - log.Fatal(err) + log.Fatal("Error connecting to NATS:", err) } defer nc.Close() - // HTTP handler function + // HTTP handler to proxy all requests to NATS http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // Read the request body + // Read the entire request body (if any) body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Error reading request body", http.StatusInternalServerError) @@ -29,44 +29,55 @@ func main() { } defer r.Body.Close() - // Drop the leading slash if there is one, and replace slashes with dots. - subject := strings.ReplaceAll(strings.TrimPrefix(r.URL.Path, "/"), "/", ".") + // Create the NATS subject. + // Remove the leading slash from the path and replace remaining slashes with dots. + // The subject is prefixed with "http.<method>.", where <method> is lower-case. + path := strings.TrimPrefix(r.URL.Path, "/") + subjectPath := strings.ReplaceAll(path, "/", ".") + subject := fmt.Sprintf("http.%s.%s", strings.ToLower(r.Method), subjectPath) - // Create a NATS message with the request body and headers + log.Println("Forwarding HTTP", r.Method, "request on", r.URL.Path, "to NATS subject:", subject) + + // Create a new NATS message with the HTTP request body msg := nats.Msg{ - Subject: fmt.Sprintf("http.%s", subject), + Subject: subject, Data: body, Header: nats.Header{}, } - log.Println("subject:", msg.Subject) - // Copy HTTP headers to NATS message headers + // Copy over all the HTTP request headers to the NATS message headers for key, values := range r.Header { for _, value := range values { msg.Header.Add(key, value) } } - // Send request to NATS and wait for reply + // Add additional HTTP meta-data as headers + msg.Header.Set("X-HTTP-Method", r.Method) + msg.Header.Set("X-HTTP-Path", r.URL.Path) + msg.Header.Set("X-HTTP-Query", r.URL.RawQuery) + msg.Header.Set("X-Remote-Addr", r.RemoteAddr) + + // Send the NATS request and wait synchronously for a reply (timeout: 30 seconds) reply, err := nc.RequestMsg(&msg, 30*time.Second) if err != nil { http.Error(w, "Error processing request", http.StatusInternalServerError) - log.Println("Error processing the request", err) + log.Println("NATS request error:", err) return } - // Copy NATS reply headers to HTTP response + // Set any response headers from the NATS reply on the HTTP response for key, values := range reply.Header { for _, value := range values { w.Header().Add(key, value) } } - // Write NATS reply body to HTTP response + // Write the reply body (from NATS) back to the HTTP client w.Write(reply.Data) }) - // Start HTTP server + // Start the HTTP server fmt.Println("Server is running on http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) } |