func main() { conf := struct { Domain string `flag:"domain,use this domain name during TLS handshake"` Addr string `flag:"addr,host:port to connect to (defaults to domain:443)"` File string `flag:"file,read domain+addr pairs from this CSV file"` Before time.Duration `flag:"exp,warn if certificate will expire in this period of time"` }{ Before: time.Duration(30*24) * time.Hour, } autoflags.Define(&conf) flag.Parse() if conf.File == "" { check(conf.Domain, conf.Addr, conf.Before) return } f, err := os.Open(conf.File) if err != nil { log.Fatal(err) } defer f.Close() rd := csv.NewReader(f) rd.FieldsPerRecord = -1 rd.Comment = '#' rd.TrimLeadingSpace = true g := newGate(5) for { rec, err := rd.Read() if err == io.EOF { break } if err != nil { log.Print(err) break } switch len(rec) { case 1: g.Lock() go func(d string) { check(d, "", conf.Before); g.Unlock() }(rec[0]) case 2: g.Lock() go func(d, a string) { check(d, a, conf.Before); g.Unlock() }(rec[0], rec[1]) default: log.Print("csv line skipped: invalid number of fields", len(rec)) } } // by acquiring gate lock as many times as its capacity we make sure // that none other goroutines hold it for i := 0; i < cap(g); i++ { g.Lock() } }
func main() { cfg.Addr = ":8080" cfg.Scheme = "http" cfg.Host = "localhost:80" cfg.BasePath = "" cfg.LogReq = true cfg.LogResp = false autoflags.Define(&cfg) flag.Parse() proxy = httputil.NewSingleHostReverseProxy(&url.URL{Scheme: cfg.Scheme, Host: cfg.Host, Path: cfg.BasePath}) http.ListenAndServe(cfg.Addr, http.HandlerFunc(logServe)) }
func main() { autoflags.Define(&config) flag.Parse() log.SetLevelByString(config.LogLevel) // to avoid pprof being optimized by gofmt log.Debug(pprof.Handler("profile")) if len(config.LogFile) != 0 { log.SetOutputByName(config.LogFile) log.SetRotateByDay() } if config.LogEveryN <= 0 { proxy.LogEveryN = 1 } else { proxy.LogEveryN = config.LogEveryN } log.Infof("%#v", config) sigChan := make(chan os.Signal) signal.Notify(sigChan, os.Interrupt, os.Kill) log.Infof("pid %d", os.Getpid()) if len(config.DebugAddr) != 0 { http.HandleFunc("/setloglevel", handleSetLogLevel) go func() { log.Fatal(http.ListenAndServe(config.DebugAddr, nil)) }() log.Infof("debug service listens on %s", config.DebugAddr) } // shuffle startup nodes startupNodes := strings.Split(config.StartupNodes, ",") indexes := rand.Perm(len(startupNodes)) for i, startupNode := range startupNodes { startupNodes[i] = startupNodes[indexes[i]] startupNodes[indexes[i]] = startupNode } connPool := proxy.NewConnPool(config.BackendIdleConnections, config.ConnectTimeout, config.ReadPrefer != proxy.READ_PREFER_MASTER) dispatcher := proxy.NewDispatcher(startupNodes, config.SlotsReloadInterval, connPool, config.ReadPrefer) if err := dispatcher.InitSlotTable(); err != nil { log.Fatal(err) } proxy := proxy.NewProxy(config.Addr, dispatcher, connPool) go proxy.Run() sig := <-sigChan log.Infof("terminated by %#v", sig) proxy.Exit() }
func main() { params := struct { User string `flag:"user,ssh connection username"` Addr string `flag:"addr,ssh host:port"` Dir string `flag:"dir,remote directory to upload files to"` Url string `flag:"url,remote url base to open after upload"` Long bool `flag:"long,generate long subdirectory name"` }{ User: os.Getenv("USER"), Addr: "localhost:22", Dir: "/tmp", } autoflags.Define(¶ms) flag.Parse() cfg, err := config(params.User) if err != nil { log.Fatal(err) } res, err := upload(params.Addr, params.Dir, params.Long, cfg, flag.Args()) if res != "" { fmt.Println(res) if params.Url != "" { browser.OpenURL(path.Join(params.Url, path.Base(res))) } } if err != nil { log.Fatal(err) } }