Пример #1
0
func NewTestConfig() Config {
	return Config{
		DatabaseUrl:            test.DatabaseUrl(),
		StellarCoreDatabaseUrl: test.StellarCoreDatabaseUrl(),
		RateLimit:              throttled.PerHour(1000),
	}
}
Пример #2
0
func NewTestConfig() Config {
	return Config{
		DatabaseURL:            test.DatabaseURL(),
		StellarCoreDatabaseURL: test.StellarCoreDatabaseURL(),
		RateLimit:              throttled.PerHour(1000),
		LogLevel:               hlog.InfoLevel,
	}
}
Пример #3
0
func initConfig() {
	if viper.GetString("db-url") == "" {
		log.Fatal("Invalid config: db-url is blank.  Please specify --db-url on the command line or set the DATABASE_URL environment variable.")
	}

	if viper.GetString("stellar-core-db-url") == "" {
		log.Fatal("Invalid config: stellar-core-db-url is blank.  Please specify --stellar-core-db-url on the command line or set the STELLAR_CORE_DATABASE_URL environment variable.")
	}

	if viper.GetString("stellar-core-url") == "" {
		log.Fatal("Invalid config: stellar-core-url is blank.  Please specify --stellar-core-url on the command line or set the STELLAR_CORE_URL environment variable.")
	}

	ll, err := logrus.ParseLevel(viper.GetString("log-level"))

	if err != nil {
		log.Fatalf("Could not parse log-level: %v", viper.GetString("log-level"))
	}

	hlog.DefaultLogger.Level = ll

	cert, key := viper.GetString("tls-cert"), viper.GetString("tls-key")

	switch {
	case cert != "" && key == "":
		log.Fatal("Invalid TLS config: key not configured")
	case cert == "" && key != "":
		log.Fatal("Invalid TLS config: cert not configured")
	}

	config = horizon.Config{
		DatabaseURL:            viper.GetString("db-url"),
		StellarCoreDatabaseURL: viper.GetString("stellar-core-db-url"),
		StellarCoreURL:         viper.GetString("stellar-core-url"),
		Autopump:               viper.GetBool("autopump"),
		Port:                   viper.GetInt("port"),
		RateLimit:              throttled.PerHour(viper.GetInt("per-hour-rate-limit")),
		RedisURL:               viper.GetString("redis-url"),
		LogLevel:               ll,
		SentryDSN:              viper.GetString("sentry-dsn"),
		LogglyToken:            viper.GetString("loggly-token"),
		LogglyHost:             viper.GetString("loggly-host"),
		FriendbotSecret:        viper.GetString("friendbot-secret"),
		TLSCert:                cert,
		TLSKey:                 key,
		Ingest:                 viper.GetBool("ingest"),
	}
}
Пример #4
0
func run(cmd *cobra.Command, args []string) {

	var err error

	if viper.GetString("db-url") == "" {
		rootCmd.Help()
		os.Exit(1)
	}

	if viper.GetString("stellar-core-db-url") == "" {
		rootCmd.Help()
		os.Exit(1)
	}

	ll, err := logrus.ParseLevel(viper.GetString("log-level"))

	if err != nil {
		log.Fatalf("Could not parse log-level: %v", viper.GetString("log-level"))
	}

	hlog.DefaultLogger.Level = ll

	config := horizon.Config{
		DatabaseUrl:            viper.GetString("db-url"),
		StellarCoreDatabaseUrl: viper.GetString("stellar-core-db-url"),
		StellarCoreUrl:         viper.GetString("stellar-core-url"),
		Autopump:               viper.GetBool("autopump"),
		Port:                   viper.GetInt("port"),
		RateLimit:              throttled.PerHour(viper.GetInt("per-hour-rate-limit")),
		RedisUrl:               viper.GetString("redis-url"),
		RubyHorizonUrl:         viper.GetString("ruby-horizon-url"),
		LogLevel:               ll,
		SentryDSN:              viper.GetString("sentry-dsn"),
		LogglyToken:            viper.GetString("loggly-token"),
		LogglyHost:             viper.GetString("loggly-host"),
		FriendbotSecret:        viper.GetString("friendbot-secret"),
	}

	app, err = horizon.NewApp(config)

	if err != nil {
		log.Fatal(err.Error())
	}

	app.Serve()
}
func TestRateLimitMiddleware(t *testing.T) {

	Convey("Rate Limiting", t, func() {
		c := NewTestConfig()
		c.RateLimit = throttled.PerHour(10)
		app, _ := NewApp(c)
		defer app.Close()
		rh := NewRequestHelper(app)

		Convey("sets X-RateLimit-Limit headers correctly", func() {
			w := rh.Get("/", test.RequestHelperNoop)
			So(w.Code, ShouldEqual, 200)
			So(w.Header().Get("X-RateLimit-Limit"), ShouldEqual, "10")
		})

		Convey("sets X-RateLimit-Remaining headers correctly", func() {
			for i := 0; i < 10; i++ {
				w := rh.Get("/", test.RequestHelperNoop)
				expected := 10 - (i + 1)
				So(w.Header().Get("X-RateLimit-Remaining"), ShouldEqual, strconv.Itoa(expected))
			}

			// confirm remaining stays at 0
			for i := 0; i < 10; i++ {
				w := rh.Get("/", test.RequestHelperNoop)
				So(w.Header().Get("X-RateLimit-Remaining"), ShouldEqual, "0")
			}
		})

		Convey("sets X-RateLimit-Reset header correctly", func() {
			w := rh.Get("/", test.RequestHelperNoop)
			So(w.Header().Get("X-RateLimit-Reset"), ShouldEqual, "3599")
		})

		Convey("Restricts based on RemoteAddr IP after too many requests", func() {
			for i := 0; i < 10; i++ {
				w := rh.Get("/", test.RequestHelperNoop)
				So(w.Code, ShouldEqual, 200)
			}

			w := rh.Get("/", test.RequestHelperNoop)
			So(w.Code, ShouldEqual, 429)

			w = rh.Get("/", test.RequestHelperRemoteAddr("127.0.0.2"))
			So(w.Code, ShouldEqual, 200)

			// Ignores ports
			w = rh.Get("/", test.RequestHelperRemoteAddr("127.0.0.1:4312"))
			So(w.Code, ShouldEqual, 429)
		})

		Convey("Restrict based upon X-Forwarded-For correctly", func() {
			for i := 0; i < 10; i++ {
				w := rh.Get("/", test.RequestHelperXFF("4.4.4.4"))
				So(w.Code, ShouldEqual, 200)
			}

			w := rh.Get("/", test.RequestHelperXFF("4.4.4.4"))
			So(w.Code, ShouldEqual, 429)

			// allow other ips
			w = rh.Get("/", test.RequestHelperRemoteAddr("4.4.4.3"))
			So(w.Code, ShouldEqual, 200)

			// Ignores leading private ips
			w = rh.Get("/", test.RequestHelperXFF("10.0.0.1, 4.4.4.4"))
			So(w.Code, ShouldEqual, 429)

			// Ignores trailing ips
			w = rh.Get("/", test.RequestHelperXFF("4.4.4.4, 4.4.4.5, 127.0.0.1"))
			So(w.Code, ShouldEqual, 429)

		})
	})

	Convey("Rate Limiting works with redis", t, func() {
		c := NewTestConfig()
		c.RateLimit = throttled.PerHour(10)
		c.RedisUrl = "redis://127.0.0.1:6379/"
		app, _ := NewApp(c)
		defer app.Close()
		rh := NewRequestHelper(app)

		redis := app.redis.Get()
		_, err := redis.Do("FLUSHDB")
		So(err, ShouldBeNil)

		for i := 0; i < 10; i++ {
			w := rh.Get("/", test.RequestHelperNoop)
			So(w.Code, ShouldEqual, 200)
		}

		w := rh.Get("/", test.RequestHelperNoop)
		So(w.Code, ShouldEqual, 429)

		w = rh.Get("/", test.RequestHelperRemoteAddr("127.0.0.2"))
		So(w.Code, ShouldEqual, 200)
	})
}