refactor
This commit is contained in:
18
cli.go
18
cli.go
@@ -62,13 +62,17 @@ func main() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
server := NewReseeder()
|
Run(&Config{
|
||||||
server.NetDBDir = c.String("netdb")
|
NetDBDir: c.String("netdb"),
|
||||||
server.RefreshInterval = c.Duration("refresh")
|
RefreshInterval: c.Duration("refresh"),
|
||||||
server.Proxy = c.Bool("proxy")
|
Proxy: c.Bool("proxy"),
|
||||||
server.Verbose = c.Bool("verbose")
|
Verbose: c.Bool("verbose"),
|
||||||
server.RateLimit = c.Int("rateLimit")
|
RateLimit: c.Int("rateLimit"),
|
||||||
server.Start(c.String("addr"), c.String("port"), c.String("cert"), c.String("key"))
|
Addr: c.String("addr"),
|
||||||
|
Port: c.String("port"),
|
||||||
|
Cert: c.String("cert"),
|
||||||
|
Key: c.String("key"),
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
157
reseeder.go
157
reseeder.go
@@ -15,6 +15,7 @@ package main
|
|||||||
// https://geti2p.net/en/docs/spec/updates
|
// https://geti2p.net/en/docs/spec/updates
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/PuerkitoBio/throttled"
|
"github.com/PuerkitoBio/throttled"
|
||||||
"github.com/PuerkitoBio/throttled/store"
|
"github.com/PuerkitoBio/throttled/store"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
@@ -29,6 +30,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LIST_TEMPLATE = `<html><head><title>NetDB</title></head><body><ul>{{ range . }}<li><a href="{{ . }}">{{ . }}</a></li>{{ end }}</ul></body></html>`
|
||||||
|
)
|
||||||
|
|
||||||
func proxiedHandler(h http.Handler) http.Handler {
|
func proxiedHandler(h http.Handler) http.Handler {
|
||||||
return remoteAddrFixup{h}
|
return remoteAddrFixup{h}
|
||||||
}
|
}
|
||||||
@@ -44,98 +49,124 @@ func (h remoteAddrFixup) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
h.h.ServeHTTP(w, r)
|
h.h.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reseeder struct {
|
type Config struct {
|
||||||
NetDBDir string
|
NetDBDir string
|
||||||
nextMap chan []string
|
|
||||||
RefreshInterval time.Duration
|
RefreshInterval time.Duration
|
||||||
Proxy bool
|
Proxy bool
|
||||||
Verbose bool
|
Verbose bool
|
||||||
RateLimit int
|
RateLimit int
|
||||||
|
|
||||||
listTemplate *template.Template
|
Addr string
|
||||||
|
Port string
|
||||||
|
Cert string
|
||||||
|
Key string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *Reseeder) Start(addr, port, cert, key string) {
|
func Run(config *Config) {
|
||||||
var err error
|
legacyReseeder := NewLegacyReseeder(config.NetDBDir)
|
||||||
|
legacyReseeder.Start(config.RefreshInterval)
|
||||||
|
|
||||||
go rs.runMap()
|
su3Reseeder := NewSu3Reseeder(config.NetDBDir)
|
||||||
go rs.refresher()
|
su3Reseeder.Start()
|
||||||
|
|
||||||
// parse the template for routerInfo lists
|
|
||||||
rs.listTemplate, err = template.New("routerinfos").Parse(`<html><head><title>NetDB</title></head><body><ul>{{ range . }}<li><a href="{{ . }}">{{ . }}</a></li>{{ end }}</ul></body></html>`)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln("error parsing routerInfo list template", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
s := r.PathPrefix("/netdb").Subrouter()
|
s := r.PathPrefix("/netdb").Subrouter()
|
||||||
|
|
||||||
s.HandleFunc("/", rs.listHandler)
|
s.HandleFunc("/", legacyReseeder.ListHandler)
|
||||||
s.HandleFunc("/i2pseeds.su3", rs.su3Handler)
|
s.HandleFunc("/i2pseeds.su3", su3Reseeder.Su3Handler)
|
||||||
s.HandleFunc(`/routerInfo-{hash:[A-Za-z0-9+/\-=~]+}.dat`, rs.routerInfoHandler)
|
s.HandleFunc(`/routerInfo-{hash:[A-Za-z0-9+/\-=~]+}.dat`, legacyReseeder.RouterInfoHandler)
|
||||||
|
|
||||||
// timeout
|
// timeout
|
||||||
muxWithMiddlewares := http.TimeoutHandler(r, time.Second*5, "Timeout!")
|
muxWithMiddlewares := http.TimeoutHandler(r, time.Second*5, "Timeout!")
|
||||||
|
|
||||||
th := throttled.RateLimit(throttled.PerMin(rs.RateLimit), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(1000))
|
th := throttled.RateLimit(throttled.PerMin(config.RateLimit), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(1000))
|
||||||
muxWithMiddlewares = th.Throttle(muxWithMiddlewares)
|
muxWithMiddlewares = th.Throttle(muxWithMiddlewares)
|
||||||
|
|
||||||
if rs.Proxy {
|
if config.Proxy {
|
||||||
muxWithMiddlewares = proxiedHandler(muxWithMiddlewares)
|
muxWithMiddlewares = proxiedHandler(muxWithMiddlewares)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rs.Verbose {
|
if config.Verbose {
|
||||||
muxWithMiddlewares = handlers.CombinedLoggingHandler(os.Stdout, muxWithMiddlewares)
|
muxWithMiddlewares = handlers.CombinedLoggingHandler(os.Stdout, muxWithMiddlewares)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listenAddress := fmt.Sprintf("%s:%s", config.Addr, config.Port)
|
||||||
|
|
||||||
// try to start tls server
|
// try to start tls server
|
||||||
if _, err = os.Stat(cert); err == nil {
|
if config.Cert != "" && config.Key != "" {
|
||||||
if _, err = os.Stat(key); err == nil {
|
log.Println("Starting TLS reseed server on " + listenAddress)
|
||||||
log.Println("Starting TLS reseed server on " + addr + ":" + port)
|
err := http.ListenAndServeTLS(listenAddress, config.Cert, config.Key, muxWithMiddlewares)
|
||||||
err := http.ListenAndServeTLS(addr+":"+port, cert, key, muxWithMiddlewares)
|
if nil != err {
|
||||||
if nil != err {
|
log.Fatalln(err)
|
||||||
log.Fatalln(err)
|
}
|
||||||
|
} else {
|
||||||
|
// fall back to regular http server
|
||||||
|
log.Println("Starting reseed server on " + listenAddress)
|
||||||
|
err := http.ListenAndServe(listenAddress, muxWithMiddlewares)
|
||||||
|
if nil != err {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLegacyReseeder(netdbDir string) *LegacyReseeder {
|
||||||
|
return &LegacyReseeder{netdbDir: netdbDir, nextMap: make(chan []string)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSu3Reseeder(netdbDir string) *Su3Reseeder {
|
||||||
|
return &Su3Reseeder{netdbDir: netdbDir, nextMap: make(chan []string)}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Su3Reseeder struct {
|
||||||
|
nextMap chan []string
|
||||||
|
netdbDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Su3Reseeder) Start() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rs *Su3Reseeder) Su3Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
type LegacyReseeder struct {
|
||||||
|
nextMap chan []string
|
||||||
|
netdbDir string
|
||||||
|
listTemplate *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *LegacyReseeder) Start(refreshInterval time.Duration) {
|
||||||
|
go func() {
|
||||||
|
var m []string
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case m = <-r.nextMap:
|
||||||
|
case r.nextMap <- m:
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
|
|
||||||
// fall back to regular http server
|
go func() {
|
||||||
log.Println("Starting reseed server on " + addr + ":" + port)
|
for {
|
||||||
err = http.ListenAndServe(addr+":"+port, muxWithMiddlewares)
|
log.Println("Updating routerInfos")
|
||||||
if nil != err {
|
r.Refresh()
|
||||||
log.Fatalln(err)
|
time.Sleep(refreshInterval)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReseeder() *Reseeder {
|
|
||||||
return &Reseeder{nextMap: make(chan []string)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reseeder) runMap() {
|
|
||||||
var m []string
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case m = <-r.nextMap:
|
|
||||||
case r.nextMap <- m:
|
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// parse the template for routerInfo lists
|
||||||
|
var err error
|
||||||
|
r.listTemplate, err = template.New("ri").Parse(LIST_TEMPLATE)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("error parsing routerInfo list template", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reseeder) refresher() {
|
func (r *LegacyReseeder) Refresh() {
|
||||||
for {
|
|
||||||
log.Println("Updating routerInfos")
|
|
||||||
r.Refresh()
|
|
||||||
time.Sleep(r.RefreshInterval)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reseeder) Refresh() {
|
|
||||||
var m []string
|
var m []string
|
||||||
|
|
||||||
src, err := ioutil.ReadDir(r.NetDBDir)
|
src, err := ioutil.ReadDir(r.netdbDir)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
log.Fatalln("error reading netdb dir", err)
|
log.Fatalln("error reading netdb dir", err)
|
||||||
return
|
return
|
||||||
@@ -162,21 +193,17 @@ func (r *Reseeder) Refresh() {
|
|||||||
r.nextMap <- m
|
r.nextMap <- m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *Reseeder) listHandler(w http.ResponseWriter, r *http.Request) {
|
func (lr *LegacyReseeder) ListHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
err := rs.listTemplate.Execute(w, <-rs.nextMap)
|
err := lr.listTemplate.Execute(w, <-lr.nextMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("error rending list template", err)
|
log.Fatalln("error rending list template", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *Reseeder) su3Handler(w http.ResponseWriter, r *http.Request) {
|
func (rs *LegacyReseeder) RouterInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
http.NotFound(w, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rs *Reseeder) routerInfoHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
fileName := "routerInfo-" + vars["hash"] + ".dat"
|
fileName := "routerInfo-" + vars["hash"] + ".dat"
|
||||||
f, err := os.Open(rs.NetDBDir + "/" + fileName)
|
f, err := os.Open(rs.netdbDir + "/" + fileName)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
log.Println("error sending file", err)
|
log.Println("error sending file", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user