Use X-Forwarded-For, add comments

This commit is contained in:
Neil Alexander 2020-09-02 17:26:52 +01:00
parent 0959b9da3c
commit 123ee630b7
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944

View file

@ -28,6 +28,10 @@ func newRateLimits() *rateLimits {
func (l *rateLimits) clean() { func (l *rateLimits) clean() {
for { for {
// On a ten minute interval, we'll take an exclusive write
// lock of the entire map and see if any of the channels are
// empty. If they are then we will close and delete them,
// freeing up memory.
time.Sleep(time.Second * 10) time.Sleep(time.Second * 10)
l.limitsMutex.Lock() l.limitsMutex.Lock()
for k, c := range l.limits { for k, c := range l.limits {
@ -41,16 +45,26 @@ func (l *rateLimits) clean() {
} }
func (l *rateLimits) rateLimit(req *http.Request) *util.JSONResponse { func (l *rateLimits) rateLimit(req *http.Request) *util.JSONResponse {
// Check if the user has got free resource slots for this request.
// If they don't then we'll return an error.
l.limitsMutex.RLock() l.limitsMutex.RLock()
defer l.limitsMutex.RUnlock() defer l.limitsMutex.RUnlock()
rateLimit, ok := l.limits[req.RemoteAddr] // First of all, work out if X-Forwarded-For was sent to us. If not
if !ok { // then we'll just use the IP address of the caller.
l.limits[req.RemoteAddr] = make(chan struct{}, l.maxRequests) caller := req.RemoteAddr
rateLimit = l.limits[req.RemoteAddr] if forwardedFor := req.Header.Get("X-Forwarded-For"); forwardedFor != "" {
caller = forwardedFor
} }
// Look up the caller's channel, if they have one. If they don't then
// let's create one.
rateLimit, ok := l.limits[caller]
if !ok {
l.limits[caller] = make(chan struct{}, l.maxRequests)
rateLimit = l.limits[caller]
}
// Check if the user has got free resource slots for this request.
// If they don't then we'll return an error.
select { select {
case rateLimit <- struct{}{}: case rateLimit <- struct{}{}:
default: default: