Return response indicating success or error when results are submitted. Added option requiring data be signed.
authorMark Cote <mcote@mozilla.com>
Wed, 14 Mar 2012 23:58:10 -0400
changeset 82 93d231182e8cfb60f2a15da18e34a1c70ee7ad81
parent 81 56c19eec9cad47e271a428577ae264de56e1837b
child 83 3bc9aa8c9cf431e9fcce459a05ef71b1c05b7594
push id80
push usermcote@mozilla.com
push dateThu, 15 Mar 2012 03:58:15 +0000
Return response indicating success or error when results are submitted. Added option requiring data be signed.
server/handlers.py
--- a/server/handlers.py
+++ b/server/handlers.py
@@ -6,34 +6,36 @@ import re
 import speedtests
 import templeton.handlers
 import urllib2
 import web
 from collections import defaultdict
 
 class DefaultConfigParser(ConfigParser.ConfigParser):
 
-    def get_default(self, section, option, default):
+    def get_default(self, section, option, default, func='get'):
         try:
-            return cfg.get(section, option)
+            return getattr(cfg, func)(section, option)
         except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
             return default
 
 TESTS_DIR = 'speedtests'
 
 DEFAULT_CONF_FILE = 'speedtests_server.conf'
 cfg = DefaultConfigParser()
 
 cfg.read(DEFAULT_CONF_FILE)
 HTML_DIR = cfg.get_default('speedtests', 'html_dir', os.path.join('..', 'html'))
 PROXY_TO = cfg.get_default('speedtests', 'proxy', None)
 DB_HOST = cfg.get_default('speedtests', 'db_host', 'localhost')
 DB_NAME = cfg.get_default('speedtests', 'db_name', 'speedtests')
 DB_USER = cfg.get_default('speedtests', 'db_user', 'speedtests')
 DB_PASSWD = cfg.get_default('speedtests', 'db_passwd', 'speedtests')
+REQUIRE_SIGNED = cfg.get_default('speedtests', 'require_signed', False,
+                                 'getboolean')
 try:
     CLIENT_KEYS = dict(cfg.items('client keys'))
 except ConfigParser.NoSectionError:
     CLIENT_KEYS = {}
 
 if CLIENT_KEYS:
     try:
         import jwt
@@ -163,41 +165,47 @@ class TestResults(object):
             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
             'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
             'Accept-Encoding': 'gzip, deflate'
             }
         # FIXME: Error logging
         request = urllib2.Request(PROXY_TO, web.data(), headers)
         response = urllib2.urlopen(request, timeout=120).read()
 
+    @templeton.handlers.json_response
     def POST(self):
         if PROXY_TO:
             self.proxy_request()
             return
         content_type = web.ctx.env.get('CONTENT_TYPE', '')
         if content_type == 'application/jwt':
             token = jwt.decode(web.data(),
                                signers=[jwt.jws.HmacSha(keydict=CLIENT_KEYS)])
             if not token['valid']:
                 # JWT signature not valid
                 # FIXME: Log error!
-                return
+                return {'result': 'error', 'error': 'invalid signature'}
             web_data = token['payload']
+        elif REQUIRE_SIGNED:
+            return {'result': 'error', 'error': 'results must be signed'}
         else:
             web_data = json.loads(web.data())
+        if web_data.get('ignore'):
+            return {'result': 'ok'}
+        testname = web_data['testname']
         machine_ip = web_data['ip']
-        testname = web_data['testname']
         browser_id = get_browser_id(web_data['ua'])
         for results in web_data['results']:
             results['browser_id'] = browser_id
     	    results['ip'] = machine_ip
             cols = {}
             for k, v in results.iteritems():
                 cols[k.encode('ascii')] = v
             db.insert(testname, **cols)
+        return {'result': 'ok'}
 
     @templeton.handlers.json_response
     def GET(self):
         args, body = templeton.handlers.get_request_parms()
         tables = args.get('testname', None)
         start = args.get('start', None)
         end = args.get('end', None)
         ip = args.get('ip', None)