rework .done() behaviour

- use the new dedicated field to store the location such that we can
  still properly send metadata with responses to HEAD requests

- always send the location, not just for GET 301s

- no need to generate a 410 as long as we still have the metadata

- retire TUS_REDIRECT type, we do not need it (files with a redirect
  remain intact).
parent 0e2552a8
...@@ -948,17 +948,24 @@ tus_file_done(struct tus_file_core *fcore, struct tus_file_disk *fdisk, const ch ...@@ -948,17 +948,24 @@ tus_file_done(struct tus_file_core *fcore, struct tus_file_disk *fdisk, const ch
int fd; int fd;
size_t l = strlen(url); size_t l = strlen(url);
if (l >= TUS_METADATA_MAX) if (l >= TUS_PATH_MAX)
return (0); return (0);
assert(fdisk->type == TUS_SINGLE || fdisk->type == TUS_FINAL); strcpy(fdisk->location, url);
fdisk->location_length = l;
strcpy(fdisk->metadata, url); /*
fdisk->metadata_length = l; * for TUS_FINAL files, we store the list of parts in the data section,
* so we keep it intact
*
* for TUS_SINGLE files, we delete the data because we now have it at
* location
*/
if (fdisk->type == TUS_FINAL)
return (1);
fdisk->upload_offset = 0; assert(fdisk->type == TUS_SINGLE);
fdisk->upload_length = 0;
fdisk->type = TUS_REDIRECT;
fd = tus_file_open(fcore); fd = tus_file_open(fcore);
if (fd >= 0) { if (fd >= 0) {
......
...@@ -14,7 +14,7 @@ enum tus_f_type { ...@@ -14,7 +14,7 @@ enum tus_f_type {
TUS_SINGLE = 0, TUS_SINGLE = 0,
TUS_PARTIAL, TUS_PARTIAL,
TUS_FINAL, TUS_FINAL,
TUS_REDIRECT _TUS_TYPE_LIMIT
}; };
// header of disk file - mmaped // header of disk file - mmaped
...@@ -25,7 +25,6 @@ struct tus_file_disk { ...@@ -25,7 +25,6 @@ struct tus_file_disk {
char url_path[TUS_PATH_MAX]; char url_path[TUS_PATH_MAX];
unsigned guard_magic; unsigned guard_magic;
unsigned url_path_length; unsigned url_path_length;
// for TUS_REDIRECT, repurposed for location
char metadata[TUS_METADATA_MAX]; char metadata[TUS_METADATA_MAX];
unsigned guard2_magic; unsigned guard2_magic;
unsigned metadata_length; unsigned metadata_length;
...@@ -77,6 +76,8 @@ tus_file_disk_err(const struct tus_file_disk *d) ...@@ -77,6 +76,8 @@ tus_file_disk_err(const struct tus_file_disk *d)
return ("location_length mismatch"); return ("location_length mismatch");
if (strnlen(d->metadata, TUS_METADATA_MAX) != d->metadata_length) if (strnlen(d->metadata, TUS_METADATA_MAX) != d->metadata_length)
return ("metadata_length mismatch"); return ("metadata_length mismatch");
if (d->type >= _TUS_TYPE_LIMIT)
return ("bad type");
return (NULL); return (NULL);
} }
......
...@@ -305,12 +305,14 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -305,12 +305,14 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
return (0); return (0);
} }
if (type == TUS_REDIRECT) { if (m == GET) {
r->fcore = fcore; if (fdisk->location_length > 0) {
r->status = 301; /* done file */
return (0); r->fcore = fcore;
} else if (m == GET) { r->status = 301;
r->status = 400; } else {
r->status = 400;
}
return (0); return (0);
} }
......
...@@ -94,16 +94,17 @@ tus_response(VRT_CTX, const struct VPFX(tus_server) *tussrv, ...@@ -94,16 +94,17 @@ tus_response(VRT_CTX, const struct VPFX(tus_server) *tussrv,
http_Unset(r, hdr_exp); http_Unset(r, hdr_exp);
http_Unset(r, hdr_loc); http_Unset(r, hdr_loc);
if (resp->status == 301) { if (fdisk != NULL && fdisk->location_length > 0) {
AN(fdisk); /* cannot happen for creation */
assert(fdisk->type == TUS_REDIRECT); assert(resp->status != 201);
if (fdisk->metadata_length == 0) if (fdisk->location[0] == '/')
resp->status = 410;
else if (fdisk->metadata[0] == '/')
http_PrintfHeader(r, "Location: %s%s", resp->schemeauth, http_PrintfHeader(r, "Location: %s%s", resp->schemeauth,
fdisk->metadata); fdisk->location);
else else
http_ForceHeader(r, hdr_loc, fdisk->metadata); http_ForceHeader(r, hdr_loc, fdisk->location);
}
if (resp->status == 301) {
VRT_l_resp_status(ctx, resp->status); VRT_l_resp_status(ctx, resp->status);
return; return;
} }
...@@ -150,6 +151,7 @@ tus_response(VRT_CTX, const struct VPFX(tus_server) *tussrv, ...@@ -150,6 +151,7 @@ tus_response(VRT_CTX, const struct VPFX(tus_server) *tussrv,
VTIM_format(fdisk->upload_expires, t); VTIM_format(fdisk->upload_expires, t);
http_ForceHeader(r, hdr_exp, t); http_ForceHeader(r, hdr_exp, t);
if (resp->status == 201) { if (resp->status == 201) {
AZ(fdisk->location_length);
AN(resp->schemeauth); AN(resp->schemeauth);
http_PrintfHeader(r, "Location: %s%s", resp->schemeauth, http_PrintfHeader(r, "Location: %s%s", resp->schemeauth,
fdisk->url_path); fdisk->url_path);
......
...@@ -164,12 +164,14 @@ For the example above, the code would be:: ...@@ -164,12 +164,14 @@ For the example above, the code would be::
$Method BOOL .done([STRING location]) $Method BOOL .done([STRING location])
Mark the upload as done: This frees all storage except for information Mark the upload as done. For simple (non concat) uploads, this frees
on the upload URL itself. all storage except for information on the upload URL itself.
If the optional *location* string is provided, a 301 redirect to If the optional *location* string is provided, a ``Location:``
*location* will be generated for any access attempt. Otherwise, a 410 response header with that location will be added to all future
response will be generated. responses querying the object.
For any ``GET`` access, a 301 response will be generated.
May only be called from client methods. For anything but final concat May only be called from client methods. For anything but final concat
or single (non-concat) uploads, this operation is a noop. or single (non-concat) uploads, this operation is a noop.
......
...@@ -76,6 +76,21 @@ client c1 { ...@@ -76,6 +76,21 @@ client c1 {
expect resp.http.Upload-Expires ~ "GMT$" expect resp.http.Upload-Expires ~ "GMT$"
expect resp.http.Location == "http://localhost/id" expect resp.http.Location == "http://localhost/id"
# even for a done file, HEAD will return the correct metadata
txreq -method HEAD -url "/id" \
-hdr "Tus-Resumable: 1.0.0"
rxresp
expect resp.status == 200
expect resp.http.Tus-Resumable == "1.0.0"
expect resp.http.Tus-Version == "1.0.0"
expect resp.http.Tus-Extension == "creation,creation-with-upload,expiration,termination,concatenation,checksum"
expect resp.http.Tus-Checksum-Algorithm == "crc32,icrc32,md5,rs,sha1,sha224,sha256,sha384,sha3_224,sha3_256,sha3_384,sha3_512,sha512"
expect resp.http.Tus-Max-Size == 4194304
expect resp.http.Upload-Offset == 386550
expect resp.http.Upload-Length == 386550
expect resp.http.Upload-Expires ~ "GMT$"
expect resp.http.Location == "http://localhost/id"
txreq -url "/id" \ txreq -url "/id" \
-hdr "Tus-Resumable: 1.0.0" -hdr "Tus-Resumable: 1.0.0"
rxresp rxresp
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment