Skip to content

Commit

Permalink
Use incoming request to produce location for @tus-upload (#1570)
Browse files Browse the repository at this point in the history
* Use request url to generate tus upload location. Allows seemless use of ++api++

* Add changelog entry

* Add test for ++api++

* Rewrite location url if @tus-replace endpoint is used

* flake8/black fixes

* Make url change more explicit and add an explanatory comment

---------

Co-authored-by: Timo Stollenwerk <[email protected]>
Co-authored-by: Jefferson Bledsoe <[email protected]>
  • Loading branch information
3 people authored Aug 25, 2023
1 parent dc2deb5 commit 1824086
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
2 changes: 2 additions & 0 deletions news/1570.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Use incoming request to produce location for @tus-upload
[instification]
7 changes: 6 additions & 1 deletion src/plone/restapi/services/content/tus.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,14 @@ def reply(self):
tus_upload = TUSUpload(uuid4().hex, metadata=metadata)

self.request.response.setStatus(201)
url = self.request.getURL()
# Regardless of @tus-upload or @tus-replace the response should return
# a Location of @tus-upload
if url.endswith("@tus-replace"):
url = url.replace("@tus-replace", "@tus-upload")
self.request.response.setHeader(
"Location",
f"{self.context.absolute_url()}/@tus-upload/{tus_upload.uid}",
f"{url}/{tus_upload.uid}",
)
self.request.response.setHeader("Upload-Expires", tus_upload.expires())
self.request.response.setHeader("Tus-Resumable", "1.0.0")
Expand Down
29 changes: 29 additions & 0 deletions src/plone/restapi/tests/test_tus.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,35 @@ def record_event(event):
sm.unregisterHandler(record_event, (IObjectAddedEvent,))
sm.unregisterHandler(record_event, (IObjectModifiedEvent,))

def test_tus_with_api(self):
self.upload_url = (
f"{self.portal.absolute_url()}/++api++/{self.folder.id}/@tus-upload"
)
metadata = _prepare_metadata(UPLOAD_FILENAME, UPLOAD_MIMETYPE)
response = self.api_session.post(
self.upload_url,
headers={
"Tus-Resumable": "1.0.0",
"Upload-Length": str(UPLOAD_LENGTH),
"Upload-Metadata": metadata,
},
)
self.assertEqual(response.status_code, 201)
location = response.headers["Location"]
self.assertEqual("++api++" in location, True)

# upload the data with PATCH
response = self.api_session.patch(
location,
headers={
"Content-Type": "application/offset+octet-stream",
"Upload-Offset": "0",
"Tus-Resumable": "1.0.0",
},
data=BytesIO(UPLOAD_DATA),
)
self.assertEqual(response.status_code, 204)

def tearDown(self):
self.api_session.close()
client_home = os.environ.get("CLIENT_HOME")
Expand Down

0 comments on commit 1824086

Please sign in to comment.