mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-21 20:08:15 +00:00
Implement more of the writing logic.
This commit is contained in:
parent
f5437d9be7
commit
3bed067828
@ -198,7 +198,7 @@ class StorageClientImmutables(object):
|
||||
"/v1/immutable/{}/{}".format(_encode_si(storage_index), share_number)
|
||||
)
|
||||
response = yield self._client._request(
|
||||
"POST",
|
||||
"PATCH",
|
||||
url,
|
||||
upload_secret=upload_secret,
|
||||
data=data,
|
||||
|
@ -219,15 +219,35 @@ class HTTPServer(object):
|
||||
)
|
||||
def write_share_data(self, request, authorization, storage_index, share_number):
|
||||
"""Write data to an in-progress immutable upload."""
|
||||
# TODO parse the content-range header to get offset for writing
|
||||
# TODO basic checks on validity of offset
|
||||
# TODO basic check that body isn't infinite. require content-length? if so, needs t be in protocol spec.
|
||||
storage_index = si_a2b(storage_index.encode("ascii"))
|
||||
content_range = request.getHeader("content-range")
|
||||
if content_range is None:
|
||||
offset = 0
|
||||
else:
|
||||
offset = int(content_range.split()[1].split("-")[0])
|
||||
|
||||
# TODO basic checks on validity of start, offset, and content-range in general. also of share_number.
|
||||
# TODO basic check that body isn't infinite. require content-length? or maybe we should require content-range (it's optional now)? if so, needs to be rflected in protocol spec.
|
||||
|
||||
data = request.content.read()
|
||||
# TODO write to bucket at that offset.
|
||||
try:
|
||||
bucket = self._uploads[storage_index].shares[share_number]
|
||||
except (KeyError, IndexError):
|
||||
# TODO return 404
|
||||
raise
|
||||
|
||||
# TODO check if it conflicts with existing data (probably underlying code already handles that) if so, CONFLICT.
|
||||
finished = bucket.write(offset, data)
|
||||
|
||||
# TODO if it finished writing altogether, 201 CREATED. Otherwise 200 OK.
|
||||
# TODO if raises ConflictingWriteError, return HTTP CONFLICT code.
|
||||
|
||||
if finished:
|
||||
request.setResponseCode(http.CREATED)
|
||||
else:
|
||||
request.setResponseCode(http.OK)
|
||||
|
||||
# TODO spec says we should return missing ranges. but client doesn't
|
||||
# actually use them? So is it actually useful?
|
||||
return b""
|
||||
|
||||
@_authorized_route(
|
||||
_app,
|
||||
|
@ -13,7 +13,7 @@ if PY2:
|
||||
|
||||
import os, stat, struct, time
|
||||
|
||||
from collections_extended import RangeMap
|
||||
from collections_extended import RangeMap, MappedRange
|
||||
|
||||
from foolscap.api import Referenceable
|
||||
|
||||
@ -375,7 +375,10 @@ class BucketWriter(object):
|
||||
def allocated_size(self):
|
||||
return self._max_size
|
||||
|
||||
def write(self, offset, data):
|
||||
def write(self, offset, data): # type: (int, bytes) -> bool
|
||||
"""
|
||||
Write data at given offset, return whether the upload is complete.
|
||||
"""
|
||||
# Delay the timeout, since we received data:
|
||||
self._timeout.reset(30 * 60)
|
||||
start = self._clock.seconds()
|
||||
@ -399,6 +402,10 @@ class BucketWriter(object):
|
||||
self.ss.add_latency("write", self._clock.seconds() - start)
|
||||
self.ss.count("write")
|
||||
|
||||
# Return whether the whole thing has been written.
|
||||
# TODO needs property test
|
||||
return self._already_written.ranges() == [MappedRange(0, self._max_size, True)]
|
||||
|
||||
def close(self):
|
||||
precondition(not self.closed)
|
||||
self._timeout.cancel()
|
||||
|
Loading…
Reference in New Issue
Block a user