2021-06-24 11:10:00 +00:00
|
|
|
package handler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"testing"
|
2021-07-02 16:05:43 +00:00
|
|
|
"time"
|
2021-06-24 11:10:00 +00:00
|
|
|
|
2021-09-10 06:56:56 +00:00
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
2021-08-09 08:53:58 +00:00
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
2021-06-24 11:10:00 +00:00
|
|
|
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestFetchRangeHeader(t *testing.T) {
|
|
|
|
for _, tc := range []struct {
|
|
|
|
header string
|
|
|
|
expected *layer.RangeParams
|
|
|
|
fullSize uint64
|
|
|
|
err bool
|
|
|
|
}{
|
2021-08-06 09:59:28 +00:00
|
|
|
{header: "bytes=0-256", expected: &layer.RangeParams{Start: 0, End: 256}, fullSize: 257, err: false},
|
|
|
|
{header: "bytes=0-0", expected: &layer.RangeParams{Start: 0, End: 0}, fullSize: 1, err: false},
|
|
|
|
{header: "bytes=0-256", expected: &layer.RangeParams{Start: 0, End: 255}, fullSize: 256, err: false},
|
2021-06-24 11:10:00 +00:00
|
|
|
{header: "bytes=0-", expected: &layer.RangeParams{Start: 0, End: 99}, fullSize: 100, err: false},
|
|
|
|
{header: "bytes=-10", expected: &layer.RangeParams{Start: 90, End: 99}, fullSize: 100, err: false},
|
|
|
|
{header: "", err: false},
|
|
|
|
{header: "bytes=-1-256", err: true},
|
|
|
|
{header: "bytes=256-0", err: true},
|
|
|
|
{header: "bytes=string-0", err: true},
|
|
|
|
{header: "bytes=0-string", err: true},
|
|
|
|
{header: "bytes:0-256", err: true},
|
|
|
|
{header: "bytes:-", err: true},
|
2021-08-06 09:59:28 +00:00
|
|
|
{header: "bytes=0-0", fullSize: 0, err: true},
|
|
|
|
{header: "bytes=10-20", fullSize: 5, err: true},
|
2021-06-24 11:10:00 +00:00
|
|
|
} {
|
|
|
|
h := make(http.Header)
|
|
|
|
h.Add("Range", tc.header)
|
|
|
|
params, err := fetchRangeHeader(h, tc.fullSize)
|
|
|
|
if tc.err {
|
|
|
|
require.Error(t, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tc.expected, params)
|
|
|
|
}
|
|
|
|
}
|
2021-07-02 16:05:43 +00:00
|
|
|
|
2021-09-10 06:56:56 +00:00
|
|
|
func newInfo(etag string, created time.Time) *data.ObjectInfo {
|
|
|
|
return &data.ObjectInfo{
|
2021-07-02 16:05:43 +00:00
|
|
|
HashSum: etag,
|
|
|
|
Created: created,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPreconditions(t *testing.T) {
|
|
|
|
today := time.Now()
|
|
|
|
yesterday := today.Add(-24 * time.Hour)
|
|
|
|
etag := "etag"
|
|
|
|
etag2 := "etag2"
|
|
|
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
name string
|
2021-09-10 06:56:56 +00:00
|
|
|
info *data.ObjectInfo
|
2021-07-02 16:21:53 +00:00
|
|
|
args *conditionalArgs
|
2021-07-14 12:51:45 +00:00
|
|
|
expected error
|
2021-07-02 16:05:43 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no conditions",
|
2021-09-10 06:56:56 +00:00
|
|
|
info: new(data.ObjectInfo),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: new(conditionalArgs),
|
2021-07-14 12:51:45 +00:00
|
|
|
expected: nil,
|
2021-07-02 16:05:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "IfMatch true",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfMatch: etag},
|
2021-07-14 12:51:45 +00:00
|
|
|
expected: nil,
|
2021-07-02 16:05:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "IfMatch false",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfMatch: etag2},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrPreconditionFailed)},
|
2021-07-02 16:05:43 +00:00
|
|
|
{
|
|
|
|
name: "IfNoneMatch true",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfNoneMatch: etag2},
|
2021-07-14 12:51:45 +00:00
|
|
|
expected: nil},
|
2021-07-02 16:05:43 +00:00
|
|
|
{
|
|
|
|
name: "IfNoneMatch false",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfNoneMatch: etag},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrNotModified)},
|
2021-07-02 16:05:43 +00:00
|
|
|
{
|
|
|
|
name: "IfModifiedSince true",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfModifiedSince: &yesterday},
|
2021-07-14 12:51:45 +00:00
|
|
|
expected: nil},
|
2021-07-02 16:05:43 +00:00
|
|
|
{
|
|
|
|
name: "IfModifiedSince false",
|
|
|
|
info: newInfo(etag, yesterday),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfModifiedSince: &today},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrNotModified)},
|
2021-07-02 16:05:43 +00:00
|
|
|
{
|
|
|
|
name: "IfUnmodifiedSince true",
|
|
|
|
info: newInfo(etag, yesterday),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfUnmodifiedSince: &today},
|
2021-07-14 12:51:45 +00:00
|
|
|
expected: nil},
|
2021-07-02 16:05:43 +00:00
|
|
|
{
|
|
|
|
name: "IfUnmodifiedSince false",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfUnmodifiedSince: &yesterday},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrPreconditionFailed)},
|
2021-07-02 16:05:43 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
name: "IfMatch true, IfUnmodifiedSince false",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfMatch: etag, IfUnmodifiedSince: &yesterday},
|
2021-07-14 12:51:45 +00:00
|
|
|
expected: nil,
|
2021-07-02 16:05:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "IfMatch false, IfUnmodifiedSince true",
|
|
|
|
info: newInfo(etag, yesterday),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfMatch: etag2, IfUnmodifiedSince: &today},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrPreconditionFailed),
|
2021-07-02 16:05:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "IfNoneMatch false, IfModifiedSince true",
|
|
|
|
info: newInfo(etag, today),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfNoneMatch: etag, IfModifiedSince: &yesterday},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrNotModified),
|
2021-07-02 16:05:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "IfNoneMatch true, IfModifiedSince false",
|
|
|
|
info: newInfo(etag, yesterday),
|
2021-07-02 16:21:53 +00:00
|
|
|
args: &conditionalArgs{IfNoneMatch: etag2, IfModifiedSince: &today},
|
2021-08-09 08:53:58 +00:00
|
|
|
expected: errors.GetAPIError(errors.ErrNotModified),
|
2021-07-02 16:05:43 +00:00
|
|
|
},
|
|
|
|
} {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
2021-07-02 16:21:53 +00:00
|
|
|
actual := checkPreconditions(tc.info, tc.args)
|
2021-07-02 16:05:43 +00:00
|
|
|
require.Equal(t, tc.expected, actual)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|