mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
web: PresignedGet/Put targetHost should always have a valid value.
PresignedURLs should always be generated for the targetHost, so that we can avoid signature issues.
This commit is contained in:
parent
1c33926239
commit
d4c91426a7
13
Docker.md
13
Docker.md
@ -35,12 +35,15 @@ docker run -p 9000 --volumes-from minio-export --name minio1 minio/my-minio
|
|||||||
|
|
||||||
Please download [Caddy Server](https://caddyserver.com/download)
|
Please download [Caddy Server](https://caddyserver.com/download)
|
||||||
|
|
||||||
Create a caddy configuration file as below, change the ip addresses for your environment.
|
Create a caddy configuration file as below, change the ip addresses according to your local
|
||||||
|
minio and DNS configuration.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat Caddyfile
|
your.public.com {
|
||||||
10.0.0.3:2015 {
|
proxy / 10.0.1.3:9000 {
|
||||||
proxy / localhost:9000 {
|
|
||||||
proxy_header Host {host}
|
proxy_header Host {host}
|
||||||
|
proxy_header X-Real-IP {remote}
|
||||||
|
proxy_header X-Forwarded-Proto {scheme}
|
||||||
}
|
}
|
||||||
tls off
|
tls off
|
||||||
}
|
}
|
||||||
@ -49,5 +52,5 @@ cat Caddyfile
|
|||||||
```bash
|
```bash
|
||||||
$ ./caddy
|
$ ./caddy
|
||||||
Activating privacy features... done.
|
Activating privacy features... done.
|
||||||
10.0.0.3:2015
|
your.public.com
|
||||||
```
|
```
|
||||||
|
@ -15,130 +15,3 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/minio/minio/pkg/disk"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MakeBucketArgs - make bucket args.
|
|
||||||
type MakeBucketArgs struct {
|
|
||||||
BucketName string `json:"bucketName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DiskInfoArgs - disk info args.
|
|
||||||
type DiskInfoArgs struct{}
|
|
||||||
|
|
||||||
// ServerInfoArgs - server info args.
|
|
||||||
type ServerInfoArgs struct{}
|
|
||||||
|
|
||||||
// ListBucketsArgs - list bucket args.
|
|
||||||
type ListBucketsArgs struct{}
|
|
||||||
|
|
||||||
// GenericArgs - empty struct
|
|
||||||
type GenericArgs struct{}
|
|
||||||
|
|
||||||
// DiskInfoRep - disk info reply.
|
|
||||||
type DiskInfoRep struct {
|
|
||||||
DiskInfo disk.Info `json:"diskInfo"`
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListBucketsRep - list buckets response
|
|
||||||
type ListBucketsRep struct {
|
|
||||||
Buckets []BucketInfo `json:"buckets"`
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListObjectsArgs - list object args.
|
|
||||||
type ListObjectsArgs struct {
|
|
||||||
BucketName string `json:"bucketName"`
|
|
||||||
Prefix string `json:"prefix"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListObjectsRep - list objects response.
|
|
||||||
type ListObjectsRep struct {
|
|
||||||
Objects []ObjectInfo `json:"objects"`
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutObjectURLArgs - args to generate url for upload access.
|
|
||||||
type PutObjectURLArgs struct {
|
|
||||||
TargetHost string `json:"targetHost"`
|
|
||||||
BucketName string `json:"bucketName"`
|
|
||||||
ObjectName string `json:"objectName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutObjectURLRep - reply for presigned upload url request.
|
|
||||||
type PutObjectURLRep struct {
|
|
||||||
URL string `json:"url"`
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetObjectURLArgs - args to generate url for download access.
|
|
||||||
type GetObjectURLArgs struct {
|
|
||||||
TargetHost string `json:"targetHost"`
|
|
||||||
BucketName string `json:"bucketName"`
|
|
||||||
ObjectName string `json:"objectName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetObjectURLRep - reply for presigned download url request.
|
|
||||||
type GetObjectURLRep struct {
|
|
||||||
URL string `json:"url"`
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveObjectArgs - args to remove an object
|
|
||||||
type RemoveObjectArgs struct {
|
|
||||||
TargetHost string `json:"targetHost"`
|
|
||||||
BucketName string `json:"bucketName"`
|
|
||||||
ObjectName string `json:"objectName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenericRep - reply structure for calls for which reply is success/failure
|
|
||||||
// for ex. RemoveObject MakeBucket
|
|
||||||
type GenericRep struct {
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// BucketInfo container for list buckets metadata.
|
|
||||||
type BucketInfo struct {
|
|
||||||
// The name of the bucket.
|
|
||||||
Name string `json:"name"`
|
|
||||||
// Date the bucket was created.
|
|
||||||
CreationDate time.Time `json:"creationDate"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ObjectInfo container for list objects metadata.
|
|
||||||
type ObjectInfo struct {
|
|
||||||
// Name of the object
|
|
||||||
Key string `json:"name"`
|
|
||||||
// Date and time the object was last modified.
|
|
||||||
LastModified time.Time `json:"lastModified"`
|
|
||||||
// Size in bytes of the object.
|
|
||||||
Size int64 `json:"size"`
|
|
||||||
// ContentType is mime type of the object.
|
|
||||||
ContentType string `json:"contentType"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoginArgs - login arguments.
|
|
||||||
type LoginArgs struct {
|
|
||||||
Username string `json:"username" form:"username"`
|
|
||||||
Password string `json:"password" form:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoginRep - login reply.
|
|
||||||
type LoginRep struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServerInfoRep - server info reply.
|
|
||||||
type ServerInfoRep struct {
|
|
||||||
MinioVersion string
|
|
||||||
MinioMemory string
|
|
||||||
MinioPlatform string
|
|
||||||
MinioRuntime string
|
|
||||||
UIVersion string `json:"uiVersion"`
|
|
||||||
}
|
|
||||||
|
147
web-handlers.go
147
web-handlers.go
@ -18,7 +18,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -33,7 +32,6 @@ import (
|
|||||||
"github.com/gorilla/rpc/v2/json2"
|
"github.com/gorilla/rpc/v2/json2"
|
||||||
"github.com/minio/minio-go"
|
"github.com/minio/minio-go"
|
||||||
"github.com/minio/minio/pkg/disk"
|
"github.com/minio/minio/pkg/disk"
|
||||||
"github.com/minio/minio/pkg/probe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// isJWTReqAuthenticated validates if any incoming request to be a
|
// isJWTReqAuthenticated validates if any incoming request to be a
|
||||||
@ -52,12 +50,33 @@ func isJWTReqAuthenticated(req *http.Request) bool {
|
|||||||
return token.Valid
|
return token.Valid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenericRep - reply structure for calls for which reply is success/failure
|
||||||
|
// for ex. RemoveObject MakeBucket
|
||||||
|
type GenericRep struct {
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenericArgs - empty struct
|
||||||
|
type GenericArgs struct{}
|
||||||
|
|
||||||
// GetUIVersion - get UI version
|
// GetUIVersion - get UI version
|
||||||
func (web webAPI) GetUIVersion(r *http.Request, args *GenericArgs, reply *GenericRep) error {
|
func (web webAPI) GetUIVersion(r *http.Request, args *GenericArgs, reply *GenericRep) error {
|
||||||
reply.UIVersion = uiVersion
|
reply.UIVersion = uiVersion
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServerInfoRep - server info reply.
|
||||||
|
type ServerInfoRep struct {
|
||||||
|
MinioVersion string
|
||||||
|
MinioMemory string
|
||||||
|
MinioPlatform string
|
||||||
|
MinioRuntime string
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerInfoArgs - server info args.
|
||||||
|
type ServerInfoArgs struct{}
|
||||||
|
|
||||||
// ServerInfo - get server info.
|
// ServerInfo - get server info.
|
||||||
func (web *webAPI) ServerInfo(r *http.Request, args *ServerInfoArgs, reply *ServerInfoRep) error {
|
func (web *webAPI) ServerInfo(r *http.Request, args *ServerInfoArgs, reply *ServerInfoRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -87,6 +106,15 @@ func (web *webAPI) ServerInfo(r *http.Request, args *ServerInfoArgs, reply *Serv
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiskInfoArgs - disk info args.
|
||||||
|
type DiskInfoArgs struct{}
|
||||||
|
|
||||||
|
// DiskInfoRep - disk info reply.
|
||||||
|
type DiskInfoRep struct {
|
||||||
|
DiskInfo disk.Info `json:"diskInfo"`
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
// DiskInfo - get disk statistics.
|
// DiskInfo - get disk statistics.
|
||||||
func (web *webAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *DiskInfoRep) error {
|
func (web *webAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *DiskInfoRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -101,6 +129,11 @@ func (web *webAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *DiskInfo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeBucketArgs - make bucket args.
|
||||||
|
type MakeBucketArgs struct {
|
||||||
|
BucketName string `json:"bucketName"`
|
||||||
|
}
|
||||||
|
|
||||||
// MakeBucket - make a bucket.
|
// MakeBucket - make a bucket.
|
||||||
func (web *webAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *GenericRep) error {
|
func (web *webAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *GenericRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -114,6 +147,23 @@ func (web *webAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *Gene
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListBucketsArgs - list bucket args.
|
||||||
|
type ListBucketsArgs struct{}
|
||||||
|
|
||||||
|
// ListBucketsRep - list buckets response
|
||||||
|
type ListBucketsRep struct {
|
||||||
|
Buckets []BucketInfo `json:"buckets"`
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BucketInfo container for list buckets metadata.
|
||||||
|
type BucketInfo struct {
|
||||||
|
// The name of the bucket.
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Date the bucket was created.
|
||||||
|
CreationDate time.Time `json:"creationDate"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListBuckets - list buckets api.
|
// ListBuckets - list buckets api.
|
||||||
func (web *webAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *ListBucketsRep) error {
|
func (web *webAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *ListBucketsRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -133,6 +183,30 @@ func (web *webAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *Li
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListObjectsArgs - list object args.
|
||||||
|
type ListObjectsArgs struct {
|
||||||
|
BucketName string `json:"bucketName"`
|
||||||
|
Prefix string `json:"prefix"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListObjectsRep - list objects response.
|
||||||
|
type ListObjectsRep struct {
|
||||||
|
Objects []ObjectInfo `json:"objects"`
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectInfo container for list objects metadata.
|
||||||
|
type ObjectInfo struct {
|
||||||
|
// Name of the object
|
||||||
|
Key string `json:"name"`
|
||||||
|
// Date and time the object was last modified.
|
||||||
|
LastModified time.Time `json:"lastModified"`
|
||||||
|
// Size in bytes of the object.
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
// ContentType is mime type of the object.
|
||||||
|
ContentType string `json:"contentType"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListObjects - list objects api.
|
// ListObjects - list objects api.
|
||||||
func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error {
|
func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -166,19 +240,17 @@ func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *Li
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTargetHost(apiAddress, targetHost string) (string, *probe.Error) {
|
// PutObjectURLArgs - args to generate url for upload access.
|
||||||
if targetHost != "" {
|
type PutObjectURLArgs struct {
|
||||||
_, port, e := net.SplitHostPort(apiAddress)
|
TargetHost string `json:"targetHost"`
|
||||||
if e != nil {
|
BucketName string `json:"bucketName"`
|
||||||
return "", probe.NewError(e)
|
ObjectName string `json:"objectName"`
|
||||||
}
|
}
|
||||||
host, _, e := net.SplitHostPort(targetHost)
|
|
||||||
if e != nil {
|
// PutObjectURLRep - reply for presigned upload url request.
|
||||||
return "", probe.NewError(e)
|
type PutObjectURLRep struct {
|
||||||
}
|
URL string `json:"url"`
|
||||||
targetHost = net.JoinHostPort(host, port)
|
UIVersion string `json:"uiVersion"`
|
||||||
}
|
|
||||||
return targetHost, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutObjectURL - generates url for upload access.
|
// PutObjectURL - generates url for upload access.
|
||||||
@ -186,11 +258,7 @@ func (web *webAPI) PutObjectURL(r *http.Request, args *PutObjectURLArgs, reply *
|
|||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
return &json2.Error{Message: "Unauthorized request"}
|
return &json2.Error{Message: "Unauthorized request"}
|
||||||
}
|
}
|
||||||
targetHost, err := getTargetHost(web.apiAddress, args.TargetHost)
|
client, e := minio.New(args.TargetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
|
||||||
if err != nil {
|
|
||||||
return &json2.Error{Message: err.Cause.Error(), Data: err.String()}
|
|
||||||
}
|
|
||||||
client, e := minio.NewV4(targetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
|
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return &json2.Error{Message: e.Error()}
|
return &json2.Error{Message: e.Error()}
|
||||||
}
|
}
|
||||||
@ -203,6 +271,19 @@ func (web *webAPI) PutObjectURL(r *http.Request, args *PutObjectURLArgs, reply *
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetObjectURLArgs - args to generate url for download access.
|
||||||
|
type GetObjectURLArgs struct {
|
||||||
|
TargetHost string `json:"targetHost"`
|
||||||
|
BucketName string `json:"bucketName"`
|
||||||
|
ObjectName string `json:"objectName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectURLRep - reply for presigned download url request.
|
||||||
|
type GetObjectURLRep struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetObjectURL - generates url for download access.
|
// GetObjectURL - generates url for download access.
|
||||||
func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *GetObjectURLRep) error {
|
func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *GetObjectURLRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -215,14 +296,11 @@ func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *
|
|||||||
return &json2.Error{Message: e.Error()}
|
return &json2.Error{Message: e.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
targetHost, err := getTargetHost(web.apiAddress, args.TargetHost)
|
client, e := minio.New(args.TargetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
|
||||||
if err != nil {
|
|
||||||
return &json2.Error{Message: err.Cause.Error(), Data: err.String()}
|
|
||||||
}
|
|
||||||
client, e := minio.NewV4(targetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
|
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return &json2.Error{Message: e.Error()}
|
return &json2.Error{Message: e.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
reqParams := make(url.Values)
|
reqParams := make(url.Values)
|
||||||
// Set content disposition for browser to download the file.
|
// Set content disposition for browser to download the file.
|
||||||
reqParams.Set("response-content-disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(args.ObjectName)))
|
reqParams.Set("response-content-disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(args.ObjectName)))
|
||||||
@ -235,6 +313,13 @@ func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveObjectArgs - args to remove an object
|
||||||
|
type RemoveObjectArgs struct {
|
||||||
|
TargetHost string `json:"targetHost"`
|
||||||
|
BucketName string `json:"bucketName"`
|
||||||
|
ObjectName string `json:"objectName"`
|
||||||
|
}
|
||||||
|
|
||||||
// RemoveObject - removes an object.
|
// RemoveObject - removes an object.
|
||||||
func (web *webAPI) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *GenericRep) error {
|
func (web *webAPI) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *GenericRep) error {
|
||||||
if !isJWTReqAuthenticated(r) {
|
if !isJWTReqAuthenticated(r) {
|
||||||
@ -248,6 +333,18 @@ func (web *webAPI) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoginArgs - login arguments.
|
||||||
|
type LoginArgs struct {
|
||||||
|
Username string `json:"username" form:"username"`
|
||||||
|
Password string `json:"password" form:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoginRep - login reply.
|
||||||
|
type LoginRep struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
UIVersion string `json:"uiVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
// Login - user login handler.
|
// Login - user login handler.
|
||||||
func (web *webAPI) Login(r *http.Request, args *LoginArgs, reply *LoginRep) error {
|
func (web *webAPI) Login(r *http.Request, args *LoginArgs, reply *LoginRep) error {
|
||||||
jwt := initJWT()
|
jwt := initJWT()
|
||||||
|
Loading…
Reference in New Issue
Block a user