Skip to content

Instantly share code, notes, and snippets.

@solyard
Created December 25, 2023 15:43
Show Gist options
  • Save solyard/ffdd2c78781317803fb88ca1e76cc276 to your computer and use it in GitHub Desktop.
Save solyard/ffdd2c78781317803fb88ca1e76cc276 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
)
var (
upstreamURLs = []string{
"https://ya.ru",
"https://google.com",
"https://bing.com",
}
)
func main() {
http.HandleFunc("/", forwardHandler)
log.Println("Server started on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func forwardHandler(w http.ResponseWriter, req *http.Request) {
// Create a WaitGroup to wait for all goroutines to finish
var wg sync.WaitGroup
responses := make(chan string, len(upstreamURLs))
for _, upstream := range upstreamURLs {
wg.Add(1)
go func(upstream string) {
defer wg.Done()
forwardRequest(upstream, req, responses)
}(upstream)
}
go func() {
wg.Wait()
close(responses)
}()
for response := range responses {
fmt.Fprintln(w, response)
}
}
func forwardRequest(upstream string, req *http.Request, responses chan<- string) {
request, err := http.NewRequest(req.Method, upstream, req.Body)
if err != nil {
log.Printf("Error creating request for upstream %s: %v", upstream, err)
responses <- fmt.Sprintf("Error contacting upstream %s", upstream)
return
}
request.Header = req.Header
client := &http.Client{}
resp, err := client.Do(request)
if err != nil {
log.Printf("Error forwarding request to upstream %s: %v", upstream, err)
responses <- fmt.Sprintf("Error contacting upstream %s", upstream)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("Error reading response from upstream %s: %v", upstream, err)
responses <- fmt.Sprintf("Error reading response from upstream %s", upstream)
return
}
responses <- string(body)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment