mirror of
https://github.com/versity/versitygw.git
synced 2026-09-19 22:44:28 +00:00
feat: implements conditional reads for GetObject and HeadObject
Closes #882 Implements conditional reads for `GetObject` and `HeadObject` in the gateway for both POSIX and Azure backends. The behavior is controlled by the `If-Match`, `If-None-Match`, `If-Modified-Since`, and `If-Unmodified-Since` request headers, where the first two perform ETag comparisons and the latter two compare against the object’s `LastModified` date. No validation is performed for invalid ETags or malformed date formats, and precondition date headers are expected to follow RFC1123; otherwise, they are ignored. The Integration tests cover all possible combinations of conditional headers, ensuring the feature is 100% AWS S3–compatible.
This commit is contained in:
@@ -642,6 +642,59 @@ func ParseCreateMpChecksumHeaders(ctx *fiber.Ctx) (types.ChecksumAlgorithm, type
|
||||
return algo, chType, nil
|
||||
}
|
||||
|
||||
// ConditionalHeaders holds the conditional header values
|
||||
type ConditionalHeaders struct {
|
||||
IfMatch *string
|
||||
IfNoneMatch *string
|
||||
IfModSince *time.Time
|
||||
IfUnmodeSince *time.Time
|
||||
}
|
||||
|
||||
// ParsePreconditionHeaders parses the precondition headers:
|
||||
// - If-Match
|
||||
// - If-None-Match
|
||||
// - If-Modified-Since
|
||||
// - If-Unmodified-Since
|
||||
func ParsePreconditionHeaders(ctx *fiber.Ctx) ConditionalHeaders {
|
||||
ifMatch, ifNoneMatch := ParsePreconditionMatchHeaders(ctx)
|
||||
ifModSince, ifUnmodeSince := ParsePreconditionDateHeaders(ctx)
|
||||
|
||||
return ConditionalHeaders{
|
||||
IfMatch: ifMatch,
|
||||
IfNoneMatch: ifNoneMatch,
|
||||
IfModSince: ifModSince,
|
||||
IfUnmodeSince: ifUnmodeSince,
|
||||
}
|
||||
}
|
||||
|
||||
// ParsePreconditionMatchHeaders extracts "If-Match" and "If-None-Match" headers from fiber Ctx
|
||||
func ParsePreconditionMatchHeaders(ctx *fiber.Ctx) (*string, *string) {
|
||||
return GetStringPtr(ctx.Get("If-Match")), GetStringPtr(ctx.Get("If-None-Match"))
|
||||
}
|
||||
|
||||
// ParsePreconditionDateHeaders parses the "If-Modified-Since" and "If-Unmodified-Since"
|
||||
// headers from fiber context to *time.Time
|
||||
func ParsePreconditionDateHeaders(ctx *fiber.Ctx) (*time.Time, *time.Time) {
|
||||
ifModSince := ctx.Get("If-Modified-Since")
|
||||
ifUnmodSince := ctx.Get("If-Unmodified-Since")
|
||||
|
||||
var ifModSinceParsed, ifUnmodSinceParsed *time.Time
|
||||
|
||||
// the time format should be a valid RFC1123
|
||||
// if parsing fails, ignore the error and leave the value as nil
|
||||
modParsed, err := time.Parse(time.RFC1123, ifModSince)
|
||||
if err == nil {
|
||||
ifModSinceParsed = &modParsed
|
||||
}
|
||||
|
||||
unmodParsed, err := time.Parse(time.RFC1123, ifUnmodSince)
|
||||
if err == nil {
|
||||
ifUnmodSinceParsed = &unmodParsed
|
||||
}
|
||||
|
||||
return ifModSinceParsed, ifUnmodSinceParsed
|
||||
}
|
||||
|
||||
// TagLimit specifies the allowed tag count in a tag set
|
||||
type TagLimit int
|
||||
|
||||
|
||||
Reference in New Issue
Block a user