#!/usr/bin/python2 import cgi, cgitb, os, sys, time, re from js_check import jsparser from js_check import validate import redis from hashlib import sha1 from random import random import MySQLdb import simplejson as json #set max interval between requests MAX_INTERVAL = 30; REQUEST_LIMIT = 3; API_NAME = "shaderblaster" REMOTE_IP = cgi.escape(os.environ["REMOTE_ADDR"]) REDIS = redis.StrictRedis(host='localhost', port=6379, db=0); NOW = time.time() def error(message): print json.dumps({'ERROR': message }); sys.exit(1); def check_limits(api_name, tf_length, limit, ip, now): #when should this expire? value = REDIS.get("%s_%s" % (ip, api_name)) if not value: # create new timeframe new_tf = "%d-%d" % (now , 1) # tf starts now else: parts = re.findall(r'[^-]+', value); tf_start = int(parts[0]); req_count = int(parts[1]); reset_time = tf_start + tf_length if reset_time < now : new_tf = "%d-%d" % (now , 1) else: # still in tf, check limits, increase counter req_count += 1 if req_count > limit : # return the too many requests error return int(reset_time - now) else : # increase request count new_tf = "%d-%d" % (tf_start, req_count); redis_key = "%s_%s" % (ip, api_name ) REDIS.set(redis_key, new_tf); REDIS.expire(redis_key, MAX_INTERVAL*2) #arbitrary time longer than other interval return False def strip_querystring(url): p = re.compile('^[^\?]*') return p.findall(url)[0] def store_shader_in_db(script, shader_id=False, image_url="",username="",name=""): conn = MySQLdb.connect(host= "127.0.0.1", user="asdfus", passwd="gTYgT&M6q", db="asdfus") x = conn.cursor() try: if not shader_id: x.execute('''INSERT INTO shader_ids(username) values (%s)''' , (username)); shader_id = conn.insert_id() conn.commit() x.execute("""INSERT INTO shaders (script, image_url, username, name, remote_addr, time, shader_id) values (%s,%s,%s,%s,%s,%s,%s)""" , (script, image_url, username, name, REMOTE_IP, NOW, shader_id) ); last_id = conn.insert_id() conn.commit() except Exception as e: conn.rollback() return False conn.close() return last_id def main(): #set up cgi print 'Content-type: text/html\n\n' cgitb.enable() limit_test = check_limits(API_NAME, MAX_INTERVAL, REQUEST_LIMIT, REMOTE_IP, NOW) if limit_test: return error("You have exceeded the maximum number of requests, try again in %s seconds" % limit_test); #form should contain script, shader_id, username, name, image_url form = cgi.FieldStorage(keep_blank_values=1) if 'script' not in form or not form['script']: error( 'script not found') image_url = 'NULL' if 'image_url' in form and form['image_url'].value: image_url = strip_querystring(form['image_url'].value) test = jsparser.parse(form['script'].value) test_failure = validate.test_script(test) if test_failure: error("Cannot save this shader:%s" % test_failure) shader_version_id = store_shader_in_db( form['script'].value, form['shader_id'].value, image_url, form['username'].value, form['name'].value); if not shader_version_id: error('DB Error') else: print json.dumps({ "success":1, "id": shader_version_id }); main() exit(0);