showdot bool
indexes bool
timeout int
+ crate int
+ cburst int
+ njobs int
+ nworker int
logfile string
verbose bool
}{
showdot: false,
indexes: false,
timeout: 60,
+ crate: 5,
+ cburst: 50,
+ nworker: 6,
+ njobs: 50,
logfile: "",
verbose: false,
}
cfg.indexes = strToBool(val)
case "timeout":
cfg.timeout, _ = strconv.Atoi(val)
+ case "crate":
+ cfg.crate, _ = strconv.Atoi(val)
+ case "cburst":
+ cfg.cburst, _ = strconv.Atoi(val)
+ case "nworker":
+ cfg.nworker, _ = strconv.Atoi(val)
+ case "njobs":
+ cfg.njobs, _ = strconv.Atoi(val)
case "logfile":
cfg.logfile = val
case "verbose":
var err error
help := false
cfgfile := ""
- flag.StringVar(&cfgfile, "c", cfgfile, "configuration file")
+ flag.StringVar(&cfgfile, "c", cfgfile, "read configuration from `file`")
flag.StringVar(&cfg.iface, "i", cfg.iface, "interface to bind to; empty for any")
- flag.StringVar(&cfg.port, "p", cfg.port, "TCP port to listen on")
+ flag.StringVar(&cfg.port, "p", cfg.port, "TCP `port` to listen on")
flag.StringVar(&cfg.fqdn, "f", cfg.fqdn, "fully qualified domain name")
- flag.StringVar(&cfg.docroot, "r", cfg.docroot, "document root directory")
- flag.StringVar(&cfg.idxpage, "I", cfg.idxpage, "directory index page")
- flag.StringVar(&cfg.header, "H", cfg.header, "header file to prepend to generated pages")
- flag.StringVar(&cfg.footer, "F", cfg.footer, "footer file to append to generated pages")
- flag.BoolVar(&help, "h", help, "show this help page")
+ flag.StringVar(&cfg.docroot, "r", cfg.docroot, "document root `directory`")
+ flag.StringVar(&cfg.idxpage, "I", cfg.idxpage, "directory index `file` name")
+ flag.StringVar(&cfg.header, "H", cfg.header, "header: prepend contents of `file` to generated pages")
+ flag.StringVar(&cfg.footer, "F", cfg.footer, "footer: append contents of `file` to generated pages")
+ flag.BoolVar(&help, "h", help, "display this help message")
flag.BoolVar(&cfg.fsymln, "s", cfg.fsymln, "follow symbolic links")
flag.BoolVar(&cfg.showdot, "d", cfg.showdot, "allow access to dotfiles")
flag.BoolVar(&cfg.indexes, "D", cfg.indexes, "allow generated directory indexes")
- flag.IntVar(&cfg.timeout, "t", cfg.timeout, "connection read/write timeout in seconds")
- flag.StringVar(&cfg.logfile, "L", cfg.logfile, "write log to file; empty for stderr")
+ flag.IntVar(&cfg.timeout, "t", cfg.timeout, "connection read/write timeout in `seconds`")
+ flag.IntVar(&cfg.crate, "lc", cfg.crate, "set connections per second rate limit to `num`")
+ flag.IntVar(&cfg.cburst, "lb", cfg.cburst, "set connection burst limit to `num`")
+ flag.IntVar(&cfg.nworker, "lw", cfg.nworker, "set number of worker threads to `num`")
+ flag.IntVar(&cfg.njobs, "lj", cfg.njobs, "set worker job queue size to `num`")
+ flag.StringVar(&cfg.logfile, "L", cfg.logfile, "write log to `file`; empty for stderr")
flag.BoolVar(&cfg.verbose, "v", cfg.verbose, "produce verbose output")
flag.Parse()
if help {
tracer.Print("showdot: ", cfg.showdot)
tracer.Print("indexes: ", cfg.indexes)
tracer.Print("timeout: ", cfg.timeout)
+ tracer.Print("crate: ", cfg.crate)
+ tracer.Print("cburst: ", cfg.cburst)
+ tracer.Print("nworker: ", cfg.nworker)
+ tracer.Print("njobs: ", cfg.njobs)
tracer.Print("verbose: ", cfg.verbose)
tracer.Print("gogopherd version ", version)
}
func serveTCP(listener *net.TCPListener) {
// connection rate limiter
- rate := 5
- burst := 50
- interval := time.Second / time.Duration(rate)
- tick := time.NewTicker(interval)
+ tick := time.NewTicker(time.Second / time.Duration(cfg.crate))
defer tick.Stop()
- throttle := make(chan time.Time, burst)
+ throttle := make(chan time.Time, cfg.cburst)
go func() {
for t := range tick.C {
select {
}
}()
// worker and job queue setup
- nworker := 5
- njobs := 50
- jobs := make(chan net.Conn, njobs)
- for w := 1; w <= nworker; w++ {
+ jobs := make(chan net.Conn, cfg.njobs)
+ for w := 1; w <= cfg.nworker; w++ {
go func(id int, jobs <-chan net.Conn) {
for j := range jobs {
tracer.Print("worker id ", id, ": ", j.RemoteAddr())