mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-18 18:56:28 +00:00
Basic mutable read support.
This commit is contained in:
parent
f5c4513cd3
commit
21c3c50e37
@ -601,6 +601,49 @@ class HTTPServer(object):
|
||||
)
|
||||
return self._send_encoded(request, {"success": success, "data": read_data})
|
||||
|
||||
@_authorized_route(
|
||||
_app,
|
||||
set(),
|
||||
"/v1/mutable/<storage_index:storage_index>/<int(signed=False):share_number>",
|
||||
methods=["GET"],
|
||||
)
|
||||
def read_mutable_chunk(self, request, authorization, storage_index, share_number):
|
||||
"""Read a chunk from a mutable."""
|
||||
if request.getHeader("range") is None:
|
||||
# TODO in follow-up ticket
|
||||
raise NotImplementedError()
|
||||
|
||||
# TODO reduce duplication with immutable reads?
|
||||
# TODO unit tests, perhaps shared if possible
|
||||
range_header = parse_range_header(request.getHeader("range"))
|
||||
if (
|
||||
range_header is None
|
||||
or range_header.units != "bytes"
|
||||
or len(range_header.ranges) > 1 # more than one range
|
||||
or range_header.ranges[0][1] is None # range without end
|
||||
):
|
||||
request.setResponseCode(http.REQUESTED_RANGE_NOT_SATISFIABLE)
|
||||
return b""
|
||||
|
||||
offset, end = range_header.ranges[0]
|
||||
|
||||
# TODO limit memory usage
|
||||
# https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3872
|
||||
data = self._storage_server.slot_readv(
|
||||
storage_index, [share_number], [(offset, end - offset)]
|
||||
)[share_number][0]
|
||||
|
||||
# TODO reduce duplication?
|
||||
request.setResponseCode(http.PARTIAL_CONTENT)
|
||||
if len(data):
|
||||
# For empty bodies the content-range header makes no sense since
|
||||
# the end of the range is inclusive.
|
||||
request.setHeader(
|
||||
"content-range",
|
||||
ContentRange("bytes", offset, offset + len(data)).to_header(),
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
@implementer(IStreamServerEndpoint)
|
||||
@attr.s
|
||||
|
@ -1195,18 +1195,17 @@ class _HTTPStorageServer(object):
|
||||
def slot_readv(self, storage_index, shares, readv):
|
||||
mutable_client = StorageClientMutables(self._http_client)
|
||||
reads = {}
|
||||
# TODO if shares list is empty, that means list all shares, so we need
|
||||
# to do a query to get that.
|
||||
assert shares # TODO replace with call to list shares
|
||||
for share_number in shares:
|
||||
share_reads = reads[share_number] = []
|
||||
for (offset, length) in readv:
|
||||
d = mutable_client.read_share_chunk(
|
||||
r = yield mutable_client.read_share_chunk(
|
||||
storage_index, share_number, offset, length
|
||||
)
|
||||
share_reads.append(d)
|
||||
result = {
|
||||
share_number: [(yield d) for d in share_reads]
|
||||
for (share_number, reads) in reads.items()
|
||||
}
|
||||
defer.returnValue(result)
|
||||
share_reads.append(r)
|
||||
defer.returnValue(reads)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def slot_testv_and_readv_and_writev(
|
||||
|
Loading…
Reference in New Issue
Block a user