func main() { runtime.GOMAXPROCS(runtime.NumCPU()) flag.Parse() if *profile != "" { flag, err := os.Create(*profile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(flag) defer pprof.StopCPUProfile() } if *authTokenFlag == "" { *authTokenFlag = "public" log.Println("Using default Token", *authTokenFlag) } if *certFile == "" || *keyFile == "" { log.Error("need cert file and key file .pem") return } th := throttled.RateLimit(throttled.PerMin(30), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(100), ) mux := http.NewServeMux() mux.Handle("/remoton/", http.StripPrefix("/remoton", remoton.NewServer(func(authToken string, r *http.Request) bool { return authToken == *authTokenFlag }, func() string { return uuid.NewV4().String()[0:8] }))) log.Println("Listen at HTTPS ", *listenAddr) sSecure := &http.Server{ Addr: *listenAddr, Handler: th.Throttle(mux), } host, port, err := net.SplitHostPort(*listenAddr) if err != nil { log.Fatal(err) } iport, err := strconv.Atoi(port) if err != nil { panic(err) } listenInsecureAddr := net.JoinHostPort(host, strconv.Itoa(iport-1)) //Default insecure it's a previous port log.Println("Listen at HTTP ", listenInsecureAddr) sInsecure := &http.Server{ Addr: listenInsecureAddr, Handler: th.Throttle(mux), } go sInsecure.ListenAndServe() log.Fatal(sSecure.ListenAndServeTLS(*certFile, *keyFile)) }
// Ensure that the current implementation remains compatible with the // supported but deprecated usage until the next major version. func TestDeprecatedUsage(t *testing.T) { // Declare interfaces to statically check that names haven't changed var st throttled.Store var thr *throttled.Throttler var q throttled.Quota st = store.NewMemStore(100) vary := &throttled.VaryBy{Path: true} q = throttled.PerMin(2) thr = throttled.RateLimit(q, vary, st) handler := thr.Throttle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })) cases := []struct { path string code int headers map[string]string }{ {"/foo", 200, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "1", "X-Ratelimit-Reset": "30"}}, {"/foo", 200, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "0", "X-Ratelimit-Reset": "60"}}, {"/foo", 429, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "0", "X-Ratelimit-Reset": "60", "Retry-After": "30"}}, {"/bar", 200, map[string]string{"X-Ratelimit-Limit": "2", "X-Ratelimit-Remaining": "1", "X-Ratelimit-Reset": "30"}}, } for i, c := range cases { req, err := http.NewRequest("GET", c.path, nil) if err != nil { t.Fatal(err) } rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) if have, want := rr.Code, c.code; have != want { t.Errorf("Expected request %d at %s to return %d but got %d", i, c.path, want, have) } for name, want := range c.headers { if have := rr.HeaderMap.Get(name); have != want { t.Errorf("Expected request %d at %s to have header '%s: %s' but got '%s'", i, c.path, name, want, have) } } } }
func NewServer(prefix string, trustProxy bool) *Server { config := &tls.Config{ MinVersion: tls.VersionTLS10, PreferServerCipherSuites: true, CipherSuites: []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, }, } h := &http.Server{TLSConfig: config} server := Server{Server: h, Reseeder: nil} th := throttled.RateLimit(throttled.PerDay(4), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(200000)) middlewareChain := alice.New() if trustProxy { middlewareChain = middlewareChain.Append(proxiedMiddleware) } errorHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) if _, err := w.Write(nil); nil != err { log.Println(err) } }) mux := http.NewServeMux() mux.Handle("/", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware).Then(errorHandler)) mux.Handle(prefix+"/i2pseeds.su3", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, verifyMiddleware, th.Throttle).Then(http.HandlerFunc(server.reseedHandler))) server.Handler = mux return &server }