-
Notifications
You must be signed in to change notification settings - Fork 657
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
api, core: Add new Core API {Get,Stat}Object with pre-conditions. #670
Conversation
b82a6f5
to
645600a
Compare
api-get-conditions.go
Outdated
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html | ||
type GetConditions struct { | ||
http.Header | ||
} |
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.
why not:
type PreConditions http.Header
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.
Too generic we already have CopyConditions.
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.
But PreConditions are generic header information ... i.e it can apply to HEAD too if required.
SetRange
does not sound right for a "Conditions" type.
You could name it just Header
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.
Ah you are right.
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.
SetRange is appropriate as it is part of the conditions here http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html - Header is not conveying any information.
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.
SetRange is under Request Headers
section not conditions. i.e Preconditions belongs to Request Headers
but Range does not belong to Preconditions
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.
Range also is part of a pre-condition such that you need to validate the requested range first. So i don't agree.
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.
From a HTTP point of view you are right Range is not part of Pre-Conditions - https://tools.ietf.org/html/rfc7232#section-3 one needs to set If-Range. But AWS S3 doesn't support that yet.
api-get-object-file.go
Outdated
// Initialize get object conditions and set the appropriate | ||
// range offsets to read from. | ||
conds := GetConditions{} | ||
conds.SetRange(st.Size(), 0) |
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.
will panic as the map is nil
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.
Ah will change this.
e4e3603
to
6245b83
Compare
pre-conditions.go
Outdated
// SetRange - set the start and end offset of the object to be read. | ||
// See https://tools.ietf.org/html/rfc7233#section-3.1 for reference. | ||
func (c PreConditions) SetRange(start, end int64) error { | ||
if start < 0 || end > 0 && end < start { |
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.
Can you reject when end is negative, it looks it can pass when end = -1 and start = 1 for example.
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.
End negative is a valid case.. though.
api-get-object-partial.go
Outdated
@@ -0,0 +1,17 @@ | |||
package minio |
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.
Looks like this file is not needed.
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.
will remove.
api-get-object-file.go
Outdated
// Initialize get object conditions and set the appropriate | ||
// range offsets to read from. | ||
conds := NewPreConditions() | ||
conds.SetRange(st.Size(), 0) |
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 should be conds.SetRange(0, st.Size()-1)
I understand the meaning of end = 0 now.
pre-conditions.go
Outdated
|
||
// SetRange - set the start and end offset of the object to be read. | ||
// See https://tools.ietf.org/html/rfc7233#section-3.1 for reference. | ||
func (c PreConditions) SetRange(start, end int64) error { |
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't download only the first byte with this primitive.
SetRange(0, 0) should be able to return the first byte.
I think end
should be -1 when we need to indicate that we want to download from start until the end of the target object.
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.
Yes there are more cases in pure HTTP, But all cases are not supported by AWS S3.
bad0b1b
to
e69012b
Compare
Can you check again @krishnasrinivas @vadmeste |
request-headers.go
Outdated
case start > 0 && end > 0 && end > start: | ||
// Read everything starting at 'start' till the 'end'. `bytes=N-M` | ||
c.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end)) | ||
case start == 0 && end == 0: |
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.
Only the first byte?
I guess S3 can support reading one byte in other positions. You can merge this case with the previous one, so it would be: case start > 0 && end > 0 && end >= start:
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.
Done
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.
One comment
86bdf05
to
a6f206c
Compare
core_test.go
Outdated
io.ReadFull(reader, buf3) | ||
reader.Close() | ||
|
||
if objectInfo.Size != int64(len(buf3)) { |
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 above check doesn't guarantee that len(buf3)
bytes were read from reader
. The check should be,
n, err = io.ReadFull(reader, buf3)
if err != nil {
t.Fatal(err)
}
if objectInfo.Size != n {
t.Fatal(err)
}
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.
Why do you think that ?
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.
Number of bytes read would be different than len(buf3)
if io.ReadFull
returned with io.UnexpectedEOF
.
api-get-object-file.go
Outdated
// Initialize get object conditions and set the appropriate | ||
// range offsets to read from. | ||
reqHeaders := NewGetReqHeaders() | ||
reqHeaders.SetRange(st.Size(), 0) |
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.
As per, case start > 0 && end == 0:
in SetRange(...)
method this reqHeaders
will request bytes of object starting from st.Size()
to EOF, which is not intended. Shouldn't it be SetRange(0, -st.Size())
?
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 don't think so..
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.
@harshavardhana which case statement would match SetRange(st.Size(), 0)
, where st.Size() > 0
?
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.
@krisis it looks confusing but st.Size() is actually size of the partially downloaded file, not the size of the object
a6f206c
to
5bf96ba
Compare
5bf96ba
to
d09fe2a
Compare
982ad47
to
3aa4ee3
Compare
Implements a new API to provide a way to set headers for GetObject(), StatObject() request such as to - read partial data starting at offsets. - read only if etag matches. - read only if modtime matches. - read only if etag doesn't match. - read only if modtime doesn't match. Fixes minio#669
3aa4ee3
to
c6a7758
Compare
Implements a new API to provide a way to set headers
for GetObject(), StatObject() request such as to
Fixes #669