Clean up code
This commit is contained in:
parent
4e41814724
commit
53a807f38c
21 changed files with 95 additions and 113 deletions
6
Gopkg.lock
generated
6
Gopkg.lock
generated
|
@ -54,7 +54,7 @@
|
|||
branch = "master"
|
||||
name = "github.com/mitchellh/go-homedir"
|
||||
packages = ["."]
|
||||
revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
|
||||
revision = "3864e76763d94a6df2f9960b16a20a33da9f9a66"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
|
@ -88,7 +88,7 @@
|
|||
"blake2b",
|
||||
"ssh/terminal"
|
||||
]
|
||||
revision = "1a580b3eff7814fc9b40602fd35256c63b50f491"
|
||||
revision = "a3beeb748656e13e54256fd2cde19e058f41f60f"
|
||||
|
||||
[[projects]]
|
||||
branch = "release-branch.go1.10"
|
||||
|
@ -107,7 +107,7 @@
|
|||
"unix",
|
||||
"windows"
|
||||
]
|
||||
revision = "7f59abf37be6a6007f075af1bc7f16f137bc176b"
|
||||
revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
.PHONY: all lint test build-docker deploy-cf
|
||||
|
||||
all:
|
||||
go build ./cmd/...
|
||||
go build ./cmd/s3manager
|
||||
|
||||
lint:
|
||||
gometalinter --vendor ./...
|
||||
|
|
|
@ -8,8 +8,8 @@ A Web GUI written in Go to manage S3 buckets from any provider.
|
|||
|
||||
## Install Dependencies
|
||||
|
||||
1. Install [Dep](https://github.com/golang/dep)
|
||||
1. Run `dep ensure`
|
||||
1. Install [Dep](https://github.com/golang/dep)
|
||||
1. Run `dep ensure`
|
||||
|
||||
## Build and Run Locally
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:latest
|
||||
FROM golang:1
|
||||
|
||||
WORKDIR /go/src/github.com/mastertinner/s3manager
|
||||
COPY . .
|
||||
|
|
|
@ -69,12 +69,12 @@ func main() {
|
|||
Handler(s3manager.DeleteBucketHandler(s3))
|
||||
r.
|
||||
Methods(http.MethodPost).
|
||||
Headers(s3manager.HeaderContentType, s3manager.ContentTypeJSON).
|
||||
Headers("Content-Type", "application/json; charset=utf-8").
|
||||
Path("/api/buckets/{bucketName}/objects").
|
||||
Handler(s3manager.CopyObjectHandler(s3))
|
||||
r.
|
||||
Methods(http.MethodPost).
|
||||
HeadersRegexp(s3manager.HeaderContentType, s3manager.ContentTypeMultipartForm).
|
||||
HeadersRegexp("Content-Type", "multipart/form-data").
|
||||
Path("/api/buckets/{bucketName}/objects").
|
||||
Handler(s3manager.CreateObjectHandler(s3))
|
||||
r.
|
||||
|
|
|
@ -11,20 +11,18 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// objectWithIcon is a minio object with an added icon.
|
||||
type objectWithIcon struct {
|
||||
minio.ObjectInfo
|
||||
Icon string
|
||||
}
|
||||
|
||||
// bucketPage defines the details page of a bucket.
|
||||
type bucketPage struct {
|
||||
BucketName string
|
||||
Objects []objectWithIcon
|
||||
}
|
||||
|
||||
// BucketViewHandler shows the details page of a bucket.
|
||||
func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
||||
type objectWithIcon struct {
|
||||
minio.ObjectInfo
|
||||
Icon string
|
||||
}
|
||||
|
||||
type pageData struct {
|
||||
BucketName string
|
||||
Objects []objectWithIcon
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
bucketName := mux.Vars(r)["bucketName"]
|
||||
|
||||
|
@ -40,7 +38,7 @@ func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
|||
obj := objectWithIcon{object, icon(object.Key)}
|
||||
objs = append(objs, obj)
|
||||
}
|
||||
page := bucketPage{
|
||||
data := pageData{
|
||||
BucketName: bucketName,
|
||||
Objects: objs,
|
||||
}
|
||||
|
@ -49,12 +47,12 @@ func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
|||
p := filepath.Join(tmplDir, "bucket.html.tmpl")
|
||||
t, err := template.ParseFiles(l, p)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errParsingTemplates))
|
||||
handleHTTPError(w, errors.Wrap(err, "error parsing template files"))
|
||||
return
|
||||
}
|
||||
err = t.ExecuteTemplate(w, "layout", page)
|
||||
err = t.ExecuteTemplate(w, "layout", data)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errExecutingTemplate))
|
||||
handleHTTPError(w, errors.Wrap(err, "error executing template"))
|
||||
return
|
||||
}
|
||||
})
|
||||
|
@ -63,7 +61,6 @@ func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
|||
// icon returns an icon for a file type.
|
||||
func icon(fileName string) string {
|
||||
e := path.Ext(fileName)
|
||||
|
||||
switch e {
|
||||
case ".tgz", ".gz":
|
||||
return "archive"
|
||||
|
@ -72,6 +69,5 @@ func icon(fileName string) string {
|
|||
case ".mp3", ".wav":
|
||||
return "music_note"
|
||||
}
|
||||
|
||||
return "insert_drive_file"
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains string
|
||||
}{
|
||||
"renders a bucket containing a file": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
objCh <- minio.ObjectInfo{Key: "testFile"}
|
||||
|
@ -36,7 +36,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains: "testFile",
|
||||
},
|
||||
"renders placeholder for an empty bucket": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
close(objCh)
|
||||
return objCh
|
||||
|
@ -46,7 +46,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains: "No objects in",
|
||||
},
|
||||
"renders a bucket containing an archive": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
objCh <- minio.ObjectInfo{Key: "archive.tar.gz"}
|
||||
|
@ -59,7 +59,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains: "archive",
|
||||
},
|
||||
"renders a bucket containing an image": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
objCh <- minio.ObjectInfo{Key: "testImage.png"}
|
||||
|
@ -72,7 +72,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains: "photo",
|
||||
},
|
||||
"renders a bucket containing a sound file": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
objCh <- minio.ObjectInfo{Key: "testSound.mp3"}
|
||||
|
@ -85,7 +85,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains: "music_note",
|
||||
},
|
||||
"returns error if the bucket doesn't exist": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
objCh <- minio.ObjectInfo{Err: s3manager.ErrBucketDoesNotExist}
|
||||
|
@ -98,7 +98,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
expectedBodyContains: http.StatusText(http.StatusNotFound),
|
||||
},
|
||||
"returns error if there is an S3 error": {
|
||||
listObjectsV2Func: func(bucketName string, objectPrefix string, recursive bool, doneCh <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
listObjectsV2Func: func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo {
|
||||
objCh := make(chan minio.ObjectInfo)
|
||||
go func() {
|
||||
objCh <- minio.ObjectInfo{Err: errors.New("mocked S3 error")}
|
||||
|
@ -132,7 +132,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
|
||||
url := fmt.Sprintf("%s/buckets/%s", ts.URL, tc.bucketName)
|
||||
resp, err := http.Get(url)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
defer func() {
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
|
@ -141,10 +141,10 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode, tcID)
|
||||
assert.Contains(string(body), tc.expectedBodyContains, tcID)
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode)
|
||||
assert.Contains(string(body), tc.expectedBodyContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ func BucketsViewHandler(s3 S3, tmplDir string) http.Handler {
|
|||
p := filepath.Join(tmplDir, "buckets.html.tmpl")
|
||||
t, err := template.ParseFiles(l, p)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errParsingTemplates))
|
||||
handleHTTPError(w, errors.Wrap(err, "error parsing template files"))
|
||||
return
|
||||
}
|
||||
err = t.ExecuteTemplate(w, "layout", buckets)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errExecutingTemplate))
|
||||
handleHTTPError(w, errors.Wrap(err, "error executing template"))
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -58,7 +58,7 @@ func TestBucketsViewHandler(t *testing.T) {
|
|||
Handler(s3manager.BucketViewHandler(s3, tmplDir))
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "/buckets", nil)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := s3manager.BucketsViewHandler(s3, tmplDir)
|
||||
|
@ -66,8 +66,8 @@ func TestBucketsViewHandler(t *testing.T) {
|
|||
handler.ServeHTTP(rr, req)
|
||||
resp := rr.Result()
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode, tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,26 +9,26 @@ import (
|
|||
minio "github.com/minio/minio-go"
|
||||
)
|
||||
|
||||
// copyObjectInfo is the information about an object to copy.
|
||||
type copyObjectInfo struct {
|
||||
BucketName string `json:"bucketName"`
|
||||
ObjectName string `json:"objectName"`
|
||||
SourceBucketName string `json:"sourceBucketName"`
|
||||
SourceObjectName string `json:"sourceObjectName"`
|
||||
}
|
||||
|
||||
// CopyObjectHandler copies an existing object under a new name.
|
||||
func CopyObjectHandler(s3 S3) http.Handler {
|
||||
// request is the information about an object to copy.
|
||||
type request struct {
|
||||
BucketName string `json:"bucketName"`
|
||||
ObjectName string `json:"objectName"`
|
||||
SourceBucketName string `json:"sourceBucketName"`
|
||||
SourceObjectName string `json:"sourceObjectName"`
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var copy copyObjectInfo
|
||||
err := json.NewDecoder(r.Body).Decode(©)
|
||||
var req request
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errDecodingBody))
|
||||
handleHTTPError(w, errors.Wrap(err, "error decoding body JSON"))
|
||||
return
|
||||
}
|
||||
|
||||
src := minio.NewSourceInfo(copy.SourceBucketName, copy.SourceObjectName, nil)
|
||||
dst, err := minio.NewDestinationInfo(copy.BucketName, copy.ObjectName, nil, nil)
|
||||
src := minio.NewSourceInfo(req.SourceBucketName, req.SourceObjectName, nil)
|
||||
dst, err := minio.NewDestinationInfo(req.BucketName, req.ObjectName, nil, nil)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, "error creating destination for copying"))
|
||||
return
|
||||
|
@ -39,11 +39,11 @@ func CopyObjectHandler(s3 S3) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
w.Header().Set(HeaderContentType, ContentTypeJSON)
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
err = json.NewEncoder(w).Encode(copy)
|
||||
err = json.NewEncoder(w).Encode(req)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errEncodingJSON))
|
||||
handleHTTPError(w, errors.Wrap(err, "error encoding JSON"))
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -14,7 +14,7 @@ func CreateBucketHandler(s3 S3) http.Handler {
|
|||
var bucket minio.BucketInfo
|
||||
err := json.NewDecoder(r.Body).Decode(&bucket)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errDecodingBody))
|
||||
handleHTTPError(w, errors.Wrap(err, "error decoding body JSON"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,11 @@ func CreateBucketHandler(s3 S3) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
w.Header().Set(HeaderContentType, ContentTypeJSON)
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
err = json.NewEncoder(w).Encode(bucket)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errEncodingJSON))
|
||||
handleHTTPError(w, errors.Wrap(err, "error encoding JSON"))
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -19,15 +19,15 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
expectedBodyContains string
|
||||
}{
|
||||
"creates a new bucket": {
|
||||
makeBucketFunc: func(bucketName string, location string) error {
|
||||
makeBucketFunc: func(string, string) error {
|
||||
return nil
|
||||
},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
body: `{"name":"myBucket"}`,
|
||||
expectedStatusCode: http.StatusCreated,
|
||||
expectedBodyContains: "{\"name\":\"myBucket\",\"creationDate\":\"0001-01-01T00:00:00Z\"}\n",
|
||||
expectedBodyContains: `{"name":"myBucket","creationDate":"0001-01-01T00:00:00Z"}`,
|
||||
},
|
||||
"returns error for empty request": {
|
||||
makeBucketFunc: func(bucketName string, location string) error {
|
||||
makeBucketFunc: func(string, string) error {
|
||||
return nil
|
||||
},
|
||||
body: "",
|
||||
|
@ -35,7 +35,7 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
expectedBodyContains: http.StatusText(http.StatusUnprocessableEntity),
|
||||
},
|
||||
"returns error for malformed request": {
|
||||
makeBucketFunc: func(bucketName string, location string) error {
|
||||
makeBucketFunc: func(string, string) error {
|
||||
return nil
|
||||
},
|
||||
body: "}",
|
||||
|
@ -43,10 +43,10 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
expectedBodyContains: http.StatusText(http.StatusUnprocessableEntity),
|
||||
},
|
||||
"returns error if there is an S3 error": {
|
||||
makeBucketFunc: func(bucketName string, location string) error {
|
||||
makeBucketFunc: func(string, string) error {
|
||||
return errors.New("mocked S3 error")
|
||||
},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
body: `{"name":"myBucket"}`,
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyContains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
|
@ -61,7 +61,7 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, "/api/buckets", bytes.NewBufferString(tc.body))
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := s3manager.CreateBucketHandler(s3)
|
||||
|
@ -69,8 +69,8 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
handler.ServeHTTP(rr, req)
|
||||
resp := rr.Result()
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode, tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ func CreateObjectHandler(s3 S3) http.Handler {
|
|||
bucketName := mux.Vars(r)["bucketName"]
|
||||
err := r.ParseMultipartForm(32 << 20)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, errParsingForm))
|
||||
handleHTTPError(w, errors.Wrap(err, "error parsing multipart form"))
|
||||
return
|
||||
}
|
||||
file, handler, err := r.FormFile("file")
|
||||
|
@ -30,7 +30,7 @@ func CreateObjectHandler(s3 S3) http.Handler {
|
|||
}
|
||||
}()
|
||||
|
||||
_, err = s3.PutObject(bucketName, handler.Filename, file, 1, minio.PutObjectOptions{ContentType: contentTypeOctetStream})
|
||||
_, err = s3.PutObject(bucketName, handler.Filename, file, 1, minio.PutObjectOptions{ContentType: "application/octet-stream"})
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, "error putting object"))
|
||||
return
|
||||
|
|
|
@ -17,14 +17,14 @@ func TestDeleteBucketHandler(t *testing.T) {
|
|||
expectedBodyContains string
|
||||
}{
|
||||
"deletes an existing bucket": {
|
||||
removeBucketFunc: func(bucketName string) error {
|
||||
removeBucketFunc: func(string) error {
|
||||
return nil
|
||||
},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBodyContains: "",
|
||||
},
|
||||
"returns error if there is an S3 error": {
|
||||
removeBucketFunc: func(bucketName string) error {
|
||||
removeBucketFunc: func(string) error {
|
||||
return errors.New("mocked S3 error")
|
||||
},
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
|
@ -41,7 +41,7 @@ func TestDeleteBucketHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodDelete, "/api/buckets/bucketName", nil)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := s3manager.DeleteBucketHandler(s3)
|
||||
|
@ -49,8 +49,8 @@ func TestDeleteBucketHandler(t *testing.T) {
|
|||
handler.ServeHTTP(rr, req)
|
||||
resp := rr.Result()
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode, tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@ func TestDeleteObjectHandler(t *testing.T) {
|
|||
expectedBodyContains string
|
||||
}{
|
||||
"deletes an existing object": {
|
||||
removeObjectFunc: func(bucketName string, objectName string) error {
|
||||
removeObjectFunc: func(string, string) error {
|
||||
return nil
|
||||
},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBodyContains: "",
|
||||
},
|
||||
"returns error if there is an S3 error": {
|
||||
removeObjectFunc: func(bucketName string, objectName string) error {
|
||||
removeObjectFunc: func(string, string) error {
|
||||
return errors.New("mocked S3 error")
|
||||
},
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
|
@ -41,15 +41,15 @@ func TestDeleteObjectHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodDelete, "/api/buckets/bucketName/objects/objectName", nil)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
handler := s3manager.DeleteObjectHandler(s3)
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code, tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,15 +9,6 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Error codes commonly used throughout the application
|
||||
const (
|
||||
errDecodingBody = "error decoding body JSON"
|
||||
errEncodingJSON = "error encoding JSON"
|
||||
errExecutingTemplate = "error executing template"
|
||||
errParsingForm = "error parsing form"
|
||||
errParsingTemplates = "error parsing template files"
|
||||
)
|
||||
|
||||
// Errors that may be returned from an S3 client.
|
||||
var (
|
||||
ErrBucketDoesNotExist = errors.New("The specified bucket does not exist.") // nolint: golint
|
||||
|
|
|
@ -23,8 +23,8 @@ func GetObjectHandler(s3 S3) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
w.Header().Set(headerContentDisposition, fmt.Sprintf("attachment; filename=\"%s\"", objectName))
|
||||
w.Header().Set(HeaderContentType, contentTypeOctetStream)
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", objectName))
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
_, err = io.Copy(w, object)
|
||||
if err != nil {
|
||||
handleHTTPError(w, errors.Wrap(err, "error copying object to response writer"))
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestGetObjectHandler(t *testing.T) {
|
|||
expectedBodyContains string
|
||||
}{
|
||||
"returns error if there is an S3 error": {
|
||||
getObjectFunc: func(bucketName string, objectName string, opts minio.GetObjectOptions) (*minio.Object, error) {
|
||||
getObjectFunc: func(string, string, minio.GetObjectOptions) (*minio.Object, error) {
|
||||
return nil, errors.New("mocked S3 error")
|
||||
},
|
||||
bucketName: "testBucket",
|
||||
|
@ -52,7 +52,7 @@ func TestGetObjectHandler(t *testing.T) {
|
|||
|
||||
url := fmt.Sprintf("%s/buckets/%s/objects/%s", ts.URL, tc.bucketName, tc.objectName)
|
||||
resp, err := http.Get(url)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
defer func() {
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
|
@ -61,10 +61,10 @@ func TestGetObjectHandler(t *testing.T) {
|
|||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
assert.NoError(err, tcID)
|
||||
assert.NoError(err)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode, tcID)
|
||||
assert.Contains(string(body), tc.expectedBodyContains, tcID)
|
||||
assert.Equal(tc.expectedStatusCode, resp.StatusCode)
|
||||
assert.Contains(string(body), tc.expectedBodyContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,2 @@
|
|||
// Package s3manager allows to interact with an S3 compatible storage.
|
||||
package s3manager
|
||||
|
||||
// These are constants commonly used throughout the application.
|
||||
const (
|
||||
HeaderContentType = "Content-Type"
|
||||
ContentTypeJSON = "application/json"
|
||||
ContentTypeMultipartForm = "multipart/form-data"
|
||||
headerContentDisposition = "Content-Disposition"
|
||||
contentTypeOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
|
|
@ -83,7 +83,7 @@ function createBucket() {
|
|||
url: '/api/buckets',
|
||||
data: JSON.stringify(formData),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
success: function() { location.reload(); }
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,15 +10,19 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css"><Paste>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{ template "content" . }}
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.3.1.min.js"
|
||||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('.modal').modal();
|
||||
|
|
Loading…
Reference in a new issue