# Buggy code
def _get_payload(self, request):
    content = request.content.read()
    content = bytes2NativeString(content)

    signature = request.getHeader(_HEADER_SIGNATURE)
    signature = bytes2NativeString(signature)

    if not signature and self._strict:
        raise ValueError("Request has no required signature")

    if self._secret and signature:
        try:
            hash_type, hexdigest = signature.split("=")
        except ValueError:
            raise ValueError("Wrong signature format: {}".format(signature))

        if hash_type != "sha1":
            raise ValueError("Unknown hash type: {}".format(hash_type))

        mac = hmac.new(
            unicode2bytes(self._secret), msg=unicode2bytes(content), digestmod=sha1
        )
        # NOTE: hmac.compare_digest should be used, but it's only available
        # starting Python 2.7.7
        if mac.hexdigest() != hexdigest:
            raise ValueError("Hash mismatch")

    content_type = request.getHeader(b"Content-Type")

    if content_type == b"application/json":
        payload = json.loads(content)
    elif content_type == b"application/x-www-form-urlencoded":
        payload = json.loads(request.args["payload"][0])
    else:
        raise ValueError("Unknown content type: {}".format(content_type))

    log.msg("Payload: {}".format(payload), logLevel=logging.DEBUG)

    return payload


# Traceback (builtins.KeyError)
Traceback (most recent call last):
File "/opt/buildbot/lib/python3.5/site-packages/twisted/web/server.py", line 235, in render
body = resrc.render(self)
File "/opt/buildbot/lib/python3.5/site-packages/twisted/web/resource.py", line 250, in render
return m(request)
File "/opt/buildbot/lib/python3.5/site-packages/buildbot/www/change_hook.py", line 81, in render_POST
d = self.getAndSubmitChanges(request)
File "/opt/buildbot/lib/python3.5/site-packages/twisted/internet/defer.py", line 1532, in unwindGenerator
return _inlineCallbacks(None, gen, Deferred())
--- <exception caught here> ---
File "/opt/buildbot/lib/python3.5/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
result = result.throwExceptionIntoGenerator(g)
File "/opt/buildbot/lib/python3.5/site-packages/twisted/python/failure.py", line 393, in throwExceptionIntoGenerator
return g.throw(self.type, self.value, self.tb)
File "/opt/buildbot/lib/python3.5/site-packages/buildbot/www/change_hook.py", line 107, in getAndSubmitChanges
changes, src = yield self.getChanges(request)
builtins.KeyError: 'payload'

# Fixed code
def _get_payload(self, request):
    content = request.content.read()
    content = bytes2unicode(content)

    signature = request.getHeader(_HEADER_SIGNATURE)
    signature = bytes2unicode(signature)

    if not signature and self._strict:
        raise ValueError("Request has no required signature")

    if self._secret and signature:
        try:
            hash_type, hexdigest = signature.split("=")
        except ValueError:
            raise ValueError("Wrong signature format: {}".format(signature))

        if hash_type != "sha1":
            raise ValueError("Unknown hash type: {}".format(hash_type))

        mac = hmac.new(
            unicode2bytes(self._secret), msg=unicode2bytes(content), digestmod=sha1
        )
        # NOTE: hmac.compare_digest should be used, but it's only available
        # starting Python 2.7.7
        if mac.hexdigest() != hexdigest:
            raise ValueError("Hash mismatch")

    content_type = request.getHeader(b"Content-Type")

    if content_type == b"application/json":
        payload = json.loads(content)
    elif content_type == b"application/x-www-form-urlencoded":
        payload = json.loads(bytes2unicode(request.args[b"payload"][0]))
    else:
        raise ValueError("Unknown content type: {}".format(content_type))

    log.msg("Payload: {}".format(payload), logLevel=logging.DEBUG)

    return payload