Skip to content

Commit

Permalink
Merge pull request #1608 from tardyp/b3228
Browse files Browse the repository at this point in the history
fix encoding header validation
  • Loading branch information
Mikhail Sobolev committed Mar 24, 2015
2 parents 0bc3a37 + 747b97e commit 0fdb4c7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
13 changes: 13 additions & 0 deletions master/buildbot/test/unit/test_www_rest.py
Expand Up @@ -669,3 +669,16 @@ def test_valid_fails(self):
responseCode=500)
# the error gets logged, too:
self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)


class ContentTypeParser(unittest.TestCase):

def test_simple(self):
self.assertEqual(rest.ContentTypeParser("application/json").gettype(), "application/json")

def test_complex(self):
self.assertEqual(rest.ContentTypeParser("application/json; Charset=UTF-8").gettype(),
"application/json")

def test_text(self):
self.assertEqual(rest.ContentTypeParser("text/plain; Charset=UTF-8").gettype(), "text/plain")
20 changes: 15 additions & 5 deletions master/buildbot/www/rest.py
Expand Up @@ -17,6 +17,7 @@

import datetime
import fnmatch
import mimetools
import re
import types

Expand All @@ -43,6 +44,18 @@ def __init__(self, message, jsonrpccode):
self.jsonrpccode = jsonrpccode


class ContentTypeParser(mimetools.Message):

def __init__(self, contenttype):
self.typeheader = contenttype
self.encodingheader = None
self.parsetype()
self.parseplist()

URL_ENCODED = "application/x-www-form-urlencoded"
JSON_ENCODED = "application/json"


class RestRootResource(resource.Resource):
version_classes = {}

Expand All @@ -65,16 +78,14 @@ def __init__(self, master):
self.putChild('latest', child)

def render(self, request):
request.setHeader("content-type", 'application/json')
request.setHeader("content-type", JSON_ENCODED)
min_vers = self.master.config.www.get('rest_minimum_version', 0)
api_versions = dict(('v%d' % v, '%sapi/v%d' % (self.base_url, v))
for v in self.version_classes
if v > min_vers)
return json.dumps(dict(api_versions=api_versions))


URL_ENCODED = "application/x-www-form-urlencoded"
JSON_ENCODED = "application/json"
JSONRPC_CODES = dict(parse_error=-32700,
invalid_request=-32600,
method_not_found=-32601,
Expand Down Expand Up @@ -137,7 +148,7 @@ def decodeJsonRPC2(self, request):
# Verify the content-type. Browsers are easily convinced to send
# POST data to arbitrary URLs via 'form' elements, but they won't
# use the application/json content-type.
if request.getHeader('content-type') != 'application/json':
if ContentTypeParser(request.getHeader('content-type')).gettype() != JSON_ENCODED:
raise BadJsonRpc2('Invalid content-type (use application/json)',
JSONRPC_CODES["invalid_request"])

Expand Down Expand Up @@ -204,7 +215,6 @@ def writeError(msg, errcode=399,
request.write(data)

# JSONAPI support

def decodeResultSpec(self, request, endpoint):
reqArgs = request.args

Expand Down

0 comments on commit 0fdb4c7

Please sign in to comment.