github.com/docker/compose-on-kubernetes@v0.5.0/samples/web/dispatcher.go (about)

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