Skip to content

Commit

Permalink
integrated sliding window rate limit on frontend client
Browse files Browse the repository at this point in the history
  • Loading branch information
x-sushant-x committed Nov 11, 2024
1 parent 6b6554d commit c98576c
Show file tree
Hide file tree
Showing 7 changed files with 371 additions and 96 deletions.
174 changes: 174 additions & 0 deletions rate_shield/api/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RateShield Status</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f3f4f6;
color: #333;
}
.container {
text-align: center;
padding: 2rem;
max-width: 600px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
h1 {
color: #4a90e2;
margin-bottom: 1rem;
}
p {
font-size: 1.1rem;
margin-bottom: 1.5rem;
}
.button {
display: inline-block;
padding: 0.8rem 1.5rem;
margin-top: 1rem;
font-size: 1rem;
font-weight: bold;
color: #fff;
background-color: #4a90e2;
border: none;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: #357ABD;
}
.instructions {
font-size: 0.9rem;
margin-top: 1.5rem;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>RateShield is Running!</h1>
<p>Welcome to the RateShield rate limiter. The server is currently active on this port.</p>
<a href="#" class="button">Default Frontend Port: 5173</a>
<p class="instructions">If the frontend is not accessible, ensure the React application is running. Use:</p>
<code class="instructions">npm run dev</code>
</div>
</body>
</html> -->


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RateShield Status</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, sans-serif;
}

body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #eaeaea;
color: #333;
}

.container {
text-align: center;
padding: 2rem;
max-width: 500px;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

h1 {
color: #333;
font-size: 1.8rem;
margin-bottom: 1rem;
}

p {
font-size: 1rem;
color: #555;
margin-bottom: 1rem;
line-height: 1.5;
}

.button {
display: inline-block;
padding: 0.6rem 1.5rem;
margin-top: 1rem;
font-size: 0.95rem;
color: #ffffff;
background-color: #4a90e2;
border: none;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
transition: background-color 0.3s ease;
}

.button:hover {
background-color: #3b7bbf;
}

.instructions {
font-size: 0.85rem;
color: #666;
margin-top: 1rem;
}

code.instructions {
display: block;
font-size: 0.85rem;
margin-top: 0.5rem;
background-color: #f7f7f7;
color: #333;
padding: 0.3rem 0.6rem;
border-radius: 4px;
}
</style>
</head>
<body>

<div class="container">
<h1>RateShield is Running</h1>
<p>Welcome to the RateShield rate limiter. The server is currently active on this port.</p>
<a href="#" class="button">Default Frontend Port: 5173</a>
<p class="instructions">If the frontend is not accessible, ensure the React application is running. Use:</p>
<code class="instructions">npm run dev</code>
</div>

</body>
</html>
23 changes: 20 additions & 3 deletions rate_shield/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"fmt"
"net/http"
"os"

"github.com/rs/zerolog/log"
"github.com/x-sushant-x/RateShield/limiter"
Expand All @@ -23,11 +24,12 @@ func NewServer(port int, limiter limiter.Limiter) Server {
}

func (s Server) StartServer() error {
log.Info().Msg("Setting Up API Endpoints ✅")
log.Info().Msg("Setting Up API endpoints ✅")
mux := http.NewServeMux()

s.rulesRoutes(mux)
s.registerRateLimiterRoutes(mux)
s.setupHome(mux)

corsMux := s.setupCORS(mux)

Expand All @@ -36,7 +38,7 @@ func (s Server) StartServer() error {
Handler: corsMux,
}

log.Info().Msg("Rate Shield Running ✅")
log.Info().Msg("Rate Shield running on port: " + fmt.Sprintf("%d", s.port) + " ✅")

err := server.ListenAndServe()
if err != nil {
Expand Down Expand Up @@ -79,6 +81,21 @@ func (s Server) rulesRoutes(mux *http.ServeMux) {

func (s Server) registerRateLimiterRoutes(mux *http.ServeMux) {
rateLimiterHandler := NewRateLimitHandler(s.limiter)

mux.HandleFunc("/check-limit", rateLimiterHandler.CheckRateLimit)
}

func (s Server) setupHome(mux *http.ServeMux) {
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")

wd, wdError := os.Getwd()

homepage, err := os.ReadFile(wd + "/api/" + "index.html")
if err != nil || wdError != nil {
fmt.Println(err)
w.Write([]byte("Rate Shield is running. Open frontend client on port 5173. If it does not work make sure react application is running."))
}

fmt.Fprint(w, string(homepage))
})
}
2 changes: 1 addition & 1 deletion rate_shield/limiter/limiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (l *Limiter) GetRule(key string) (*models.Rule, bool, error) {
}

func (l *Limiter) StartRateLimiter() {
log.Info().Msg("Starting Limiter Service ✅")
log.Info().Msg("Starting limiter service ✅")
l.cachedRules = l.redisRuleSvc.CacheRulesLocally()
l.tokenBucket.startAddTokenJob()
go l.listenToRulesUpdate()
Expand Down
7 changes: 7 additions & 0 deletions web/src/api/rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface rule {
endpoint: string;
http_method: string;
fixed_window_counter_rule: fixedWindowCounterRule | null;
sliding_window_counter_rule: slidingWindowCounterRule | null;
token_bucket_rule: tokenBucketRule | null;
allow_on_error: boolean;
}
Expand All @@ -27,6 +28,12 @@ export interface fixedWindowCounterRule {
window: number;
}

export interface slidingWindowCounterRule {
max_requests: number;
window: number;
}


export interface tokenBucketRule {
bucket_capacity: number;
token_add_rate: number;
Expand Down
Loading

0 comments on commit c98576c

Please sign in to comment.