Skip to content

Commit 50b9ff5

Browse files
author
Marius
authored
handler: Fix error with RUFH upload ending too soon (#1098)
* handler: Fix error with RUFH upload ending too soon * Remove redundant check
1 parent 7684751 commit 50b9ff5

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

pkg/handler/body_reader.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,28 @@ func (r *bodyReader) Read(b []byte) (int, error) {
5454

5555
}
5656
if err != nil {
57-
// We can ignore some of these errors:
58-
// - io.EOF means that the request body was fully read
59-
// - io.ErrBodyReadAfterClose means that the bodyReader closed the request body because the upload is
60-
// is stopped or the server shuts down.
57+
// Note: if an error occurs while reading the body, we must set `r.err` (either in here
58+
// or somewhere else, such as in closeWithError). Otherwise, the PATCH handler might not know
59+
// that an error occurred and assumes that a request was transferred succesfully even though
60+
// it was interrupted. This leads to problems with the RUFH draft.
61+
62+
// io.EOF means that the request body was fully read and does not represent an error.
63+
if err == io.EOF {
64+
return n, io.EOF
65+
}
66+
67+
// http.ErrBodyReadAfterClose means that the bodyReader closed the request body because the upload is
68+
// is stopped or the server shuts down. In this case, the closeWithError method already
69+
// set `r.err` and thus we don't overerwrite it here but just return.
70+
if err == http.ErrBodyReadAfterClose {
71+
return n, io.EOF
72+
}
73+
74+
// All of the following errors can be understood as the input stream ending too soon:
6175
// - io.ErrClosedPipe is returned in the package's unit test with io.Pipe()
6276
// - io.UnexpectedEOF means that the client aborted the request.
63-
// In all of those cases, we do not forward the error to the storage,
64-
// but act like the body just ended naturally.
65-
if err == io.EOF || err == io.ErrClosedPipe || err == http.ErrBodyReadAfterClose || err == io.ErrUnexpectedEOF {
66-
return n, io.EOF
77+
if err == io.ErrClosedPipe || err == io.ErrUnexpectedEOF {
78+
err = ErrUnexpectedEOF
6779
}
6880

6981
// Connection resets are not dropped silently, but responded to the client.

pkg/handler/unrouted_handler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ var (
6262
ErrUploadInterrupted = NewError("ERR_UPLOAD_INTERRUPTED", "upload has been interrupted by another request for this upload resource", http.StatusBadRequest)
6363
ErrServerShutdown = NewError("ERR_SERVER_SHUTDOWN", "request has been interrupted because the server is shutting down", http.StatusServiceUnavailable)
6464
ErrOriginNotAllowed = NewError("ERR_ORIGIN_NOT_ALLOWED", "request origin is not allowed", http.StatusForbidden)
65+
ErrUnexpectedEOF = NewError("ERR_UNEXPECTED_EOF", "server expected to receive more bytes", http.StatusBadRequest)
6566

6667
// These two responses are 500 for backwards compatability. Clients might receive a timeout response
6768
// when the upload got interrupted. Most clients will not retry 4XX but only 5XX, so we responsd with 500 here.

0 commit comments

Comments
 (0)