-
Notifications
You must be signed in to change notification settings - Fork 507
fix: allow range headers to be set in getObject request when offset is 0 (#706) #707
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
fix: allow range headers to be set in getObject request when offset is 0 (#706) #707
Conversation
|
Some notes for anyone reviewing this:
It seems like there may be some sort of regression in one of the more recent versions of minio, but I haven't really tracked that down just yet. In any case, it doesn't look like the test failure is really caused by anything specifically added by my branch. Here is a docker-compose file snippet that can be used to spin up a test environment to show the different behaviors:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not a regression we fixed a compatibility issue, the PR here is changing certain assumptions.
getObject_test6() is for an empty object and for empty objects according to S3 protocol one should return InvalidRange and it is a valid exception.
| throw new InvalidArgumentException("length should be greater than zero"); | ||
| } | ||
|
|
||
| Map<String,String> headerMap = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is an incomplete implementation follow this to be implement all variations
https://github.com/minio/minio-go/blob/master/api-get-options.go#L101
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getObject() in minio-java does accept offset and length not range i.e. not start/end values. With this existing fix is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are three allowed behaviors
- bytes=N-M
- bytes=N-
- bytes=-M
In minio-java the last one is not supported this is what I meant by complete implementation @balamurugana
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meaning of offset and length are different than range i.e. offset=-8 and length=4 means move to 8 byte position before current position and read 4 bytes. This is not possible to be translated into range. Either offset/length need to be replaced with start/end or leave the current behaviour as is (not possible to support byte=-M)
| if (length != null) { | ||
| headerMap.put("Range", "bytes=" + offset + "-" + (offset + length - 1)); | ||
| } else { | ||
| // results in a 416 with response message "The requested range is not satisfiable" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is not needed
functional/FunctionalTest.java
Outdated
| String objectName = getRandomName(); | ||
| try (final InputStream is = new ContentInputStream(3 * MB)) { | ||
| client.putObject(bucketName, objectName, is, 3 * MB, nullContentType); | ||
| try (final InputStream is = new ContentInputStream(1024)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add new tests than changing existing ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the new test case (with the assertions about the bytes that should be received from the partial getObject request) into getObject_test8 in the functional suite. I had to make minor updates to two other functional tests that were leaving behind objects in the shared bucket and causing listObject_test5 to fail in error; those other tests should now be cleaning up after themselves.
7799e85 to
04c45c1
Compare
|
@harshavardhana @balamurugana can you please take another look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything else LGTM @christopher-fredregill - thanks
functional/FunctionalTest.java
Outdated
| try { | ||
| client.getObject(bucketName, objectName).close(); | ||
| } catch (final ErrorResponseException e) { | ||
| // current implementation results in request headers="Range: bytes=0-"; response is a 416 with the given message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this comment, this is an expected response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
04c45c1 to
e4bcf70
Compare
functional/FunctionalTest.java
Outdated
| if (!e.toString().contains("message=The requested range is not satisfiable")) { | ||
| throw e; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unable to understand this change. Why is it required for this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original test catches and re-throws any exception it encounters.
I modified the behavior of the client, such that a known 416 exception will always be encountered here.
The test now has to know in advance that it will see this kind of exception and accept it, or else it will simply fail.
This is why I included comments explaining this in both the client code and in the fictional test code.
Some sort of change is necessary here... maybe you can propose an alternative solution, if this doesn’t suit you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is we send offset requests by default now - after this PR change even for empty objects which is not allowed in S3
This exception check is needed, or we make sure in this test Range is not set for empty objects.
e4bcf70 to
ce617c0
Compare
ce617c0 to
d0d9f67
Compare
|
We could add a test to generate the 416 range not satisfiable with offset=1 for a zero byte object @christopher-fredregill upto you though. This PR is okay to be merged. |
fix: allow range headers to be set in getObject request when offset is 0 (#706)
fixes #706