func configWatcher(fileName string) { configReader(fileName) watcher, err := fsnotify.NewWatcher() if err != nil { fmt.Println(err) return } if err := watcher.Watch(*flagconfig); err != nil { fmt.Println(err) return } for { select { case ev := <-watcher.Event: //log.Debugf("ev.Name=%s, fileName=%s", ev.Name, fileName) if filepath.Base(ev.Name) == fileName { if ev.IsCreate() || ev.IsModify() || ev.IsRename() { time.Sleep(200 * time.Millisecond) configReader(fileName) } } case err := <-watcher.Error: log.Debugf("fsnotify error:", err) } } }
func testConnection(network, address string) error { log.Debugf("test connection") testconn, err := net.DialTimeout(network, address, time.Millisecond*100) if err != nil { log.Debugf("start run server") cmd := exec.Command(os.Args[0], "serv") timeout := time.Millisecond * 500 er := <-GoTimeoutFunc(timeout, cmd.Run) if er == ErrGoTimeout { fmt.Println("server started") } else { return fmt.Errorf("server stared failed, %v", er) } } else { testconn.Close() } return nil }
func loadRConfig() (err error) { rcfg = new(RConfig) // set default values rcfg.Server.RpcAddr = "127.0.0.1:54637" rcfg.Server.WebAddr = "127.0.0.1:54000" for _, file := range []string{"$HOME/.gosuvrc", "./gosuvrc"} { err = gcfg.ReadFileInto(rcfg, os.ExpandEnv(file)) _ = err // ignore err } log.Debugf("rcfg: %#v", rcfg) return nil }
func GoTimeoutFunc(timeout time.Duration, f func() error) chan error { ch := make(chan error) go func() { var err error select { case err = <-GoFunc(f): ch <- err case <-time.After(timeout): log.Debugf("timeout: %v", f) ch <- ErrGoTimeout } }() return ch }
func (p *ProxyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { // http://stackoverflow.com/questions/6899069/why-are-request-url-host-and-scheme-blank-in-the-development-server r.URL.Scheme = "http" // ?? r.URL.Host = r.Host // ?? log.Debug("URL path:", r.URL.Path) log.Debugf("proxy lists: %v", p.revProxies) if rpx, ok := p.revProxies[r.Host]; ok { log.Debug("server http rev proxy") rpx.ServeHTTP(w, r) return } h, _ := p.Handler(r) h.ServeHTTP(w, r) }
func main() { flag.Parse() log.SetOutputLevel(*flagdebug) configFileName := filepath.Clean(*flagconfig + "/main.conf") log.Debugf("config file '%s'\n", configFileName) log.Printf("Starting %s\n", VERSION) if *cpuprofile != "" { prof, err := os.Create(*cpuprofile) if err != nil { panic(err.Error()) } pprof.StartCPUProfile(prof) defer func() { log.Println("closing file") prof.Close() }() defer func() { log.Println("stopping profile") pprof.StopCPUProfile() }() } go configWatcher(configFileName) terminate := make(chan os.Signal) signal.Notify(terminate, os.Interrupt) <-terminate log.Printf("signal received, stopping") if *memprofile != "" { f, err := os.Create(*memprofile) if err != nil { log.Fatal(err) } pprof.WriteHeapProfile(f) f.Close() } //os.Exit(0) }
func (p *ProxyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { //log.Println("request info:", r.Method, r.Host, r.RequestURI) //host, _, _ := net.SplitHostPort(r.Host) // http://stackoverflow.com/questions/6899069/why-are-request-url-host-and-scheme-blank-in-the-development-server r.URL.Scheme = "http" // ?? r.URL.Host = r.Host // ?? log.Debug("URL path:", r.URL.Path) log.Debugf("proxy lists: %v", p.revProxies) if rpx, ok := p.revProxies[r.Host]; ok { log.Debug("server http rev proxy") rpx.ServeHTTP(w, r) return } //if p.domain != host { // http.Error(w, fmt.Sprintf("%s not ready", host), 504) // return //} h, _ := p.Handler(r) h.ServeHTTP(w, r) }
// init + build + publish + clean func (j *Builder) Auto() (addr string, err error) { lock := utils.NewNameLock(j.project) lock.Lock() defer func() { lock.Unlock() if j.wbc != nil { j.wbc.CloseWriters() } }() if err = j.init(); err != nil { return } // defer clean should start when GOPATH success created defer func() { er := j.clean() if er != nil { log.Warn(er) } if err != nil && j.wbc != nil { io.WriteString(j.wbc, err.Error()) } // FIXME: delete WriteBroadcaster after finish // if build error, output will not saved, it is not a good idea // better to change database func to -.. // SearchProject(project) AddProject(project) // SearchFile(pid, ref, os, arch) // AddFile(pid, ref, os, arch, sha) }() // download src (in order to get sha) err = j.get() if err != nil { log.Error("download src error:", err) return } // search db for history project record log.Info("request project:", j.project) log.Info("current sha:", j.sha) p, err := database.SearchProject(j.project, j.sha) if err != nil { log.Info("exists in db", j.project, j.ref, j.sha) pid, er := database.AddProject(j.project, j.ref, j.sha) if er != nil { err = er return } j.pid = pid // project id } else { j.pid = p.Id } // generate tag for builded-file search j.tag = fmt.Sprintf("%d-%s-%s", j.pid, j.os, j.arch) //log.Info("tag:", j.tag) // search memory history hisAddr, ok := history[j.tag] if ok { return hisAddr, nil } // search database history f, err := database.SearchFile(j.pid, j.tag) log.Debugf("search db: %v", f) if err == nil { addr = f.Addr return } // build xc // file maybe empty file, err := j.build(j.os, j.arch) if err != nil { log.Error("build error:", err) return } // package build file(include upload) addr, err = j.publish(file) if err != nil { return } return }
func (ps *ProxyServer) newControlHandler() func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // read listen port from request protocol, subdomain, port := parseConnectRequest(r) log.Debugf("proxy listen proto: %v, subdomain: %v port: %v", protocol, subdomain, port) // create websocket connection conn, err := upgrader.Upgrade(w, r, nil) if err != nil { http.Error(w, err.Error(), 502) return } defer conn.Close() log.Debug("remote client addr:", conn.RemoteAddr()) tunnel := &Tunnel{ wsconn: conn, } // TCP: create new port to listen log.Infof("New %s proxy for %v", protocol, conn.RemoteAddr()) switch protocol { case "tcp": // proxyAddr := fmt.Sprintf("0.0.0.0:%d", port) listener, err := NewTcpProxyListener(tunnel, port) if err != nil { log.Warnf("new tcp proxy err: %v", err) http.Error(w, err.Error(), 501) return } defer listener.Close() _, port, _ := net.SplitHostPort(listener.Addr().String()) wsSendMessage(conn, fmt.Sprintf( "Local tcp conn is now publicly available via:\n%v:%v\n", ps.domain, port)) case "http", "https": tr := &http.Transport{ Dial: tunnel.generateTransportDial(), } revProxy := &httputil.ReverseProxy{ Director: func(req *http.Request) { log.Println("director:", req.RequestURI) }, Transport: tr, } // should hook here // hook(HOOK_CREATE_HTTP_SUBDOMAIN, subdomain) // generate a uniq domain if subdomain == "" { subdomain = uniqName(5) + ".t" } pxDomain := subdomain + "." + ps.domain log.Println("http px use domain:", pxDomain) if _, exists := ps.revProxies[pxDomain]; exists { wsSendMessage(conn, fmt.Sprintf("subdomain [%s] has already been taken", pxDomain)) return } ps.Lock() ps.revProxies[pxDomain] = revProxy ps.Unlock() wsSendMessage(conn, fmt.Sprintf( "Local server is now publicly available via:\nhttp://%s\n", pxDomain)) defer func() { ps.Lock() delete(ps.revProxies, pxDomain) ps.Unlock() }() default: log.Warn("unknown protocol:", protocol) return } // HTTP: use httputil.ReverseProxy for { var msg Msg if err := conn.ReadJSON(&msg); err != nil { log.Warn(err) break } log.Info("recv json:", msg) } } }