When the server receives a request, it increments a counter. If this counter goes above a max specified value, the request is ignored.
Then, every X seconds (where you specify this time), you decrease the counter by 1.
This is analogous to a leaky bucket, where the counter is the height of water in the bucket, and a hole in the bottom of the bucket slowly drains the water. When the bucket gets too much water, the overflow is just ignored and doesn’t change the height of water in the bucket.
This might require some tuning to adjust to your gun’s firerate, but should work in general.