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
int fd;
size_t l = strlen(url);
if (l >= TUS_METADATA_MAX)
if (l >= TUS_PATH_MAX)
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;
fdisk->upload_length = 0;
fdisk->type = TUS_REDIRECT;
assert(fdisk->type == TUS_SINGLE);
fd = tus_file_open(fcore);
if (fd >= 0) {
......
......@@ -14,7 +14,7 @@ enum tus_f_type {
TUS_SINGLE = 0,
TUS_PARTIAL,
TUS_FINAL,
TUS_REDIRECT
_TUS_TYPE_LIMIT
};
// header of disk file - mmaped
......@@ -25,7 +25,6 @@ struct tus_file_disk {
char url_path[TUS_PATH_MAX];
unsigned guard_magic;
unsigned url_path_length;
// for TUS_REDIRECT, repurposed for location
char metadata[TUS_METADATA_MAX];
unsigned guard2_magic;
unsigned metadata_length;
......@@ -77,6 +76,8 @@ tus_file_disk_err(const struct tus_file_disk *d)
return ("location_length mismatch");
if (strnlen(d->metadata, TUS_METADATA_MAX) != d->metadata_length)
return ("metadata_length mismatch");
if (d->type >= _TUS_TYPE_LIMIT)
return ("bad type");
return (NULL);
}
......
......@@ -305,12 +305,14 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
return (0);
}
if (type == TUS_REDIRECT) {
r->fcore = fcore;
r->status = 301;
return (0);
} else if (m == GET) {
r->status = 400;
if (m == GET) {
if (fdisk->location_length > 0) {
/* done file */
r->fcore = fcore;
r->status = 301;
} else {
r->status = 400;
}
return (0);
}
......
......@@ -94,16 +94,17 @@ tus_response(VRT_CTX, const struct VPFX(tus_server) *tussrv,
http_Unset(r, hdr_exp);
http_Unset(r, hdr_loc);
if (resp->status == 301) {
AN(fdisk);
assert(fdisk->type == TUS_REDIRECT);
if (fdisk->metadata_length == 0)
resp->status = 410;
else if (fdisk->metadata[0] == '/')
if (fdisk != NULL && fdisk->location_length > 0) {
/* cannot happen for creation */
assert(resp->status != 201);
if (fdisk->location[0] == '/')
http_PrintfHeader(r, "Location: %s%s", resp->schemeauth,
fdisk->metadata);
fdisk->location);
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);
return;
}
......@@ -150,6 +151,7 @@ tus_response(VRT_CTX, const struct VPFX(tus_server) *tussrv,
VTIM_format(fdisk->upload_expires, t);
http_ForceHeader(r, hdr_exp, t);
if (resp->status == 201) {
AZ(fdisk->location_length);
AN(resp->schemeauth);
http_PrintfHeader(r, "Location: %s%s", resp->schemeauth,
fdisk->url_path);
......
......@@ -164,12 +164,14 @@ For the example above, the code would be::
$Method BOOL .done([STRING location])
Mark the upload as done: This frees all storage except for information
on the upload URL itself.
Mark the upload as done. For simple (non concat) uploads, this frees
all storage except for information on the upload URL itself.
If the optional *location* string is provided, a 301 redirect to
*location* will be generated for any access attempt. Otherwise, a 410
response will be generated.
If the optional *location* string is provided, a ``Location:``
response header with that location will be added to all future
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
or single (non-concat) uploads, this operation is a noop.
......
......@@ -76,6 +76,21 @@ client c1 {
expect resp.http.Upload-Expires ~ "GMT$"
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" \
-hdr "Tus-Resumable: 1.0.0"
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