Merge pull request #1297 from tahoe-lafs/4016-http-storage-content-type
HTTP storage content type correctness Fixes ticket:4016
This commit is contained in:
commit
0b992c498a
0
newsfragments/4016.minor
Normal file
0
newsfragments/4016.minor
Normal file
@ -443,11 +443,20 @@ class StorageClient(object):
|
|||||||
kwargs["data"] = dumps(message_to_serialize)
|
kwargs["data"] = dumps(message_to_serialize)
|
||||||
headers.addRawHeader("Content-Type", CBOR_MIME_TYPE)
|
headers.addRawHeader("Content-Type", CBOR_MIME_TYPE)
|
||||||
|
|
||||||
return await self._treq.request(
|
response = await self._treq.request(
|
||||||
method, url, headers=headers, timeout=timeout, **kwargs
|
method, url, headers=headers, timeout=timeout, **kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
async def decode_cbor(self, response, schema: Schema) -> object:
|
if self.TEST_MODE_REGISTER_HTTP_POOL is not None:
|
||||||
|
if response.code != 404:
|
||||||
|
# We're doing API queries, HTML is never correct except in 404, but
|
||||||
|
# it's the default for Twisted's web server so make sure nothing
|
||||||
|
# unexpected happened.
|
||||||
|
assert get_content_type(response.headers) != "text/html"
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
async def decode_cbor(self, response: IResponse, schema: Schema) -> object:
|
||||||
"""Given HTTP response, return decoded CBOR body."""
|
"""Given HTTP response, return decoded CBOR body."""
|
||||||
with start_action(action_type="allmydata:storage:http-client:decode-cbor"):
|
with start_action(action_type="allmydata:storage:http-client:decode-cbor"):
|
||||||
if response.code > 199 and response.code < 300:
|
if response.code > 199 and response.code < 300:
|
||||||
@ -587,6 +596,12 @@ def read_share_chunk(
|
|||||||
if response.code == http.NO_CONTENT:
|
if response.code == http.NO_CONTENT:
|
||||||
return b""
|
return b""
|
||||||
|
|
||||||
|
content_type = get_content_type(response.headers)
|
||||||
|
if content_type != "application/octet-stream":
|
||||||
|
raise ValueError(
|
||||||
|
f"Content-type was wrong: {content_type}, should be application/octet-stream"
|
||||||
|
)
|
||||||
|
|
||||||
if response.code == http.PARTIAL_CONTENT:
|
if response.code == http.PARTIAL_CONTENT:
|
||||||
content_range = parse_content_range_header(
|
content_range = parse_content_range_header(
|
||||||
response.headers.getRawHeaders("content-range")[0] or ""
|
response.headers.getRawHeaders("content-range")[0] or ""
|
||||||
|
@ -106,6 +106,9 @@ def _authorization_decorator(required_secrets):
|
|||||||
def decorator(f):
|
def decorator(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def route(self, request, *args, **kwargs):
|
def route(self, request, *args, **kwargs):
|
||||||
|
# Don't set text/html content type by default:
|
||||||
|
request.defaultContentType = None
|
||||||
|
|
||||||
with start_action(
|
with start_action(
|
||||||
action_type="allmydata:storage:http-server:handle-request",
|
action_type="allmydata:storage:http-server:handle-request",
|
||||||
method=request.method,
|
method=request.method,
|
||||||
@ -114,9 +117,9 @@ def _authorization_decorator(required_secrets):
|
|||||||
try:
|
try:
|
||||||
# Check Authorization header:
|
# Check Authorization header:
|
||||||
if not timing_safe_compare(
|
if not timing_safe_compare(
|
||||||
request.requestHeaders.getRawHeaders("Authorization", [""])[0].encode(
|
request.requestHeaders.getRawHeaders("Authorization", [""])[
|
||||||
"utf-8"
|
0
|
||||||
),
|
].encode("utf-8"),
|
||||||
swissnum_auth_header(self._swissnum),
|
swissnum_auth_header(self._swissnum),
|
||||||
):
|
):
|
||||||
raise _HTTPError(http.UNAUTHORIZED)
|
raise _HTTPError(http.UNAUTHORIZED)
|
||||||
@ -491,6 +494,7 @@ def read_range(
|
|||||||
|
|
||||||
def _add_error_handling(app: Klein):
|
def _add_error_handling(app: Klein):
|
||||||
"""Add exception handlers to a Klein app."""
|
"""Add exception handlers to a Klein app."""
|
||||||
|
|
||||||
@app.handle_errors(_HTTPError)
|
@app.handle_errors(_HTTPError)
|
||||||
def _http_error(_, request, failure):
|
def _http_error(_, request, failure):
|
||||||
"""Handle ``_HTTPError`` exceptions."""
|
"""Handle ``_HTTPError`` exceptions."""
|
||||||
@ -775,6 +779,7 @@ class HTTPServer(object):
|
|||||||
)
|
)
|
||||||
def read_share_chunk(self, request, authorization, storage_index, share_number):
|
def read_share_chunk(self, request, authorization, storage_index, share_number):
|
||||||
"""Read a chunk for an already uploaded immutable."""
|
"""Read a chunk for an already uploaded immutable."""
|
||||||
|
request.setHeader("content-type", "application/octet-stream")
|
||||||
try:
|
try:
|
||||||
bucket = self._storage_server.get_buckets(storage_index)[share_number]
|
bucket = self._storage_server.get_buckets(storage_index)[share_number]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -880,6 +885,7 @@ class HTTPServer(object):
|
|||||||
)
|
)
|
||||||
def read_mutable_chunk(self, request, authorization, storage_index, share_number):
|
def read_mutable_chunk(self, request, authorization, storage_index, share_number):
|
||||||
"""Read a chunk from a mutable."""
|
"""Read a chunk from a mutable."""
|
||||||
|
request.setHeader("content-type", "application/octet-stream")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
share_length = self._storage_server.get_mutable_share_length(
|
share_length = self._storage_server.get_mutable_share_length(
|
||||||
|
Loading…
Reference in New Issue
Block a user