replciate Tahoe's behavior for replace=true/false

This commit is contained in:
meejah 2020-06-13 01:55:14 -06:00
parent 0cbdbd9ebe
commit 02a543515f
2 changed files with 48 additions and 4 deletions

View File

@ -61,7 +61,7 @@ class FakeWebTest(TestCase):
@inlineCallbacks
def do_test():
resp = yield self.http_client.put("http://example.com/uri", content)
resp = yield self.http_client.put("http://example.com/uri?replace=true", content)
self.assertEqual(resp.code, 201)
cap_raw = yield resp.content()
@ -79,3 +79,22 @@ class FakeWebTest(TestCase):
do_test(),
succeeded(Always()),
)
@inlineCallbacks
def test_duplicate_upload(self):
"""
Upload the same content (via 'PUT /uri') twice with no overwrite
"""
content = "fake content\n" * 200
resp = yield self.http_client.put("http://example.com/uri", content)
self.assertEqual(resp.code, 201)
cap_raw = yield resp.content()
cap = from_string(cap_raw)
self.assertIsInstance(cap, CHKFileURI)
# this one fails: same content but no ?replace=true
resp = yield self.http_client.put("http://example.com/uri", content)
self.assertEqual(resp.code, 409)

View File

@ -30,6 +30,9 @@ from twisted.web import (
from twisted.internet.defer import (
succeed,
)
from twisted.python.failure import (
Failure,
)
from treq.client import (
HTTPClient,
@ -44,6 +47,13 @@ import allmydata.uri
from allmydata.util import (
base32,
)
from allmydata.interfaces import (
ExistingChildError,
)
from allmydata.web.common import (
humanize_failure,
)
__all__ = (
"create_fake_tahoe_root",
@ -147,7 +157,7 @@ class _FakeTahoeUriHandler(Resource, object):
capability = next(self._capability_generators[kind])
return capability
def add_data(self, kind, data):
def add_data(self, kind, data, allow_duplicate=False):
"""
adds some data to our grid
@ -156,9 +166,18 @@ class _FakeTahoeUriHandler(Resource, object):
if not isinstance(data, bytes):
raise TypeError("'data' must be bytes")
cap = self._generate_capability(kind)
if self._data is None:
self._data = dict()
for k in self._data:
if self._data[k] == data:
if allow_duplicate:
return k
raise ValueError(
"Duplicate data"
)
cap = self._generate_capability(kind)
if cap in self._data:
raise ValueError("already have '{}'".format(cap))
self._data[cap] = data
@ -167,7 +186,13 @@ class _FakeTahoeUriHandler(Resource, object):
def render_PUT(self, request):
data = request.content.read()
request.setResponseCode(http.CREATED) # real code does this for brand-new files
return self.add_data("URI:CHK:", data)
replace = request.args.get("replace", None)
try:
return self.add_data("URI:CHK:", data, allow_duplicate=replace)
except ValueError:
msg, code = humanize_failure(Failure(ExistingChildError()))
request.setResponseCode(code)
return msg
def render_POST(self, request):
t = request.args[u"t"][0]