forked from MirrorHub/synapse
More intelligent Content-Type parsing
Content-Type is allowed to contain options (`; charset=utf-8`, for instance). We should allow that.
This commit is contained in:
parent
b6146537d2
commit
b5b3a7e867
1 changed files with 30 additions and 18 deletions
|
@ -33,6 +33,7 @@ from synapse.api.errors import (
|
||||||
|
|
||||||
from signedjson.sign import sign_json
|
from signedjson.sign import sign_json
|
||||||
|
|
||||||
|
import cgi
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
|
@ -292,12 +293,7 @@ class MatrixFederationHttpClient(object):
|
||||||
|
|
||||||
if 200 <= response.code < 300:
|
if 200 <= response.code < 300:
|
||||||
# We need to update the transactions table to say it was sent?
|
# We need to update the transactions table to say it was sent?
|
||||||
c_type = response.headers.getRawHeaders("Content-Type")
|
check_content_type_is_json(response.headers)
|
||||||
|
|
||||||
if "application/json" not in c_type:
|
|
||||||
raise RuntimeError(
|
|
||||||
"Content-Type not application/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
body = yield preserve_context_over_fn(readBody, response)
|
body = yield preserve_context_over_fn(readBody, response)
|
||||||
defer.returnValue(json.loads(body))
|
defer.returnValue(json.loads(body))
|
||||||
|
@ -342,12 +338,7 @@ class MatrixFederationHttpClient(object):
|
||||||
|
|
||||||
if 200 <= response.code < 300:
|
if 200 <= response.code < 300:
|
||||||
# We need to update the transactions table to say it was sent?
|
# We need to update the transactions table to say it was sent?
|
||||||
c_type = response.headers.getRawHeaders("Content-Type")
|
check_content_type_is_json(response.headers)
|
||||||
|
|
||||||
if "application/json" not in c_type:
|
|
||||||
raise RuntimeError(
|
|
||||||
"Content-Type not application/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
body = yield preserve_context_over_fn(readBody, response)
|
body = yield preserve_context_over_fn(readBody, response)
|
||||||
|
|
||||||
|
@ -400,12 +391,7 @@ class MatrixFederationHttpClient(object):
|
||||||
|
|
||||||
if 200 <= response.code < 300:
|
if 200 <= response.code < 300:
|
||||||
# We need to update the transactions table to say it was sent?
|
# We need to update the transactions table to say it was sent?
|
||||||
c_type = response.headers.getRawHeaders("Content-Type")
|
check_content_type_is_json(response.headers)
|
||||||
|
|
||||||
if "application/json" not in c_type:
|
|
||||||
raise RuntimeError(
|
|
||||||
"Content-Type not application/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
body = yield preserve_context_over_fn(readBody, response)
|
body = yield preserve_context_over_fn(readBody, response)
|
||||||
|
|
||||||
|
@ -525,3 +511,29 @@ def _flatten_response_never_received(e):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return "%s: %s" % (type(e).__name__, e.message,)
|
return "%s: %s" % (type(e).__name__, e.message,)
|
||||||
|
|
||||||
|
|
||||||
|
def check_content_type_is_json(headers):
|
||||||
|
"""
|
||||||
|
Check that a set of HTTP headers have a Content-Type header, and that it
|
||||||
|
is application/json.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
headers (twisted.web.http_headers.Headers): headers to check
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
RuntimeError if the
|
||||||
|
|
||||||
|
"""
|
||||||
|
c_type = headers.getRawHeaders("Content-Type")
|
||||||
|
if c_type is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"No Content-Type header"
|
||||||
|
)
|
||||||
|
|
||||||
|
c_type = c_type[0] # only the first header
|
||||||
|
val, options = cgi.parse_header(c_type)
|
||||||
|
if val != "application/json":
|
||||||
|
raise RuntimeError(
|
||||||
|
"Content-Type not application/json: was '%s'" % c_type
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue