Compare commits
22 Commits
RELEASE.20
...
RELEASE.20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c85ce1afd | ||
|
|
710db6bdad | ||
|
|
058ea84605 | ||
|
|
6e7d33df20 | ||
|
|
5311eb22fd | ||
|
|
83abb310b4 | ||
|
|
3d98311d9f | ||
|
|
d44e38b462 | ||
|
|
8948c972ee | ||
|
|
29b49f9343 | ||
|
|
f8e4700a11 | ||
|
|
4c5c00c640 | ||
|
|
0be44133d4 | ||
|
|
817e763416 | ||
|
|
0abab5305f | ||
|
|
e6e855a7cf | ||
|
|
6fca1d164c | ||
|
|
9b76eba37e | ||
|
|
03714d4809 | ||
|
|
3a73ea3f54 | ||
|
|
9625629fc7 | ||
|
|
8507ce2a87 |
@@ -11,7 +11,7 @@ RUN \
|
||||
apk add --no-cache --virtual .build-deps git go musl-dev && \
|
||||
go get -v -d github.com/minio/minio && \
|
||||
cd /go/src/github.com/minio/minio && \
|
||||
go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \
|
||||
go install -v -ldflags "-X github.com/minio/minio/cmd.Version=2017-04-25T01:27:49Z -X github.com/minio/minio/cmd.ReleaseTag=RELEASE.2017-04-25T01-27-49Z -X github.com/minio/minio/cmd.CommitID=710db6bdadb1b228bf6dee7e2a6958000091125b" && \
|
||||
rm -rf /go/pkg /go/src /usr/local/go && apk del .build-deps
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
@@ -11,7 +11,7 @@ RUN \
|
||||
apk add --no-cache --virtual .build-deps git go musl-dev && \
|
||||
go get -v -d github.com/minio/minio && \
|
||||
cd /go/src/github.com/minio/minio && \
|
||||
go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \
|
||||
go install -v -ldflags "-X github.com/minio/minio/cmd.Version=2017-03-16T21:50:32Z -X github.com/minio/minio/cmd.ReleaseTag=RELEASE.2017-03-16T21-50-32Z -X github.com/minio/minio/cmd.CommitID=5311eb22fd681a8cd4a46e2a872d46c2352c64e8" && \
|
||||
rm -rf /go/pkg /go/src /usr/local/go && apk del .build-deps
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
@@ -11,7 +11,7 @@ RUN \
|
||||
apk add --no-cache --virtual .build-deps git go musl-dev && \
|
||||
go get -v -d github.com/minio/minio && \
|
||||
cd /go/src/github.com/minio/minio && \
|
||||
go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \
|
||||
go install -v -ldflags "-X github.com/minio/minio/cmd.Version=2017-03-16T21:50:32Z -X github.com/minio/minio/cmd.ReleaseTag=RELEASE.2017-03-16T21-50-32Z -X github.com/minio/minio/cmd.CommitID=5311eb22fd681a8cd4a46e2a872d46c2352c64e8" && \
|
||||
rm -rf /go/pkg /go/src /usr/local/go && apk del .build-deps
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
LDFLAGS := $(shell go run buildscripts/gen-ldflags.go)
|
||||
PWD := $(shell pwd)
|
||||
GOPATH := $(shell go env GOPATH)
|
||||
BUILD_LDFLAGS := '$(LDFLAGS)'
|
||||
BUILD_LDFLAGS := '$(LDFLAGS) -s -w'
|
||||
TAG := latest
|
||||
|
||||
HOST ?= $(shell uname)
|
||||
|
||||
@@ -53,7 +53,7 @@ go_build() {
|
||||
|
||||
release_bin_6="$release_str/$os-${arch}6vl/$(basename $package).$release_tag"
|
||||
## Support building for ARM6vl
|
||||
GOARM=6 GOOS=$os GOARCH=$arch go build --ldflags "${LDFLAGS}" -o $release_bin_6
|
||||
GOARM=6 GOOS=$os GOARCH=$arch go build --ldflags "-s -w ${LDFLAGS}" -o $release_bin_6
|
||||
|
||||
## Copy
|
||||
$CP -p $release_bin_6 $release_real_bin_6
|
||||
@@ -70,7 +70,7 @@ go_build() {
|
||||
|
||||
release_bin_7="$release_str/$os-$arch/$(basename $package).$release_tag"
|
||||
## Support building for ARM7vl
|
||||
GOARM=7 GOOS=$os GOARCH=$arch go build --ldflags "${LDFLAGS}" -o $release_bin_7
|
||||
GOARM=7 GOOS=$os GOARCH=$arch go build --ldflags "-s -w ${LDFLAGS}" -o $release_bin_7
|
||||
|
||||
## Copy
|
||||
$CP -p $release_bin_7 $release_real_bin_7
|
||||
@@ -82,7 +82,7 @@ go_build() {
|
||||
shasum_str=$(${SHASUM} ${release_bin_7})
|
||||
echo ${shasum_str} | $SED "s/$release_str\/$os-$arch\///g" > $release_shasum_7
|
||||
else
|
||||
GOOS=$os GOARCH=$arch go build --ldflags "${LDFLAGS}" -o $release_bin
|
||||
GOOS=$os GOARCH=$arch go build --ldflags "-s -w ${LDFLAGS}" -o $release_bin
|
||||
|
||||
# Create copy
|
||||
if [ $os == "windows" ]; then
|
||||
|
||||
@@ -139,6 +139,7 @@ const (
|
||||
ErrObjectExistsAsDirectory
|
||||
ErrPolicyNesting
|
||||
ErrInvalidObjectName
|
||||
ErrInvalidResourceName
|
||||
ErrServerNotInitialized
|
||||
// Add new extended error codes here.
|
||||
// Please open a https://github.com/minio/minio/issues before adding
|
||||
@@ -588,7 +589,12 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
||||
},
|
||||
ErrInvalidObjectName: {
|
||||
Code: "XMinioInvalidObjectName",
|
||||
Description: "Object name contains unsupported characters. Unsupported characters are `^*|\\\"",
|
||||
Description: "Object name contains unsupported characters.",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrInvalidResourceName: {
|
||||
Code: "XMinioInvalidResourceName",
|
||||
Description: "Resource name contains bad components such as \"..\" or \".\".",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrServerNotInitialized: {
|
||||
|
||||
@@ -407,3 +407,52 @@ func (h httpStatsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Update http statistics
|
||||
globalHTTPStats.updateStats(r, ww)
|
||||
}
|
||||
|
||||
// pathValidityHandler validates all the incoming paths for
|
||||
// any bad components and rejects them.
|
||||
type pathValidityHandler struct {
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
func setPathValidityHandler(h http.Handler) http.Handler {
|
||||
return pathValidityHandler{handler: h}
|
||||
}
|
||||
|
||||
// Bad path components to be rejected by the path validity handler.
|
||||
const (
|
||||
dotdotComponent = ".."
|
||||
dotComponent = "."
|
||||
)
|
||||
|
||||
// Check if the incoming path has bad path components,
|
||||
// such as ".." and "."
|
||||
func hasBadPathComponent(path string) bool {
|
||||
path = strings.TrimSpace(path)
|
||||
for _, p := range strings.Split(path, slashSeparator) {
|
||||
switch strings.TrimSpace(p) {
|
||||
case dotdotComponent:
|
||||
return true
|
||||
case dotComponent:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h pathValidityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Check for bad components in URL path.
|
||||
if hasBadPathComponent(r.URL.Path) {
|
||||
writeErrorResponse(w, ErrInvalidResourceName, r.URL)
|
||||
return
|
||||
}
|
||||
// Check for bad components in URL query values.
|
||||
for _, vv := range r.URL.Query() {
|
||||
for _, v := range vv {
|
||||
if hasBadPathComponent(v) {
|
||||
writeErrorResponse(w, ErrInvalidResourceName, r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
h.handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) {
|
||||
{"test-bucket-list-object", "", "", "*", 0, ListObjectsInfo{}, fmt.Errorf("delimiter '%s' is not supported", "*"), false},
|
||||
{"test-bucket-list-object", "", "", "-", 0, ListObjectsInfo{}, fmt.Errorf("delimiter '%s' is not supported", "-"), false},
|
||||
// Testing for failure cases with both perfix and marker (11).
|
||||
// The prefix and marker combination to be valid it should satisy strings.HasPrefix(marker, prefix).
|
||||
// The prefix and marker combination to be valid it should satisfy strings.HasPrefix(marker, prefix).
|
||||
{"test-bucket-list-object", "asia", "europe-object", "", 0, ListObjectsInfo{}, fmt.Errorf("Invalid combination of marker '%s' and prefix '%s'", "europe-object", "asia"), false},
|
||||
// Setting a non-existing directory to be prefix (12-13).
|
||||
{"empty-bucket", "europe/france/", "", "", 1, ListObjectsInfo{}, nil, true},
|
||||
|
||||
@@ -1110,7 +1110,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
{bucketNames[0], "", "", "", "*", 0, ListMultipartsInfo{}, fmt.Errorf("delimiter '%s' is not supported", "*"), false},
|
||||
{bucketNames[0], "", "", "", "-", 0, ListMultipartsInfo{}, fmt.Errorf("delimiter '%s' is not supported", "-"), false},
|
||||
// Testing for failure cases with both perfix and marker (Test number 10).
|
||||
// The prefix and marker combination to be valid it should satisy strings.HasPrefix(marker, prefix).
|
||||
// The prefix and marker combination to be valid it should satisfy strings.HasPrefix(marker, prefix).
|
||||
{bucketNames[0], "asia", "europe-object", "", "", 0, ListMultipartsInfo{},
|
||||
fmt.Errorf("Invalid combination of marker '%s' and prefix '%s'", "europe-object", "asia"), false},
|
||||
// Setting an invalid combination of uploadIDMarker and Marker (Test number 11-12).
|
||||
|
||||
@@ -131,6 +131,9 @@ func IsValidObjectName(object string) bool {
|
||||
// IsValidObjectPrefix verifies whether the prefix is a valid object name.
|
||||
// Its valid to have a empty prefix.
|
||||
func IsValidObjectPrefix(object string) bool {
|
||||
if hasBadPathComponent(object) {
|
||||
return false
|
||||
}
|
||||
if len(object) > 1024 {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -100,12 +100,22 @@ func TestIsValidObjectName(t *testing.T) {
|
||||
{"contains-|-pipe", true},
|
||||
{"contains-\"-quote", true},
|
||||
{"contains-`-tick", true},
|
||||
{"..test", true},
|
||||
{".. test", true},
|
||||
{". test", true},
|
||||
{".test", true},
|
||||
{"There are far too many object names, and far too few bucket names!", true},
|
||||
// cases for which test should fail.
|
||||
// passing invalid object names.
|
||||
{"", false},
|
||||
{"a/b/c/", false},
|
||||
{"/a/b/c", false},
|
||||
{"../../etc", false},
|
||||
{"../../", false},
|
||||
{"/../../etc", false},
|
||||
{" ../etc", false},
|
||||
{"./././", false},
|
||||
{"./etc", false},
|
||||
{"contains-\\-backslash", false},
|
||||
{string([]byte{0xff, 0xfe, 0xfd}), false},
|
||||
}
|
||||
|
||||
@@ -316,6 +316,58 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
|
||||
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), getGetObjectURL("", bucketName, objectName))),
|
||||
expectedRespStatus: http.StatusForbidden,
|
||||
},
|
||||
// Test case - 7.
|
||||
// Case with bad components in object name.
|
||||
{
|
||||
bucketName: bucketName,
|
||||
objectName: "../../etc",
|
||||
byteRange: "",
|
||||
accessKey: credentials.AccessKey,
|
||||
secretKey: credentials.SecretKey,
|
||||
|
||||
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName),
|
||||
getGetObjectURL("", bucketName, "../../etc"))),
|
||||
expectedRespStatus: http.StatusBadRequest,
|
||||
},
|
||||
// Test case - 8.
|
||||
// Case with strange components but returning error as not found.
|
||||
{
|
||||
bucketName: bucketName,
|
||||
objectName: ". ./. ./etc",
|
||||
byteRange: "",
|
||||
accessKey: credentials.AccessKey,
|
||||
secretKey: credentials.SecretKey,
|
||||
|
||||
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey),
|
||||
"/"+bucketName+"/"+". ./. ./etc")),
|
||||
expectedRespStatus: http.StatusNotFound,
|
||||
},
|
||||
// Test case - 9.
|
||||
// Case with bad components in object name.
|
||||
{
|
||||
bucketName: bucketName,
|
||||
objectName: ". ./../etc",
|
||||
byteRange: "",
|
||||
accessKey: credentials.AccessKey,
|
||||
secretKey: credentials.SecretKey,
|
||||
|
||||
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName),
|
||||
"/"+bucketName+"/"+". ./../etc")),
|
||||
expectedRespStatus: http.StatusBadRequest,
|
||||
},
|
||||
// Test case - 10.
|
||||
// Case with proper components
|
||||
{
|
||||
bucketName: bucketName,
|
||||
objectName: "etc/path/proper/.../etc",
|
||||
byteRange: "",
|
||||
accessKey: credentials.AccessKey,
|
||||
secretKey: credentials.SecretKey,
|
||||
|
||||
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey),
|
||||
getGetObjectURL("", bucketName, "etc/path/proper/.../etc"))),
|
||||
expectedRespStatus: http.StatusNotFound,
|
||||
},
|
||||
}
|
||||
|
||||
// Iterating over the cases, fetching the object validating the response.
|
||||
@@ -346,7 +398,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
|
||||
}
|
||||
// Verify whether the bucket obtained object is same as the one created.
|
||||
if !bytes.Equal(testCase.expectedContent, actualContent) {
|
||||
t.Errorf("Test %d: %s: Object content differs from expected value.: %s", i+1, instanceType, string(actualContent))
|
||||
t.Errorf("Test %d: %s: Object content differs from expected value %s, got %s", i+1, instanceType, testCase.expectedContent, string(actualContent))
|
||||
}
|
||||
|
||||
// Verify response of the V2 signed HTTP request.
|
||||
|
||||
@@ -85,6 +85,8 @@ func configureServerHandler(srvCmdConfig serverCmdConfig) (http.Handler, error)
|
||||
|
||||
// List of some generic handlers which are applied for all incoming requests.
|
||||
var handlerFns = []HandlerFunc{
|
||||
// Validate all the incoming paths.
|
||||
setPathValidityHandler,
|
||||
// Network statistics
|
||||
setHTTPStatsHandler,
|
||||
// Limits all requests size to a maximum fixed limit
|
||||
|
||||
@@ -170,7 +170,7 @@ func (s *TestSuiteCommon) TestObjectDir(c *C) {
|
||||
response, err = client.Do(request)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
verifyError(c, response, "XMinioInvalidObjectName", "Object name contains unsupported characters. Unsupported characters are `^*|\\\"", http.StatusBadRequest)
|
||||
verifyError(c, response, "XMinioInvalidObjectName", "Object name contains unsupported characters.", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func (s *TestSuiteCommon) TestBucketSQSNotificationAMQP(c *C) {
|
||||
@@ -1226,7 +1226,7 @@ func (s *TestSuiteCommon) TestPutObjectLongName(c *C) {
|
||||
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
verifyError(c, response, "XMinioInvalidObjectName", "Object name contains unsupported characters. Unsupported characters are `^*|\\\"", http.StatusBadRequest)
|
||||
verifyError(c, response, "XMinioInvalidObjectName", "Object name contains unsupported characters.", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
// TestNotBeAbleToCreateObjectInNonexistentBucket - Validates the error response
|
||||
|
||||
@@ -48,6 +48,9 @@ var errFileNotFound = errors.New("file not found")
|
||||
// errFileNameTooLong - given file name is too long than supported length.
|
||||
var errFileNameTooLong = errors.New("file name too long")
|
||||
|
||||
// errFileComponentInvalid - given file name has invalid components.
|
||||
var errFileComponentInvalid = errors.New("file name has invalid components")
|
||||
|
||||
// errVolumeExists - cannot create same volume again.
|
||||
var errVolumeExists = errors.New("volume already exists")
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ func StartTestServer(t TestErrHandler, instanceType string) TestServer {
|
||||
// The object Layer will be a temp back used for testing purpose.
|
||||
func initTestStorageRPCEndPoint(srvCmdConfig serverCmdConfig) http.Handler {
|
||||
// Initialize router.
|
||||
muxRouter := router.NewRouter()
|
||||
muxRouter := router.NewRouter().SkipClean(true)
|
||||
registerStorageRPCRouters(muxRouter, srvCmdConfig)
|
||||
return muxRouter
|
||||
}
|
||||
@@ -421,7 +421,8 @@ func StartTestPeersRPCServer(t TestErrHandler, instanceType string) TestServer {
|
||||
endpoints: endpoints,
|
||||
}
|
||||
|
||||
mux := router.NewRouter()
|
||||
mux := router.NewRouter().SkipClean(true)
|
||||
|
||||
// need storage layer for bucket config storage.
|
||||
registerStorageRPCRouters(mux, srvCfg)
|
||||
// need API layer to send requests, etc.
|
||||
@@ -2182,7 +2183,7 @@ func registerAPIFunctions(muxRouter *router.Router, objLayer ObjectLayer, apiFun
|
||||
func initTestAPIEndPoints(objLayer ObjectLayer, apiFunctions []string) http.Handler {
|
||||
// initialize a new mux router.
|
||||
// goriilla/mux is the library used to register all the routes and handle them.
|
||||
muxRouter := router.NewRouter()
|
||||
muxRouter := router.NewRouter().SkipClean(true)
|
||||
if len(apiFunctions) > 0 {
|
||||
// Iterate the list of API functions requested for and register them in mux HTTP handler.
|
||||
registerAPIFunctions(muxRouter, objLayer, apiFunctions...)
|
||||
@@ -2199,7 +2200,7 @@ func initTestWebRPCEndPoint(objLayer ObjectLayer) http.Handler {
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
// Initialize router.
|
||||
muxRouter := router.NewRouter()
|
||||
muxRouter := router.NewRouter().SkipClean(true)
|
||||
registerWebRouter(muxRouter)
|
||||
return muxRouter
|
||||
}
|
||||
@@ -2207,7 +2208,7 @@ func initTestWebRPCEndPoint(objLayer ObjectLayer) http.Handler {
|
||||
// Initialize browser RPC endpoint.
|
||||
func initTestBrowserPeerRPCEndPoint() http.Handler {
|
||||
// Initialize router.
|
||||
muxRouter := router.NewRouter()
|
||||
muxRouter := router.NewRouter().SkipClean(true)
|
||||
registerBrowserPeerRPCRouter(muxRouter)
|
||||
return muxRouter
|
||||
}
|
||||
@@ -2261,7 +2262,7 @@ func StartTestS3PeerRPCServer(t TestErrHandler) (TestServer, []string) {
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
// Register router on a new mux
|
||||
muxRouter := router.NewRouter()
|
||||
muxRouter := router.NewRouter().SkipClean(true)
|
||||
err = registerS3PeerRPCRouter(muxRouter)
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
%define tag RELEASE.2017-02-16T01-47-30Z
|
||||
%define tag RELEASE.2017-04-25T01-27-49Z
|
||||
%define subver %(echo %{tag} | sed -e 's/[^0-9]//g')
|
||||
# git fetch https://github.com/minio/minio.git refs/tags/RELEASE.2017-02-16T01-47-30Z
|
||||
# git fetch https://github.com/minio/minio.git refs/tags/RELEASE.2017-04-25T01-27-49Z
|
||||
# git rev-list -n 1 FETCH_HEAD
|
||||
%define commitid 3d98311d9f4ceb78dba996dcdc0751253241e697
|
||||
%define commitid 710db6bdadb1b228bf6dee7e2a6958000091125b
|
||||
Summary: Cloud Storage Server.
|
||||
Name: minio
|
||||
Version: 0.0.%{subver}
|
||||
@@ -19,7 +19,7 @@ BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
|
||||
%define debug_package %{nil}
|
||||
|
||||
## Go related tags.
|
||||
%define gobuild(o:) go build -ldflags "${LDFLAGS:-}" %{?**};
|
||||
%define gobuild(o:) go build -ldflags "-s -w ${LDFLAGS:-}" %{?**};
|
||||
%define gopath %{_libdir}/golang
|
||||
%define import_path github.com/minio/minio
|
||||
|
||||
|
||||
Reference in New Issue
Block a user