Skip to content

Commit

Permalink
Merge pull request matrix-org#1660 from matrix-org/rav/better_content…
Browse files Browse the repository at this point in the history
…_type_validation

More intelligent Content-Type parsing
  • Loading branch information
richvdh authored Nov 30, 2016
2 parents 321fe5c + b5b3a7e commit 8379a74
Showing 1 changed file with 30 additions and 18 deletions.
48 changes: 30 additions & 18 deletions synapse/http/matrixfederationclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

from signedjson.sign import sign_json

import cgi
import simplejson as json
import logging
import random
Expand Down Expand Up @@ -292,12 +293,7 @@ def body_callback(method, url_bytes, headers_dict):

if 200 <= response.code < 300:
# We need to update the transactions table to say it was sent?
c_type = response.headers.getRawHeaders("Content-Type")

if "application/json" not in c_type:
raise RuntimeError(
"Content-Type not application/json"
)
check_content_type_is_json(response.headers)

body = yield preserve_context_over_fn(readBody, response)
defer.returnValue(json.loads(body))
Expand Down Expand Up @@ -342,12 +338,7 @@ def body_callback(method, url_bytes, headers_dict):

if 200 <= response.code < 300:
# We need to update the transactions table to say it was sent?
c_type = response.headers.getRawHeaders("Content-Type")

if "application/json" not in c_type:
raise RuntimeError(
"Content-Type not application/json"
)
check_content_type_is_json(response.headers)

body = yield preserve_context_over_fn(readBody, response)

Expand Down Expand Up @@ -400,12 +391,7 @@ def body_callback(method, url_bytes, headers_dict):

if 200 <= response.code < 300:
# We need to update the transactions table to say it was sent?
c_type = response.headers.getRawHeaders("Content-Type")

if "application/json" not in c_type:
raise RuntimeError(
"Content-Type not application/json"
)
check_content_type_is_json(response.headers)

body = yield preserve_context_over_fn(readBody, response)

Expand Down Expand Up @@ -525,3 +511,29 @@ def _flatten_response_never_received(e):
)
else:
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
)

0 comments on commit 8379a74

Please sign in to comment.