diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4253c50 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.passke.org/laurentu/http-multicaster + +go 1.23.2 diff --git a/http-multicaster.go b/http-multicaster.go new file mode 100644 index 0000000..a55ab56 --- /dev/null +++ b/http-multicaster.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" + "sync" +) + +var backends = []string{ + "http://backend1.local/api", + "http://backend2.local/api", + "http://backend3.local/api", +} + +func forwardRequestToBackend(wg *sync.WaitGroup, client *http.Client, backend string, req *http.Request, responses chan<- string) { + defer wg.Done() + + // Recréer la requête HTTP + forwardReq, err := http.NewRequest(req.Method, backend, req.Body) + if err != nil { + log.Printf("Error creating request for %s: %v", backend, err) + responses <- fmt.Sprintf("Error: %v", err) + return + } + + // Copier les en-têtes de la requête originale + forwardReq.Header = req.Header.Clone() + + // Envoyer la requête au backend + resp, err := client.Do(forwardReq) + if err != nil { + log.Printf("Error forwarding to %s: %v", backend, err) + responses <- fmt.Sprintf("Error: %v", err) + return + } + defer resp.Body.Close() + + // Lire la réponse du backend + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Printf("Error reading response from %s: %v", backend, err) + responses <- fmt.Sprintf("Error: %v", err) + return + } + + // Ajouter la réponse dans le canal + responses <- fmt.Sprintf("Response from %s: %s", backend, body) +} + +func handler(w http.ResponseWriter, req *http.Request) { + client := &http.Client{} + var wg sync.WaitGroup + responses := make(chan string, len(backends)) + + // Forward la requête vers chaque backend + for _, backend := range backends { + wg.Add(1) + go forwardRequestToBackend(&wg, client, backend, req, responses) + } + + // Attendre la fin de toutes les requêtes + wg.Wait() + close(responses) + + // Collecter et afficher les réponses des backends + for response := range responses { + fmt.Fprintf(w, "%s\n", response) + } +} + +func main() { + http.HandleFunc("/", handler) + fmt.Println("Starting server on :8080...") + if err := http.ListenAndServe(":8080", nil); err != nil { + log.Fatalf("Server failed: %v", err) + } +}