// target looks up a target URL for the request from the current routing table. func target(r *http.Request) *route.Target { t := route.GetTable().Lookup(r, r.Header.Get("trace")) if t == nil { log.Print("[WARN] No route for ", r.Host, r.URL) } return t }
func HandleRoutes(w http.ResponseWriter, r *http.Request) { t := fabioroute.GetTable() var hosts []string for host := range t { hosts = append(hosts, host) } var routes []route for _, host := range hosts { for _, tr := range t[host] { for _, tg := range tr.Targets { ar := route{ Service: tg.Service, Host: tr.Host, Path: tr.Path, Dst: tg.URL.String(), Weight: tg.Weight, Tags: tg.Tags, Cmd: tr.TargetConfig(tg, true), Rate1: tg.Timer.Rate1(), Pct99: tg.Timer.Percentile(0.99), } routes = append(routes, ar) } } } writeJSON(w, r, routes) }
// HandleRoutes provides a fetch handler for the current routing table. func HandleRoutes(w http.ResponseWriter, r *http.Request) { t := fabioroute.GetTable() if _, ok := r.URL.Query()["raw"]; ok { w.Header().Set("Content-Type", "text/plain") fmt.Fprintln(w, t.String()) return } var hosts []string for host := range t { hosts = append(hosts, host) } var routes []route for _, host := range hosts { for _, tr := range t[host] { for _, tg := range tr.Targets { ar := route{ Service: tg.Service, Host: tr.Host, Path: tr.Path, Dst: tg.URL.String(), Weight: tg.Weight, Tags: tg.Tags, Cmd: tr.TargetConfig(tg, true), Rate1: tg.Timer.Rate1(), Pct99: tg.Timer.Percentile(0.99), } routes = append(routes, ar) } } } writeJSON(w, r, routes) }
func handleRoute(w http.ResponseWriter, r *http.Request) { data := struct { Config []string ConfigURL string }{ route.GetTable().Config(true), configURL, } tmplTable.ExecuteTemplate(w, "table", data) }
func handleRoute(w http.ResponseWriter, r *http.Request) { dc, err := consul.Datacenter() if err != nil { http.Error(w, "cannot get datacenter: "+err.Error(), http.StatusInternalServerError) return } data := struct { Config []string ConfigURL string }{ route.GetTable().Config(true), fmt.Sprintf("%sui/#/%s/kv%s/edit", consul.URL, dc, configPath), } tmplTable.ExecuteTemplate(w, "table", data) }
/* 处理进入的连接请求 */ func (p *tcpSNIProxy) Serve(in net.Conn) { defer in.Close() // if is shutting down, then exit if ShuttingDown() { return } // capture client hello data := make([]byte, 1024) n, err := in.Read(data) if err != nil { return } data = data[:n] // 获取客户端发来的 Server Name serverName, ok := readServerName(data) if !ok { fmt.Fprintln(in, "handshake failed") log.Print("[DEBUG] tcp+sni: TLS handshake failed") return } if serverName == "" { fmt.Fprintln(in, "server_name missing") log.Print("[DEBUG] tcp+sni: server_name missing") return } // 根据Server Name 从路由表中查找路由信息 t := route.GetTable().LookupHost(serverName) if t == nil { log.Print("[WARN] tcp+sni: No route for ", serverName) return } // 连接路由对应的真实服务器 out, err := net.DialTimeout("tcp", t.URL.Host, p.cfg.DialTimeout) if err != nil { log.Print("[WARN] tcp+sni: cannot connect to upstream ", t.URL.Host) return } defer out.Close() // copy client hello _, err = out.Write(data) if err != nil { log.Print("[WARN] tcp+sni: copy client hello failed. ", err) return } errc := make(chan error, 2) cp := func(dst io.Writer, src io.Reader) { // TODO(fs): this implementation does not enforce any timeouts. // for this the io.Copy will have to be replaced with something // more sophisticated. Idea: use TeeReader/TeeWriter to discard // the second data stream and set the deadlines. _, err := io.Copy(dst, src) errc <- err } go cp(out, in) go cp(in, out) err = <-errc if err != nil && err != io.EOF { log.Print("[WARN]: tcp+sni: ", err) } }