-
Notifications
You must be signed in to change notification settings - Fork 669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object.Read doesn't return error on truncated response #1451
Comments
As comparison I tried to run the same test with the official AWS SDK and I get
|
Will take a look @pracucci |
The main reason is that The actual expected size returned after a fully io.Copy() is |
Is it a nice way to say it's by design? :) |
This is a very low-level implementation - you would see the same behavior in this SDK as well if you used core.GetObject() the top-level implementation i.e api.GetObject() is io.ReadSeeker and io.ReaderAt compatible so the behavior is trying to be io.Reader compatible. So Read() will not return io.ErrUnexpectedEOF |
Let's see if it's possible to add it @pracucci and let me do some experimentation to see if it possible without breaking io.Reader compatibility. |
Actually no its not possible since Read() semantics allows shorter reads i.e Read(buf(n)) is allowed to be not equal to n1 returned value If you look at the Add further validation for it such that look at |
We can also try to mitigated it on our side. I'm just wondering if the Minio behaviour is expected or not because may potentially lead to issues hard to debug (we're hearing such issue since a long time and I figured it out just today). |
The problem is perhaps our readFull() implementation is hiding the real io.ErrUnexpectedEOF v/s io.ErrUnexpectedEOF because of the buffer is bigger than the underlying stream. Let me think more. |
So I tested with a test code @pracucci I see that io.ErrUnexpectedEOF is correctly returned package minio
import (
"context"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetObjectReturnErrorIfServerTruncatesResponse(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Last-Modified", "Wed, 21 Oct 2015 07:28:00 GMT")
w.Header().Set("Content-Length", "100")
// Write less bytes than the content length.
w.Write([]byte("12345"))
}))
defer srv.Close()
// New - instantiate minio client with options
clnt, err := New(srv.Listener.Addr().String(), &Options{})
obj, err := clnt.GetObject(context.Background(), "bucketName", "objectName", GetObjectOptions{})
if err != nil {
t.Fatal(err)
}
// We expect an error when reading back.
if _, err = ioutil.ReadAll(obj); err != io.ErrUnexpectedEOF {
t.Fatalf("Expected %v, got %v", io.ErrUnexpectedEOF, err)
}
}
|
Oh wait there is an issue in the test my bad! |
Yep reproduced it. |
this PR also adds tests to handle these cases specially fixes minio#1451
this PR also adds tests to handle these cases specially fixes minio#1451
PR #1452 should fix this properly once and for all. |
this PR also adds tests to handle these cases specially fixes #1451
Thanks a lot @harshavardhana ! |
As a continuation of work from minio#1452, when object sizes are bigger, we should calculate totalRead and match with expected object size. fixes minio#1451
Thanks a lot for quick turnaround 🤗 |
Thanos and Cortex are using the Minio client as S3 client. From time to time we've some reports of bugs that looks like if we get a partial/truncated response from the server which is not treated as an error from our application.
I've tried to simulate a scenario (which I don't know how much realistic could be) where the server returns a body response smaller than the
Content-Length
. The MinioObject.Read()
returns no error once all response has been consumed while, as comparison, the Google GCS client does returnio.ErrUnexpectedEOF
.I've added a test in Thanos to show it:
thanos-io/thanos#3795
Questions:
Content-Length
?The text was updated successfully, but these errors were encountered: