Original text:
MUST acknowledge it by responding with the "201 (Created)" status code, the "Upload-Incomplete" header set to true.  The client MAY automatically attempt upload resumption when the connection is terminated unexpectedly, or if a server error status code between 500 and 599 (inclusive) is received.  The client SHOULD

Reviewer comments:
Closes URL I am not super sure about the wording here, but this is a start. The sentences seem quite long and maybe the rules could also be expressed in fewer words.
I wonder if it is also possible to expose this final upload size in the response to Offset Retrieving Procedures. I don't think we can set in the HEAD responses because that would indicate that the server already has this amount of bytes, which is not correct.
If the client acknowledged its final upload size at any point ( + ), it should still know it in the future, so I don't think we need a way for the server to echo it in the offset retrieving response. If the server disagrees with the client, then someone's data representation has changed, and we shouldn't continue the upload anyway.
Looks good. Wondering if these could be reduced to SHOULDs though. It wouldn't really affect interop if the server didn't implement this.
Fair point, let's leave such functionality out of the draft. While it is true that clients usually won't really notice if the server does or does not support this, I think we can be stricter here and require this additional safety catch here. It will help to create a more standard landscape of resumable upload servers. Unless there is something against requiring this, we can keep it a MUST IMO.
I just updated this PR to use the Upload-Complete header as agreed on in
The arguments for SHOULD are: This check requires additional code and complexity. MUSTs are situations that a minimal implementation has to handle anyway and we are just strict about how to handle them. For people using chunked uploads, this check is only useful if the last chunk is interrupted which is sort of an edge case. Maybe we can generalize the check if we adopt ranged PATCH. I don't have a strong opinion on this, so either way is OK with me.
When the server receives a series of appends: If the offset+length is inconsistent, the server should reject the upload.
To clarify; Is what you are saying here that the provided during the upload creation procedure should act as the total size of the file, similar to Upload-Length in tus1x?
I am not sure if we want this. I ran into this exact problem because your NIOResumableUpload implementation uses this logic (see URL). We currently have the header to indicate the completeness of the upload. Based on this information, the server can determine if an upload is complete or not without relying on . Adding to the upload logic would mean that we have two indicators for upload completeness, which could potentially disagree with each other. Personally, I think we should not use to determine the upload's completeness and only determine it based on whether the client set in a successful request. For each Upload Creation Procedure or Upload Appending Procedure, the should be set to the number of bytes that the client wants to send in this individual procedure. For example, if you want to transmit 100 bytes in the first POST request, set (or not if you use ). If you want to transmit 200 bytes in the following PATCH request, set . If you want to finish the upload then, set and the upload is considered complete with its 300 bytes of content.
The issue in NIOResumableUpload was a bug, not how this is supposed to work. Offset + Content-Length = final upload size when the upload is complete, and if the client has told the server about the final size, it shouldn't be allowed to change its mind.
Echoing what Guoye said, should not determine the upload's completeness, but if an request has a , then the server can expect and enforce the final upload size based on that . This prevents a client from appending more bytes to their upload than the server anticipated. Ex. Client starts an upload , Server expects a final upload size of 100 bytes Upload is interrupted, offset-retrieving, server sends Client now tries to append an extra ~10GB Client sends , , Server can reject this request
I see, thanks for the explanation. That makes sense. Basically, in conjunction with let the server know the final upload size, which should not be changed
How does that work if the last append has in conjunction with . The Content-Length needs to match the number of bytes in the append message.
Final size = upload-offset + content-length if the upload is complete
So the first ever request with Upload-Incomplete: ?0 and content-length sets the expected final size. Every other request must have a content-length less than that value?
Yeah, once the final length is determined, it cannot be changed by subsequent requests.
OK I think that makes sense but it's not obvious from the spec. We should try and make it more accessible with some new or different text.
I started on the wording in

Revised text:
MUST acknowledge it by responding with the "201 (Created)" status code, the "Upload-Incomplete" header set to true. <ins> If the request includes the "Upload-Complete: ?1" header field and a valid "Content-Length" header field, the client attempts to upload the remaining resource in one request.  In this case, the upload's final size is the sum of the upload's offset and the "Content-Length" header field.  If the server does not have a record of the upload's final size from the Upload Creation or previous Upload Appending Procedures, the server MUST record the upload's final size to ensure its consistency with future Upload Appending Procedures.  If the server does have a previous record, the upload's final size from a previous procedure MUST match the upload's final size from the current Upload Appending Procedure.  If they do not match, the server MUST reject the request with the "400 (Bad Request)" status code. </ins> The client MAY automatically attempt upload resumption when the connection is terminated unexpectedly, or if a server error status code between 500 and 599 (inclusive) is received.  The client SHOULD