forked from TrueCloudLab/frostfs-s3-gw
[#619] Fix content-length invalid check
Signed-off-by: Roman Loginov <r.loginov@yadro.com>
This commit is contained in:
parent
711d6b2c71
commit
bfec3e0a5e
2 changed files with 117 additions and 7 deletions
|
@ -54,17 +54,29 @@ func (p *postPolicy) condition(key string) *policyCondition {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *postPolicy) CheckContentLength(size uint64) bool {
|
||||
func (p *postPolicy) CheckContentLength(size uint64) error {
|
||||
if p.empty {
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
for _, condition := range p.Conditions {
|
||||
if condition.Matching == "content-length-range" {
|
||||
length := strconv.FormatUint(size, 10)
|
||||
return condition.Key <= length && length <= condition.Value
|
||||
start, err := strconv.ParseUint(condition.Key, 10, 64)
|
||||
if err != nil {
|
||||
return errInvalidCondition
|
||||
}
|
||||
|
||||
end, err := strconv.ParseUint(condition.Value, 10, 64)
|
||||
if err != nil {
|
||||
return errInvalidCondition
|
||||
}
|
||||
|
||||
if start <= size && size <= end {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("length of the content did not fall within the range specified in the condition")
|
||||
}
|
||||
}
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *policyCondition) match(value string) bool {
|
||||
|
@ -560,8 +572,8 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if !policy.CheckContentLength(size) {
|
||||
h.logAndSendError(ctx, w, "invalid content-length", reqInfo, apierr.GetAPIError(apierr.ErrInvalidArgument))
|
||||
if err := policy.CheckContentLength(size); err != nil {
|
||||
h.logAndSendError(ctx, w, err.Error(), reqInfo, apierr.GetAPIError(apierr.ErrPostPolicyConditionInvalidFormat))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1206,6 +1206,104 @@ func TestFormEncryptionParamsBase(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCheckContentLength(t *testing.T) {
|
||||
contentLength := "content-length-range"
|
||||
notFallError := "length of the content did not fall within the range specified in the condition"
|
||||
parseError := "invalid condition"
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
matching string
|
||||
key string
|
||||
value string
|
||||
size uint64
|
||||
errMsg string
|
||||
emptyPolicy bool
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
matching: contentLength,
|
||||
key: "0",
|
||||
value: "1000",
|
||||
size: 50,
|
||||
},
|
||||
{
|
||||
name: "valid lower limit",
|
||||
matching: contentLength,
|
||||
key: "5",
|
||||
value: "100",
|
||||
size: 5,
|
||||
},
|
||||
{
|
||||
name: "valid upper limit",
|
||||
matching: contentLength,
|
||||
key: "5",
|
||||
value: "100",
|
||||
size: 100,
|
||||
},
|
||||
{
|
||||
name: "invalid size value (too small)",
|
||||
matching: contentLength,
|
||||
key: "5",
|
||||
value: "100",
|
||||
size: 2,
|
||||
errMsg: notFallError,
|
||||
},
|
||||
{
|
||||
name: "invalid size value (to high)",
|
||||
matching: contentLength,
|
||||
key: "5",
|
||||
value: "100",
|
||||
size: 200,
|
||||
errMsg: notFallError,
|
||||
},
|
||||
{
|
||||
name: "no matching",
|
||||
},
|
||||
{
|
||||
name: "invalid key type",
|
||||
matching: contentLength,
|
||||
key: "invalid",
|
||||
value: "100",
|
||||
size: 10,
|
||||
errMsg: parseError,
|
||||
},
|
||||
{
|
||||
name: "invalid value type",
|
||||
matching: contentLength,
|
||||
key: "5",
|
||||
value: "invalid",
|
||||
size: 10,
|
||||
errMsg: parseError,
|
||||
},
|
||||
{
|
||||
name: "empty policy",
|
||||
emptyPolicy: true,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
policy := &postPolicy{
|
||||
Conditions: []*policyCondition{
|
||||
{
|
||||
Matching: tc.matching,
|
||||
Key: tc.key,
|
||||
Value: tc.value,
|
||||
},
|
||||
},
|
||||
empty: tc.emptyPolicy,
|
||||
}
|
||||
|
||||
err := policy.CheckContentLength(tc.size)
|
||||
if tc.errMsg != "" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), tc.errMsg)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func prepareRequestForEncryption(hc *handlerContext, algo, key, md5, tlsTermination string, reqWithoutTLS, reqWithoutSSE, isCopySource bool) *http.Request {
|
||||
r := httptest.NewRequest(http.MethodPost, "/", nil)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue