forked from TrueCloudLab/frostfs-s3-gw
[#189] Add bucket name checking
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
b555a1b1d8
commit
7eb9713a67
2 changed files with 85 additions and 0 deletions
|
@ -3,6 +3,7 @@ package handler
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -73,6 +74,11 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
p = layer.CreateBucketParams{Name: reqInfo.BucketName}
|
p = layer.CreateBucketParams{Name: reqInfo.BucketName}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if err = checkBucketName(reqInfo.BucketName); err != nil {
|
||||||
|
h.logAndSendError(w, "invalid bucket name", reqInfo, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if val, ok := r.Header["X-Amz-Acl"]; ok {
|
if val, ok := r.Header["X-Amz-Acl"]; ok {
|
||||||
p.ACL, err = parseBasicACL(val[0])
|
p.ACL, err = parseBasicACL(val[0])
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,6 +130,40 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
api.WriteSuccessResponseHeadersOnly(w)
|
api.WriteSuccessResponseHeadersOnly(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkBucketName(bucketName string) error {
|
||||||
|
if len(bucketName) < 3 || len(bucketName) > 63 {
|
||||||
|
return api.GetAPIError(api.ErrInvalidBucketName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(bucketName, "xn--") || strings.HasSuffix(bucketName, "-s3alias") {
|
||||||
|
return api.GetAPIError(api.ErrInvalidBucketName)
|
||||||
|
}
|
||||||
|
if net.ParseIP(bucketName) != nil {
|
||||||
|
return api.GetAPIError(api.ErrInvalidBucketName)
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := strings.Split(bucketName, ".")
|
||||||
|
for _, label := range labels {
|
||||||
|
if len(label) == 0 {
|
||||||
|
return api.GetAPIError(api.ErrInvalidBucketName)
|
||||||
|
}
|
||||||
|
for i, r := range label {
|
||||||
|
if !isAlphaNum(r) && r != '-' {
|
||||||
|
return api.GetAPIError(api.ErrInvalidBucketName)
|
||||||
|
}
|
||||||
|
if (i == 0 || i == len(label)-1) && r == '-' {
|
||||||
|
return api.GetAPIError(api.ErrInvalidBucketName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isAlphaNum(char int32) bool {
|
||||||
|
return 'a' <= char && char <= 'z' || '0' <= char && char <= '9'
|
||||||
|
}
|
||||||
|
|
||||||
func parseLocationConstraint(r *http.Request) (*createBucketParams, error) {
|
func parseLocationConstraint(r *http.Request) (*createBucketParams, error) {
|
||||||
if r.ContentLength == 0 {
|
if r.ContentLength == 0 {
|
||||||
return new(createBucketParams), nil
|
return new(createBucketParams), nil
|
||||||
|
|
45
api/handler/put_test.go
Normal file
45
api/handler/put_test.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCheckBucketName(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
err bool
|
||||||
|
}{
|
||||||
|
{name: "bucket"},
|
||||||
|
{name: "2bucket"},
|
||||||
|
{name: "buc.ket"},
|
||||||
|
{name: "buc-ket"},
|
||||||
|
{name: "abc"},
|
||||||
|
{name: "63aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
|
||||||
|
{name: "buc.-ket", err: true},
|
||||||
|
{name: "bucket.", err: true},
|
||||||
|
{name: ".bucket", err: true},
|
||||||
|
{name: "bucket.", err: true},
|
||||||
|
{name: "bucket-", err: true},
|
||||||
|
{name: "-bucket", err: true},
|
||||||
|
{name: "Bucket", err: true},
|
||||||
|
{name: "buc.-ket", err: true},
|
||||||
|
{name: "buc-.ket", err: true},
|
||||||
|
{name: "Bucket", err: true},
|
||||||
|
{name: "buc!ket", err: true},
|
||||||
|
{name: "buc_ket", err: true},
|
||||||
|
{name: "xn--bucket", err: true},
|
||||||
|
{name: "bucket-s3alias", err: true},
|
||||||
|
{name: "192.168.0.1", err: true},
|
||||||
|
{name: "as", err: true},
|
||||||
|
{name: "64aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", err: true},
|
||||||
|
} {
|
||||||
|
err := checkBucketName(tc.name)
|
||||||
|
if tc.err {
|
||||||
|
require.Error(t, err, "bucket name: %s", tc.name)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err, "bucket name: %s", tc.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue