refactor: move types into a single file for each package

This commit is contained in:
2024-11-04 08:34:47 +01:00
parent b0443c34d7
commit 096290bcb8
9 changed files with 326 additions and 283 deletions

View File

@@ -24,18 +24,6 @@ import (
"net/http"
)
// InterceptErrors contains backend status code errors to intercept
type InterceptErrors struct {
Errors []int
}
// responseRecorder intercepts the response body and status code
type responseRecorder struct {
http.ResponseWriter
statusCode int
body *bytes.Buffer
}
func newResponseRecorder(w http.ResponseWriter) *responseRecorder {
return &responseRecorder{
ResponseWriter: w,
@@ -59,7 +47,7 @@ func (intercept InterceptErrors) ErrorInterceptor(next http.Handler) http.Handle
next.ServeHTTP(rec, r)
if canIntercept(rec.statusCode, intercept.Errors) {
logger.Error("Backend error")
logger.Error("An error occurred in the backend, %d", rec.statusCode)
logger.Error("An error occurred from the backend with the status code: %d", rec.statusCode)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(rec.statusCode)
err := json.NewEncoder(w).Encode(ProxyResponseError{

View File

@@ -23,78 +23,8 @@ import (
"net/http"
"net/url"
"strings"
"sync"
"time"
)
// RateLimiter defines rate limit properties.
type RateLimiter struct {
Requests int
Window time.Duration
ClientMap map[string]*Client
mu sync.Mutex
}
// Client stores request count and window expiration for each client.
type Client struct {
RequestCount int
ExpiresAt time.Time
}
// NewRateLimiterWindow creates a new RateLimiter.
func NewRateLimiterWindow(requests int, window time.Duration) *RateLimiter {
return &RateLimiter{
Requests: requests,
Window: window,
ClientMap: make(map[string]*Client),
}
}
// TokenRateLimiter stores tokenRate limit
type TokenRateLimiter struct {
tokens int
maxTokens int
refillRate time.Duration
lastRefill time.Time
mu sync.Mutex
}
// ProxyResponseError represents the structure of the JSON error response
type ProxyResponseError struct {
Success bool `json:"success"`
Code int `json:"code"`
Message string `json:"message"`
}
// JwtAuth stores JWT configuration
type JwtAuth struct {
AuthURL string
RequiredHeaders []string
Headers map[string]string
Params map[string]string
}
// AuthenticationMiddleware Define struct
type AuthenticationMiddleware struct {
AuthURL string
RequiredHeaders []string
Headers map[string]string
Params map[string]string
}
type AccessListMiddleware struct {
Path string
Destination string
List []string
}
// AuthBasic contains Basic auth configuration
type AuthBasic struct {
Username string
Password string
Headers map[string]string
Params map[string]string
}
// AuthMiddleware authenticate the client using JWT
//
// authorization based on the result of backend's response and continue the request when the client is authorized

View File

@@ -34,7 +34,7 @@ func (rl *TokenRateLimiter) RateLimitMiddleware() mux.MiddlewareFunc {
err := json.NewEncoder(w).Encode(ProxyResponseError{
Success: false,
Code: http.StatusTooManyRequests,
Message: "Too many requests. Please try again later.",
Message: "Too many requests, API rate limit exceeded. Please try again later.",
})
if err != nil {
return
@@ -66,13 +66,13 @@ func (rl *RateLimiter) RateLimitMiddleware() mux.MiddlewareFunc {
rl.mu.Unlock()
if client.RequestCount > rl.Requests {
logger.Error("Too many request from IP: %s %s %s", clientID, r.URL, r.UserAgent())
logger.Error("Too many requests from IP: %s %s %s", clientID, r.URL, r.UserAgent())
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusTooManyRequests)
err := json.NewEncoder(w).Encode(ProxyResponseError{
Success: false,
Code: http.StatusTooManyRequests,
Message: "Too many requests. Please try again later.",
Message: "Too many requests, API rate limit exceeded. Please try again later.",
})
if err != nil {
return

105
pkg/middleware/types.go Normal file
View File

@@ -0,0 +1,105 @@
/*
* Copyright 2024 Jonas Kaninda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package middleware
import (
"bytes"
"net/http"
"sync"
"time"
)
// RateLimiter defines rate limit properties.
type RateLimiter struct {
Requests int
Window time.Duration
ClientMap map[string]*Client
mu sync.Mutex
}
// Client stores request count and window expiration for each client.
type Client struct {
RequestCount int
ExpiresAt time.Time
}
// NewRateLimiterWindow creates a new RateLimiter.
func NewRateLimiterWindow(requests int, window time.Duration) *RateLimiter {
return &RateLimiter{
Requests: requests,
Window: window,
ClientMap: make(map[string]*Client),
}
}
// TokenRateLimiter stores tokenRate limit
type TokenRateLimiter struct {
tokens int
maxTokens int
refillRate time.Duration
lastRefill time.Time
mu sync.Mutex
}
// ProxyResponseError represents the structure of the JSON error response
type ProxyResponseError struct {
Success bool `json:"success"`
Code int `json:"code"`
Message string `json:"message"`
}
// JwtAuth stores JWT configuration
type JwtAuth struct {
AuthURL string
RequiredHeaders []string
Headers map[string]string
Params map[string]string
}
// AuthenticationMiddleware Define struct
type AuthenticationMiddleware struct {
AuthURL string
RequiredHeaders []string
Headers map[string]string
Params map[string]string
}
type AccessListMiddleware struct {
Path string
Destination string
List []string
}
// AuthBasic contains Basic auth configuration
type AuthBasic struct {
Username string
Password string
Headers map[string]string
Params map[string]string
}
// InterceptErrors contains backend status code errors to intercept
type InterceptErrors struct {
Errors []int
}
// responseRecorder intercepts the response body and status code
type responseRecorder struct {
http.ResponseWriter
statusCode int
body *bytes.Buffer
}