Index: sitescripts/reports/web/updateReport.py
===================================================================
--- a/sitescripts/reports/web/updateReport.py
+++ b/sitescripts/reports/web/updateReport.py
@@ -14,43 +14,32 @@
 # along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
-import os
-import sys
 import random
-from urlparse import parse_qsl
-from sitescripts.utils import get_config, get_template, setupStderr
-from sitescripts.web import url_handler
-from sitescripts.reports.utils import calculateReportSecret, calculateReportSecret_compat, getReport, saveReport, sendUpdateNotification, getUserId, updateUserUsefulness
+from sitescripts.utils import get_config, get_template
+from sitescripts.web import url_handler, form_handler
+from sitescripts.reports.utils import (calculateReportSecret,
+                                       calculateReportSecret_compat, getReport,
+                                       saveReport, sendUpdateNotification,
+                                       getUserId, updateUserUsefulness)
+
+GUID_REGEX = r'^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$'
 
 
 @url_handler('/updateReport')
-def handleRequest(environ, start_response):
-    setupStderr(environ['wsgi.errors'])
-
-    if environ['REQUEST_METHOD'].upper() != 'POST' or not environ.get('CONTENT_TYPE', '').startswith('application/x-www-form-urlencoded'):
-        return showError('Unsupported request method', start_response)
-
-    try:
-        request_body_length = int(environ['CONTENT_LENGTH'])
-    except:
-        return showError('Invalid or missing Content-Length header', start_response)
-
-    request_body = environ['wsgi.input'].read(request_body_length)
-    params = {}
-    for key, value in parse_qsl(request_body):
-        params[key] = value.decode('utf-8')
-
+@form_handler
+def handleRequest(environ, start_response, params):
     guid = params.get('guid', '').lower()
-    if not re.match(r'^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$', guid):
+    if not re.match(GUID_REGEX, guid):
         return showError('Invalid or missing report GUID', start_response)
 
     reportData = getReport(guid)
 
-    if reportData == None:
+    if reportData is None:
         return showError('Report does not exist', start_response)
 
     secret = calculateReportSecret(guid)
-    if params.get('secret', '') != secret and params.get('secret', '') != calculateReportSecret_compat(guid):
+    if (params.get('secret', '') != secret and
+       params.get('secret', '') != calculateReportSecret_compat(guid)):
         return showError('Wrong secret value', start_response)
 
     reportData['status'] = params.get('status', '')
@@ -59,8 +48,10 @@
 
     oldusefulness = reportData.get('usefulness', '0')
     reportData['usefulness'] = params.get('usefulness', '0')
+
     if 'email' in reportData:
-        updateUserUsefulness(getUserId(reportData['email']), reportData['usefulness'], oldusefulness)
+        updateUserUsefulness(getUserId(reportData['email']),
+                             reportData['usefulness'], oldusefulness)
 
     saveReport(guid, reportData)
 
@@ -84,5 +75,6 @@
 
 def showError(message, start_response):
     template = get_template(get_config().get('reports', 'errorTemplate'))
-    start_response('400 Processing Error', [('Content-Type', 'application/xhtml+xml; charset=utf-8')])
+    start_response('400 Processing Error',
+                   [('Content-Type', 'application/xhtml+xml; charset=utf-8')])
     return [template.render({'message': message}).encode('utf-8')]
