from pprint import pprint
import threading
import uuid
import os
from collections import defaultdict
import re
import random
import time
from flask import request
from flask import Flask
app = Flask(__name__, static_url_path='')
botPath = 'bots/'
ipBotCounts = defaultdict(int)
# We allow adjustments back to zero slowly per IP, but not fast enough to cause abuse
def background_decay_ipCount():
global ipBotCounts
while True:
time.sleep(60)
for ip in ipBotCounts:
if ipBotCounts[ip] > 0:
print("removing 1 from " + ip)
ipBotCounts[ip] -= 1
if ipBotCounts[ip] < 0:
print("adding 1 to " + ip)
ipBotCounts[ip] += 1
decay_ip_thread = threading.Thread(target=background_decay_ipCount)
decay_ip_thread.start()
@app.route('/<world>', methods=['GET', 'PUT', 'POST'])
def handleRequest(world):
pprint(ipBotCounts)
path = request.path.split('/')[1]
remoteIp = request.headers.get('X-Forwarded-For', request.remote_addr)
if not re.match(r"[a-zA-Z0-9_]", path): #Someone is doing something dodgy
return '', 400
if not os.path.isdir(botPath + path):
os.mkdir(botPath + path)
if request.method == 'PUT':
if ipBotCounts[remoteIp] >= 10:
# Sent too many bots
return '', 429
ipBotCounts[remoteIp] += 1
with open(botPath + path + '/' + str(uuid.uuid4()),'wb') as f:
f.write(request.data)
return ''
if request.method == 'GET':
if not len(os.listdir(botPath + path)) > 200: #not enough bots to give one out
return '', 404
if ipBotCounts[remoteIp] <= -10:
# Sent too little bots to us
return '', 429
ipBotCounts[remoteIp] -= 1
fileToSend = random.choice(os.listdir(botPath + path))
fileToSend = botPath + path + '/' + fileToSend
filedata = open(fileToSend, 'rb').read(100000)
os.remove(fileToSend)
return filedata
app.run(host='0.0.0.0', port=80, threaded=True)
Current server side code