dispatcher.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "math/rand"
  7. "net"
  8. "net/http"
  9. "time"
  10. )
  11. func main() {
  12. rand.Seed(time.Now().UnixNano())
  13. fwd := &forwarder{"words", 8080}
  14. http.Handle("/words/", http.StripPrefix("/words", fwd))
  15. http.Handle("/", http.FileServer(http.Dir("static")))
  16. fmt.Println("Listening on port 80")
  17. err := http.ListenAndServe(":80", nil)
  18. if err != nil {
  19. fmt.Printf("Error while starting server: %v", err)
  20. }
  21. }
  22. type forwarder struct {
  23. host string
  24. port int
  25. }
  26. func (f *forwarder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  27. addrs, err := net.LookupHost(f.host)
  28. if err != nil {
  29. log.Println("Error", err)
  30. http.Error(w, err.Error(), 500)
  31. return
  32. }
  33. log.Printf("%s %d available ips: %v", r.URL.Path, len(addrs), addrs)
  34. ip := addrs[rand.Intn(len(addrs))]
  35. log.Printf("%s I choose %s", r.URL.Path, ip)
  36. url := fmt.Sprintf("http://%s:%d%s", ip, f.port, r.URL.Path)
  37. log.Printf("%s Calling %s", r.URL.Path, url)
  38. if err = copy(url, ip, w); err != nil {
  39. log.Println("Error", err)
  40. http.Error(w, err.Error(), 500)
  41. return
  42. }
  43. }
  44. func copy(url, ip string, w http.ResponseWriter) error {
  45. resp, err := http.Get(url)
  46. if err != nil {
  47. return err
  48. }
  49. w.Header().Set("source", ip)
  50. buf, err := ioutil.ReadAll(resp.Body)
  51. if err != nil {
  52. return err
  53. }
  54. _, err = w.Write(buf)
  55. return err
  56. }