Esempio n. 1
0
File: main.go Progetto: eBay/fabio
func newHTTPProxy(cfg *config.Config) http.Handler {
	if err := route.SetPickerStrategy(cfg.Proxy.Strategy); err != nil {
		exit.Fatal("[FATAL] ", err)
	}
	log.Printf("[INFO] Using routing strategy %q", cfg.Proxy.Strategy)

	if err := route.SetMatcher(cfg.Proxy.Matcher); err != nil {
		exit.Fatal("[FATAL] ", err)
	}
	log.Printf("[INFO] Using routing matching %q", cfg.Proxy.Matcher)

	tr := &http.Transport{
		ResponseHeaderTimeout: cfg.Proxy.ResponseHeaderTimeout,
		MaxIdleConnsPerHost:   cfg.Proxy.MaxConn,
		Dial: (&net.Dialer{
			Timeout:   cfg.Proxy.DialTimeout,
			KeepAlive: cfg.Proxy.KeepAliveTimeout,
		}).Dial,
	}

	return proxy.NewHTTPProxy(tr, cfg.Proxy)
}
Esempio n. 2
0
/**
  使用配置信息创建并返回HTTP代理服务器的句柄
*/
func newHTTPProxy(cfg *config.Config) http.Handler {
	// 设置路由拣选策略
	if err := route.SetPickerStrategy(cfg.Proxy.Strategy); err != nil {
		exit.Fatal("[FATAL] ", err)
	}
	log.Printf("[INFO] Using routing strategy %q", cfg.Proxy.Strategy)

	// 设置路由匹配器
	if err := route.SetMatcher(cfg.Proxy.Matcher); err != nil {
		exit.Fatal("[FATAL] ", err)
	}
	log.Printf("[INFO] Using routing matching %q", cfg.Proxy.Matcher)

	// 配置转换器
	tr := &http.Transport{
		ResponseHeaderTimeout: cfg.Proxy.ResponseHeaderTimeout,
		MaxIdleConnsPerHost:   cfg.Proxy.MaxConn,
		Dial: (&net.Dialer{
			Timeout:   cfg.Proxy.DialTimeout,
			KeepAlive: cfg.Proxy.KeepAliveTimeout,
		}).Dial,
	}
	/**
	@todo 上面代码中有疑问,如下代码:

	Dial: (&net.Dialer{
		Timeout:   cfg.Proxy.DialTimeout,
		KeepAlive: cfg.Proxy.KeepAliveTimeout,
	}).Dial

	第一行为何用 &net.Dialer ? 即为何使用引用?
	原因是 net包的Dialer结构体(struct)的方法Dial是指针类型,所以只有使用引用定义的时候才能访问到该函数
	*/

	// 生成并返回HTTP代理句柄
	return proxy.NewHTTPProxy(tr, cfg.Proxy)
}
Esempio n. 3
0
func TestGracefulShutdown(t *testing.T) {
	req := func(url string) int {
		resp, err := http.Get(url)
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()
		return resp.StatusCode
	}

	// start a server which responds after the shutdown has been triggered.
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		<-quit // wait for shutdown signal
		return
	}))
	defer srv.Close()

	// load the routing table
	tbl, err := route.ParseString("route add svc / " + srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	route.SetTable(tbl)

	// start proxy with graceful shutdown period long enough
	// to complete one more request.
	var wg sync.WaitGroup
	l := config.Listen{Addr: "127.0.0.1:57777", Proto: "http"}
	wg.Add(1)
	go func() {
		defer wg.Done()
		startListeners([]config.Listen{l}, 250*time.Millisecond, proxy.NewHTTPProxy(http.DefaultTransport, config.Proxy{}), nil)
	}()

	// trigger shutdown after some time
	shutdownDelay := 100 * time.Millisecond
	go func() {
		time.Sleep(shutdownDelay)
		close(quit)
	}()

	// give proxy some time to start up
	// needs to be done before shutdown is triggered
	time.Sleep(shutdownDelay / 2)

	// make 200 OK request
	// start before and complete after shutdown was triggered
	if got, want := req("http://"+l.Addr+"/"), 200; got != want {
		t.Fatalf("request 1: got %v want %v", got, want)
	}

	// make 503 request
	// start and complete after shutdown was triggered
	if got, want := req("http://"+l.Addr+"/"), 503; got != want {
		t.Fatalf("got %v want %v", got, want)
	}

	// wait for listen() to return
	// note that the actual listeners have not returned yet
	wg.Wait()
}