Add deploymentID to web handler logs (#7712)

This commit is contained in:
Krishnan Parthasarathi 2019-06-03 15:40:04 -07:00 committed by kannappanr
parent 0cfd5a21ba
commit 74efbb4153
2 changed files with 183 additions and 140 deletions

View File

@ -74,6 +74,11 @@ func (c *Target) Send(e interface{}) error {
apiString += ")" apiString += ")"
timeString := "Time: " + time.Now().Format(logger.TimeFormat) timeString := "Time: " + time.Now().Format(logger.TimeFormat)
var deploymentID string
if entry.DeploymentID != "" {
deploymentID = "\nDeploymentID: " + entry.DeploymentID
}
var requestID string var requestID string
if entry.RequestID != "" { if entry.RequestID != "" {
requestID = "\nRequestID: " + entry.RequestID requestID = "\nRequestID: " + entry.RequestID
@ -94,8 +99,8 @@ func (c *Target) Send(e interface{}) error {
} }
var msg = logger.ColorFgRed(logger.ColorBold(entry.Trace.Message)) var msg = logger.ColorFgRed(logger.ColorBold(entry.Trace.Message))
var output = fmt.Sprintf("\n%s\n%s%s%s%s\nError: %s%s\n%s", var output = fmt.Sprintf("\n%s\n%s%s%s%s%s\nError: %s%s\n%s",
apiString, timeString, requestID, remoteHost, userAgent, apiString, timeString, deploymentID, requestID, remoteHost, userAgent,
msg, tagString, strings.Join(trace, "\n")) msg, tagString, strings.Join(trace, "\n"))
fmt.Println(output) fmt.Println(output)

View File

@ -73,11 +73,34 @@ type ServerInfoRep struct {
UIVersion string `json:"uiVersion"` UIVersion string `json:"uiVersion"`
} }
// newWebContext creates a context with ReqInfo values from the given
// http request and api name.
func newWebContext(r *http.Request, api string) context.Context {
vars := mux.Vars(r)
bucket := vars["bucket"]
object := vars["object"]
prefix := vars["prefix"]
if prefix != "" {
object = prefix
}
reqInfo := &logger.ReqInfo{
DeploymentID: globalDeploymentID,
RemoteHost: handlers.GetSourceIP(r),
UserAgent: r.UserAgent(),
API: api,
BucketName: bucket,
ObjectName: object,
}
return logger.SetReqInfo(context.Background(), reqInfo)
}
// ServerInfo - get server info. // ServerInfo - get server info.
func (web *webAPIHandlers) ServerInfo(r *http.Request, args *WebGenericArgs, reply *ServerInfoRep) error { func (web *webAPIHandlers) ServerInfo(r *http.Request, args *WebGenericArgs, reply *ServerInfoRep) error {
ctx := newWebContext(r, "webServerInfo")
_, owner, authErr := webRequestAuthenticate(r) _, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
host, err := os.Hostname() host, err := os.Hostname()
if err != nil { if err != nil {
@ -124,15 +147,16 @@ type StorageInfoRep struct {
// StorageInfo - web call to gather storage usage statistics. // StorageInfo - web call to gather storage usage statistics.
func (web *webAPIHandlers) StorageInfo(r *http.Request, args *WebGenericArgs, reply *StorageInfoRep) error { func (web *webAPIHandlers) StorageInfo(r *http.Request, args *WebGenericArgs, reply *StorageInfoRep) error {
ctx := newWebContext(r, "webStorageInfo")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
_, _, authErr := webRequestAuthenticate(r) _, _, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
reply.StorageInfo = objectAPI.StorageInfo(context.Background()) reply.StorageInfo = objectAPI.StorageInfo(ctx)
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
return nil return nil
} }
@ -144,13 +168,14 @@ type MakeBucketArgs struct {
// MakeBucket - creates a new bucket. // MakeBucket - creates a new bucket.
func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *WebGenericRep) error { func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *WebGenericRep) error {
ctx := newWebContext(r, "webMakeBucket")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
// For authenticated users apply IAM policy. // For authenticated users apply IAM policy.
@ -161,36 +186,36 @@ func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, rep
ConditionValues: getConditionValues(r, "", claims.Subject), ConditionValues: getConditionValues(r, "", claims.Subject),
IsOwner: owner, IsOwner: owner,
}) { }) {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, true) { if isReservedOrInvalidBucket(args.BucketName, true) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
if globalDNSConfig != nil { if globalDNSConfig != nil {
if _, err := globalDNSConfig.Get(args.BucketName); err != nil { if _, err := globalDNSConfig.Get(args.BucketName); err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
// Proceed to creating a bucket. // Proceed to creating a bucket.
if err = objectAPI.MakeBucketWithLocation(context.Background(), args.BucketName, globalServerConfig.GetRegion()); err != nil { if err = objectAPI.MakeBucketWithLocation(ctx, args.BucketName, globalServerConfig.GetRegion()); err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
if err = globalDNSConfig.Put(args.BucketName); err != nil { if err = globalDNSConfig.Put(args.BucketName); err != nil {
objectAPI.DeleteBucket(context.Background(), args.BucketName) objectAPI.DeleteBucket(ctx, args.BucketName)
return toJSONError(err) return toJSONError(ctx, err)
} }
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
return nil return nil
} }
return toJSONError(err) return toJSONError(ctx, err)
} }
return toJSONError(errBucketAlreadyExists) return toJSONError(ctx, errBucketAlreadyExists)
} }
if err := objectAPI.MakeBucketWithLocation(context.Background(), args.BucketName, globalServerConfig.GetRegion()); err != nil { if err := objectAPI.MakeBucketWithLocation(ctx, args.BucketName, globalServerConfig.GetRegion()); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
@ -204,13 +229,14 @@ type RemoveBucketArgs struct {
// DeleteBucket - removes a bucket, must be empty. // DeleteBucket - removes a bucket, must be empty.
func (web *webAPIHandlers) DeleteBucket(r *http.Request, args *RemoveBucketArgs, reply *WebGenericRep) error { func (web *webAPIHandlers) DeleteBucket(r *http.Request, args *RemoveBucketArgs, reply *WebGenericRep) error {
ctx := newWebContext(r, "webDeleteBucket")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
// For authenticated users apply IAM policy. // For authenticated users apply IAM policy.
@ -221,45 +247,43 @@ func (web *webAPIHandlers) DeleteBucket(r *http.Request, args *RemoveBucketArgs,
ConditionValues: getConditionValues(r, "", claims.Subject), ConditionValues: getConditionValues(r, "", claims.Subject),
IsOwner: owner, IsOwner: owner,
}) { }) {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
if isRemoteCallRequired(context.Background(), args.BucketName, objectAPI) { if isRemoteCallRequired(ctx, args.BucketName, objectAPI) {
sr, err := globalDNSConfig.Get(args.BucketName) sr, err := globalDNSConfig.Get(args.BucketName)
if err != nil { if err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
return toJSONError(BucketNotFound{ return toJSONError(ctx, BucketNotFound{
Bucket: args.BucketName, Bucket: args.BucketName,
}, args.BucketName) }, args.BucketName)
} }
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
core, err := getRemoteInstanceClient(r, getHostFromSrv(sr)) core, err := getRemoteInstanceClient(r, getHostFromSrv(sr))
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
if err = core.RemoveBucket(args.BucketName); err != nil { if err = core.RemoveBucket(args.BucketName); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
return nil return nil
} }
ctx := context.Background()
deleteBucket := objectAPI.DeleteBucket deleteBucket := objectAPI.DeleteBucket
if web.CacheAPI() != nil { if web.CacheAPI() != nil {
deleteBucket = web.CacheAPI().DeleteBucket deleteBucket = web.CacheAPI().DeleteBucket
} }
if err := deleteBucket(ctx, args.BucketName); err != nil { if err := deleteBucket(ctx, args.BucketName); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
globalNotificationSys.RemoveNotification(args.BucketName) globalNotificationSys.RemoveNotification(args.BucketName)
@ -270,7 +294,7 @@ func (web *webAPIHandlers) DeleteBucket(r *http.Request, args *RemoveBucketArgs,
if err := globalDNSConfig.Delete(args.BucketName); err != nil { if err := globalDNSConfig.Delete(args.BucketName); err != nil {
// Deleting DNS entry failed, attempt to create the bucket again. // Deleting DNS entry failed, attempt to create the bucket again.
objectAPI.MakeBucketWithLocation(ctx, args.BucketName, "") objectAPI.MakeBucketWithLocation(ctx, args.BucketName, "")
return toJSONError(err) return toJSONError(ctx, err)
} }
} }
@ -293,9 +317,10 @@ type WebBucketInfo struct {
// ListBuckets - list buckets api. // ListBuckets - list buckets api.
func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, reply *ListBucketsRep) error { func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, reply *ListBucketsRep) error {
ctx := newWebContext(r, "webListBuckets")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
listBuckets := objectAPI.ListBuckets listBuckets := objectAPI.ListBuckets
if web.CacheAPI() != nil { if web.CacheAPI() != nil {
@ -304,7 +329,7 @@ func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, re
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
// Set prefix value for "s3:prefix" policy conditionals. // Set prefix value for "s3:prefix" policy conditionals.
@ -317,7 +342,7 @@ func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, re
if globalDNSConfig != nil { if globalDNSConfig != nil {
dnsBuckets, err := globalDNSConfig.List() dnsBuckets, err := globalDNSConfig.List()
if err != nil && err != dns.ErrNoEntriesFound { if err != nil && err != dns.ErrNoEntriesFound {
return toJSONError(err) return toJSONError(ctx, err)
} }
bucketSet := set.NewStringSet() bucketSet := set.NewStringSet()
for _, dnsRecord := range dnsBuckets { for _, dnsRecord := range dnsBuckets {
@ -342,9 +367,9 @@ func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, re
} }
} }
} else { } else {
buckets, err := listBuckets(context.Background()) buckets, err := listBuckets(ctx)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
for _, bucket := range buckets { for _, bucket := range buckets {
if globalIAMSys.IsAllowed(iampolicy.Args{ if globalIAMSys.IsAllowed(iampolicy.Args{
@ -397,10 +422,11 @@ type WebObjectInfo struct {
// ListObjects - list objects api. // ListObjects - list objects api.
func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error { func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error {
ctx := newWebContext(r, "webListObjects")
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
listObjects := objectAPI.ListObjects listObjects := objectAPI.ListObjects
@ -408,23 +434,23 @@ func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, r
listObjects = web.CacheAPI().ListObjects listObjects = web.CacheAPI().ListObjects
} }
if isRemoteCallRequired(context.Background(), args.BucketName, objectAPI) { if isRemoteCallRequired(ctx, args.BucketName, objectAPI) {
sr, err := globalDNSConfig.Get(args.BucketName) sr, err := globalDNSConfig.Get(args.BucketName)
if err != nil { if err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
return toJSONError(BucketNotFound{ return toJSONError(ctx, BucketNotFound{
Bucket: args.BucketName, Bucket: args.BucketName,
}, args.BucketName) }, args.BucketName)
} }
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
core, err := getRemoteInstanceClient(r, getHostFromSrv(sr)) core, err := getRemoteInstanceClient(r, getHostFromSrv(sr))
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
result, err := core.ListObjects(args.BucketName, args.Prefix, args.Marker, slashSeparator, 1000) result, err := core.ListObjects(args.BucketName, args.Prefix, args.Marker, slashSeparator, 1000)
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
reply.NextMarker = result.NextMarker reply.NextMarker = result.NextMarker
reply.IsTruncated = result.IsTruncated reply.IsTruncated = result.IsTruncated
@ -480,7 +506,7 @@ func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, r
return nil return nil
} }
} else { } else {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
} }
@ -522,10 +548,10 @@ func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, r
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
lo, err := listObjects(context.Background(), args.BucketName, args.Prefix, args.Marker, slashSeparator, 1000) lo, err := listObjects(ctx, args.BucketName, args.Prefix, args.Marker, slashSeparator, 1000)
if err != nil { if err != nil {
return &json2.Error{Message: err.Error()} return &json2.Error{Message: err.Error()}
} }
@ -533,7 +559,7 @@ func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, r
if crypto.IsEncrypted(lo.Objects[i].UserDefined) { if crypto.IsEncrypted(lo.Objects[i].UserDefined) {
lo.Objects[i].Size, err = lo.Objects[i].DecryptedSize() lo.Objects[i].Size, err = lo.Objects[i].DecryptedSize()
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
} }
} }
@ -573,9 +599,10 @@ type RemoveObjectArgs struct {
// RemoveObject - removes an object, or all the objects at a given prefix. // RemoveObject - removes an object, or all the objects at a given prefix.
func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *WebGenericRep) error { func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *WebGenericRep) error {
ctx := newWebContext(r, "webRemoveObject")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
listObjects := objectAPI.ListObjects listObjects := objectAPI.ListObjects
if web.CacheAPI() != nil { if web.CacheAPI() != nil {
@ -594,37 +621,37 @@ func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs,
IsOwner: false, IsOwner: false,
ObjectName: object, ObjectName: object,
}) { }) {
return toJSONError(errAuthentication) return toJSONError(ctx, errAuthentication)
} }
} }
} else { } else {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
} }
if args.BucketName == "" || len(args.Objects) == 0 { if args.BucketName == "" || len(args.Objects) == 0 {
return toJSONError(errInvalidArgument) return toJSONError(ctx, errInvalidArgument)
} }
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
if isRemoteCallRequired(context.Background(), args.BucketName, objectAPI) { if isRemoteCallRequired(ctx, args.BucketName, objectAPI) {
sr, err := globalDNSConfig.Get(args.BucketName) sr, err := globalDNSConfig.Get(args.BucketName)
if err != nil { if err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
return toJSONError(BucketNotFound{ return toJSONError(ctx, BucketNotFound{
Bucket: args.BucketName, Bucket: args.BucketName,
}, args.BucketName) }, args.BucketName)
} }
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
core, err := getRemoteInstanceClient(r, getHostFromSrv(sr)) core, err := getRemoteInstanceClient(r, getHostFromSrv(sr))
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
objectsCh := make(chan string) objectsCh := make(chan string)
@ -639,7 +666,7 @@ func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs,
for resp := range core.RemoveObjects(args.BucketName, objectsCh) { for resp := range core.RemoveObjects(args.BucketName, objectsCh) {
if resp.Err != nil { if resp.Err != nil {
return toJSONError(resp.Err, args.BucketName, resp.ObjectName) return toJSONError(ctx, resp.Err, args.BucketName, resp.ObjectName)
} }
} }
return nil return nil
@ -652,8 +679,8 @@ next:
if !hasSuffix(objectName, slashSeparator) && objectName != "" { if !hasSuffix(objectName, slashSeparator) && objectName != "" {
// Deny if WORM is enabled // Deny if WORM is enabled
if globalWORMEnabled { if globalWORMEnabled {
if _, err = objectAPI.GetObjectInfo(context.Background(), args.BucketName, objectName, ObjectOptions{}); err == nil { if _, err = objectAPI.GetObjectInfo(ctx, args.BucketName, objectName, ObjectOptions{}); err == nil {
return toJSONError(errMethodNotAllowed) return toJSONError(ctx, errMethodNotAllowed)
} }
} }
// Check for permissions only in the case of // Check for permissions only in the case of
@ -668,11 +695,11 @@ next:
IsOwner: owner, IsOwner: owner,
ObjectName: objectName, ObjectName: objectName,
}) { }) {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
} }
if err = deleteObject(context.Background(), objectAPI, web.CacheAPI(), args.BucketName, objectName, r); err != nil { if err = deleteObject(ctx, objectAPI, web.CacheAPI(), args.BucketName, objectName, r); err != nil {
break next break next
} }
continue continue
@ -686,20 +713,20 @@ next:
IsOwner: owner, IsOwner: owner,
ObjectName: objectName, ObjectName: objectName,
}) { }) {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
// For directories, list the contents recursively and remove. // For directories, list the contents recursively and remove.
marker := "" marker := ""
for { for {
var lo ListObjectsInfo var lo ListObjectsInfo
lo, err = listObjects(context.Background(), args.BucketName, objectName, marker, "", 1000) lo, err = listObjects(ctx, args.BucketName, objectName, marker, "", 1000)
if err != nil { if err != nil {
break next break next
} }
marker = lo.NextMarker marker = lo.NextMarker
for _, obj := range lo.Objects { for _, obj := range lo.Objects {
err = deleteObject(context.Background(), objectAPI, web.CacheAPI(), args.BucketName, obj.Name, r) err = deleteObject(ctx, objectAPI, web.CacheAPI(), args.BucketName, obj.Name, r)
if err != nil { if err != nil {
break next break next
} }
@ -712,7 +739,7 @@ next:
if err != nil && !isErrObjectNotFound(err) { if err != nil && !isErrObjectNotFound(err) {
// Ignore object not found error. // Ignore object not found error.
return toJSONError(err, args.BucketName, "") return toJSONError(ctx, err, args.BucketName, "")
} }
return nil return nil
@ -732,9 +759,10 @@ type LoginRep struct {
// Login - user login handler. // Login - user login handler.
func (web *webAPIHandlers) Login(r *http.Request, args *LoginArgs, reply *LoginRep) error { func (web *webAPIHandlers) Login(r *http.Request, args *LoginArgs, reply *LoginRep) error {
ctx := newWebContext(r, "webLogin")
token, err := authenticateWeb(args.Username, args.Password) token, err := authenticateWeb(args.Username, args.Password)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
reply.Token = token reply.Token = token
@ -750,16 +778,17 @@ type GenerateAuthReply struct {
} }
func (web webAPIHandlers) GenerateAuth(r *http.Request, args *WebGenericArgs, reply *GenerateAuthReply) error { func (web webAPIHandlers) GenerateAuth(r *http.Request, args *WebGenericArgs, reply *GenerateAuthReply) error {
ctx := newWebContext(r, "webGenerateAuth")
_, owner, authErr := webRequestAuthenticate(r) _, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
if !owner { if !owner {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
cred, err := auth.GetNewCredentials() cred, err := auth.GetNewCredentials()
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
reply.AccessKey = cred.AccessKey reply.AccessKey = cred.AccessKey
reply.SecretKey = cred.SecretKey reply.SecretKey = cred.SecretKey
@ -784,19 +813,20 @@ type SetAuthReply struct {
// SetAuth - Set accessKey and secretKey credentials. // SetAuth - Set accessKey and secretKey credentials.
func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *SetAuthReply) error { func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *SetAuthReply) error {
ctx := newWebContext(r, "webSetAuth")
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
// When WORM is enabled, disallow changing credenatials for owner and user // When WORM is enabled, disallow changing credenatials for owner and user
if globalWORMEnabled { if globalWORMEnabled {
return toJSONError(errChangeCredNotAllowed) return toJSONError(ctx, errChangeCredNotAllowed)
} }
if owner { if owner {
if globalIsEnvCreds || globalEtcdClient != nil { if globalIsEnvCreds || globalEtcdClient != nil {
return toJSONError(errChangeCredNotAllowed) return toJSONError(ctx, errChangeCredNotAllowed)
} }
// get Current creds and verify // get Current creds and verify
@ -807,7 +837,7 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se
creds, err := auth.CreateCredentials(args.NewAccessKey, args.NewSecretKey) creds, err := auth.CreateCredentials(args.NewAccessKey, args.NewSecretKey)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
// Acquire lock before updating global configuration. // Acquire lock before updating global configuration.
@ -818,16 +848,16 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se
prevCred = globalServerConfig.SetCredential(creds) prevCred = globalServerConfig.SetCredential(creds)
// Persist updated credentials. // Persist updated credentials.
if err = saveServerConfig(context.Background(), newObjectLayerFn(), globalServerConfig); err != nil { if err = saveServerConfig(ctx, newObjectLayerFn(), globalServerConfig); err != nil {
// Save the current creds when failed to update. // Save the current creds when failed to update.
globalServerConfig.SetCredential(prevCred) globalServerConfig.SetCredential(prevCred)
logger.LogIf(context.Background(), err) logger.LogIf(ctx, err)
return toJSONError(err) return toJSONError(ctx, err)
} }
reply.Token, err = authenticateWeb(args.NewAccessKey, args.NewSecretKey) reply.Token, err = authenticateWeb(args.NewAccessKey, args.NewSecretKey)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
} else { } else {
// for IAM users, access key cannot be updated // for IAM users, access key cannot be updated
@ -844,7 +874,7 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se
creds, err := auth.CreateCredentials(claims.Subject, args.NewSecretKey) creds, err := auth.CreateCredentials(claims.Subject, args.NewSecretKey)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
err = globalIAMSys.SetUserSecretKey(creds.AccessKey, creds.SecretKey) err = globalIAMSys.SetUserSecretKey(creds.AccessKey, creds.SecretKey)
@ -854,8 +884,9 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se
reply.Token, err = authenticateWeb(creds.AccessKey, creds.SecretKey) reply.Token, err = authenticateWeb(creds.AccessKey, creds.SecretKey)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
} }
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
@ -871,9 +902,10 @@ type URLTokenReply struct {
// CreateURLToken creates a URL token (short-lived) for GET requests. // CreateURLToken creates a URL token (short-lived) for GET requests.
func (web *webAPIHandlers) CreateURLToken(r *http.Request, args *WebGenericArgs, reply *URLTokenReply) error { func (web *webAPIHandlers) CreateURLToken(r *http.Request, args *WebGenericArgs, reply *URLTokenReply) error {
ctx := newWebContext(r, "webCreateURLToken")
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
creds := globalServerConfig.GetCredential() creds := globalServerConfig.GetCredential()
@ -881,13 +913,13 @@ func (web *webAPIHandlers) CreateURLToken(r *http.Request, args *WebGenericArgs,
var ok bool var ok bool
creds, ok = globalIAMSys.GetUser(claims.Subject) creds, ok = globalIAMSys.GetUser(claims.Subject)
if !ok { if !ok {
return toJSONError(errInvalidAccessKeyID) return toJSONError(ctx, errInvalidAccessKeyID)
} }
} }
token, err := authenticateURL(creds.AccessKey, creds.SecretKey) token, err := authenticateURL(creds.AccessKey, creds.SecretKey)
if err != nil { if err != nil {
return toJSONError(err) return toJSONError(ctx, err)
} }
reply.Token = token reply.Token = token
@ -963,7 +995,7 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) {
} }
// Extract incoming metadata if any. // Extract incoming metadata if any.
metadata, err := extractMetadata(context.Background(), r) metadata, err := extractMetadata(ctx, r)
if err != nil { if err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
return return
@ -1041,7 +1073,7 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) {
if !hasServerSideEncryptionHeader(r.Header) && web.CacheAPI() != nil { if !hasServerSideEncryptionHeader(r.Header) && web.CacheAPI() != nil {
putObject = web.CacheAPI().PutObject putObject = web.CacheAPI().PutObject
} }
objInfo, err := putObject(context.Background(), bucket, object, pReader, opts) objInfo, err := putObject(ctx, bucket, object, pReader, opts)
if err != nil { if err != nil {
writeWebErrorResponse(w, err) writeWebErrorResponse(w, err)
return return
@ -1422,7 +1454,7 @@ func (web *webAPIHandlers) DownloadZip(w http.ResponseWriter, r *http.Request) {
// date to the response writer. // date to the response writer.
marker := "" marker := ""
for { for {
lo, err := listObjects(context.Background(), args.BucketName, pathJoin(args.Prefix, object), marker, "", 1000) lo, err := listObjects(ctx, args.BucketName, pathJoin(args.Prefix, object), marker, "", 1000)
if err != nil { if err != nil {
return return
} }
@ -1454,14 +1486,15 @@ type GetBucketPolicyRep struct {
// GetBucketPolicy - get bucket policy for the requested prefix. // GetBucketPolicy - get bucket policy for the requested prefix.
func (web *webAPIHandlers) GetBucketPolicy(r *http.Request, args *GetBucketPolicyArgs, reply *GetBucketPolicyRep) error { func (web *webAPIHandlers) GetBucketPolicy(r *http.Request, args *GetBucketPolicyArgs, reply *GetBucketPolicyRep) error {
ctx := newWebContext(r, "webGetBucketPolicy")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
// For authenticated users apply IAM policy. // For authenticated users apply IAM policy.
if !globalIAMSys.IsAllowed(iampolicy.Args{ if !globalIAMSys.IsAllowed(iampolicy.Args{
@ -1471,47 +1504,47 @@ func (web *webAPIHandlers) GetBucketPolicy(r *http.Request, args *GetBucketPolic
ConditionValues: getConditionValues(r, "", claims.Subject), ConditionValues: getConditionValues(r, "", claims.Subject),
IsOwner: owner, IsOwner: owner,
}) { }) {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
var policyInfo = &miniogopolicy.BucketAccessPolicy{Version: "2012-10-17"} var policyInfo = &miniogopolicy.BucketAccessPolicy{Version: "2012-10-17"}
if isRemoteCallRequired(context.Background(), args.BucketName, objectAPI) { if isRemoteCallRequired(ctx, args.BucketName, objectAPI) {
sr, err := globalDNSConfig.Get(args.BucketName) sr, err := globalDNSConfig.Get(args.BucketName)
if err != nil { if err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
return toJSONError(BucketNotFound{ return toJSONError(ctx, BucketNotFound{
Bucket: args.BucketName, Bucket: args.BucketName,
}, args.BucketName) }, args.BucketName)
} }
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
client, rerr := getRemoteInstanceClient(r, getHostFromSrv(sr)) client, rerr := getRemoteInstanceClient(r, getHostFromSrv(sr))
if rerr != nil { if rerr != nil {
return toJSONError(rerr, args.BucketName) return toJSONError(ctx, rerr, args.BucketName)
} }
policyStr, err := client.GetBucketPolicy(args.BucketName) policyStr, err := client.GetBucketPolicy(args.BucketName)
if err != nil { if err != nil {
return toJSONError(rerr, args.BucketName) return toJSONError(ctx, rerr, args.BucketName)
} }
bucketPolicy, err := policy.ParseConfig(strings.NewReader(policyStr), args.BucketName) bucketPolicy, err := policy.ParseConfig(strings.NewReader(policyStr), args.BucketName)
if err != nil { if err != nil {
return toJSONError(rerr, args.BucketName) return toJSONError(ctx, rerr, args.BucketName)
} }
policyInfo, err = PolicyToBucketAccessPolicy(bucketPolicy) policyInfo, err = PolicyToBucketAccessPolicy(bucketPolicy)
if err != nil { if err != nil {
// This should not happen. // This should not happen.
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} else { } else {
bucketPolicy, err := objectAPI.GetBucketPolicy(context.Background(), args.BucketName) bucketPolicy, err := objectAPI.GetBucketPolicy(ctx, args.BucketName)
if err != nil { if err != nil {
if _, ok := err.(BucketPolicyNotFound); !ok { if _, ok := err.(BucketPolicyNotFound); !ok {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
return err return err
} }
@ -1519,7 +1552,7 @@ func (web *webAPIHandlers) GetBucketPolicy(r *http.Request, args *GetBucketPolic
policyInfo, err = PolicyToBucketAccessPolicy(bucketPolicy) policyInfo, err = PolicyToBucketAccessPolicy(bucketPolicy)
if err != nil { if err != nil {
// This should not happen. // This should not happen.
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} }
@ -1549,60 +1582,61 @@ type ListAllBucketPoliciesRep struct {
// ListAllBucketPolicies - get all bucket policy. // ListAllBucketPolicies - get all bucket policy.
func (web *webAPIHandlers) ListAllBucketPolicies(r *http.Request, args *ListAllBucketPoliciesArgs, reply *ListAllBucketPoliciesRep) error { func (web *webAPIHandlers) ListAllBucketPolicies(r *http.Request, args *ListAllBucketPoliciesArgs, reply *ListAllBucketPoliciesRep) error {
ctx := newWebContext(r, "WebListAllBucketPolicies")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
_, owner, authErr := webRequestAuthenticate(r) _, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
if !owner { if !owner {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
var policyInfo = new(miniogopolicy.BucketAccessPolicy) var policyInfo = new(miniogopolicy.BucketAccessPolicy)
if isRemoteCallRequired(context.Background(), args.BucketName, objectAPI) { if isRemoteCallRequired(ctx, args.BucketName, objectAPI) {
sr, err := globalDNSConfig.Get(args.BucketName) sr, err := globalDNSConfig.Get(args.BucketName)
if err != nil { if err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
return toJSONError(BucketNotFound{ return toJSONError(ctx, BucketNotFound{
Bucket: args.BucketName, Bucket: args.BucketName,
}, args.BucketName) }, args.BucketName)
} }
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
core, rerr := getRemoteInstanceClient(r, getHostFromSrv(sr)) core, rerr := getRemoteInstanceClient(r, getHostFromSrv(sr))
if rerr != nil { if rerr != nil {
return toJSONError(rerr, args.BucketName) return toJSONError(ctx, rerr, args.BucketName)
} }
var policyStr string var policyStr string
policyStr, err = core.Client.GetBucketPolicy(args.BucketName) policyStr, err = core.Client.GetBucketPolicy(args.BucketName)
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
if policyStr != "" { if policyStr != "" {
if err = json.Unmarshal([]byte(policyStr), policyInfo); err != nil { if err = json.Unmarshal([]byte(policyStr), policyInfo); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} }
} else { } else {
bucketPolicy, err := objectAPI.GetBucketPolicy(context.Background(), args.BucketName) bucketPolicy, err := objectAPI.GetBucketPolicy(ctx, args.BucketName)
if err != nil { if err != nil {
if _, ok := err.(BucketPolicyNotFound); !ok { if _, ok := err.(BucketPolicyNotFound); !ok {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} }
policyInfo, err = PolicyToBucketAccessPolicy(bucketPolicy) policyInfo, err = PolicyToBucketAccessPolicy(bucketPolicy)
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} }
@ -1629,16 +1663,17 @@ type SetBucketPolicyWebArgs struct {
// SetBucketPolicy - set bucket policy. // SetBucketPolicy - set bucket policy.
func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolicyWebArgs, reply *WebGenericRep) error { func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolicyWebArgs, reply *WebGenericRep) error {
ctx := newWebContext(r, "webSetBucketPolicy")
objectAPI := web.ObjectAPI() objectAPI := web.ObjectAPI()
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
if objectAPI == nil { if objectAPI == nil {
return toJSONError(errServerNotInitialized) return toJSONError(ctx, errServerNotInitialized)
} }
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
// For authenticated users apply IAM policy. // For authenticated users apply IAM policy.
@ -1649,12 +1684,12 @@ func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolic
ConditionValues: getConditionValues(r, "", claims.Subject), ConditionValues: getConditionValues(r, "", claims.Subject),
IsOwner: owner, IsOwner: owner,
}) { }) {
return toJSONError(errAccessDenied) return toJSONError(ctx, errAccessDenied)
} }
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
policyType := miniogopolicy.BucketPolicy(args.Policy) policyType := miniogopolicy.BucketPolicy(args.Policy)
@ -1664,40 +1699,38 @@ func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolic
} }
} }
ctx := context.Background() if isRemoteCallRequired(ctx, args.BucketName, objectAPI) {
if isRemoteCallRequired(context.Background(), args.BucketName, objectAPI) {
sr, err := globalDNSConfig.Get(args.BucketName) sr, err := globalDNSConfig.Get(args.BucketName)
if err != nil { if err != nil {
if err == dns.ErrNoEntriesFound { if err == dns.ErrNoEntriesFound {
return toJSONError(BucketNotFound{ return toJSONError(ctx, BucketNotFound{
Bucket: args.BucketName, Bucket: args.BucketName,
}, args.BucketName) }, args.BucketName)
} }
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
core, rerr := getRemoteInstanceClient(r, getHostFromSrv(sr)) core, rerr := getRemoteInstanceClient(r, getHostFromSrv(sr))
if rerr != nil { if rerr != nil {
return toJSONError(rerr, args.BucketName) return toJSONError(ctx, rerr, args.BucketName)
} }
var policyStr string var policyStr string
// Use the abstracted API instead of core, such that // Use the abstracted API instead of core, such that
// NoSuchBucketPolicy errors are automatically handled. // NoSuchBucketPolicy errors are automatically handled.
policyStr, err = core.Client.GetBucketPolicy(args.BucketName) policyStr, err = core.Client.GetBucketPolicy(args.BucketName)
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
var policyInfo = &miniogopolicy.BucketAccessPolicy{Version: "2012-10-17"} var policyInfo = &miniogopolicy.BucketAccessPolicy{Version: "2012-10-17"}
if policyStr != "" { if policyStr != "" {
if err = json.Unmarshal([]byte(policyStr), policyInfo); err != nil { if err = json.Unmarshal([]byte(policyStr), policyInfo); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} }
policyInfo.Statements = miniogopolicy.SetPolicy(policyInfo.Statements, policyType, args.BucketName, args.Prefix) policyInfo.Statements = miniogopolicy.SetPolicy(policyInfo.Statements, policyType, args.BucketName, args.Prefix)
if len(policyInfo.Statements) == 0 { if len(policyInfo.Statements) == 0 {
if err = core.SetBucketPolicy(args.BucketName, ""); err != nil { if err = core.SetBucketPolicy(args.BucketName, ""); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
return nil return nil
} }
@ -1705,35 +1738,35 @@ func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolic
bucketPolicy, err := BucketAccessPolicyToPolicy(policyInfo) bucketPolicy, err := BucketAccessPolicyToPolicy(policyInfo)
if err != nil { if err != nil {
// This should not happen. // This should not happen.
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
policyData, err := json.Marshal(bucketPolicy) policyData, err := json.Marshal(bucketPolicy)
if err != nil { if err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
if err = core.SetBucketPolicy(args.BucketName, string(policyData)); err != nil { if err = core.SetBucketPolicy(args.BucketName, string(policyData)); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} else { } else {
bucketPolicy, err := objectAPI.GetBucketPolicy(ctx, args.BucketName) bucketPolicy, err := objectAPI.GetBucketPolicy(ctx, args.BucketName)
if err != nil { if err != nil {
if _, ok := err.(BucketPolicyNotFound); !ok { if _, ok := err.(BucketPolicyNotFound); !ok {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
} }
policyInfo, err := PolicyToBucketAccessPolicy(bucketPolicy) policyInfo, err := PolicyToBucketAccessPolicy(bucketPolicy)
if err != nil { if err != nil {
// This should not happen. // This should not happen.
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
policyInfo.Statements = miniogopolicy.SetPolicy(policyInfo.Statements, policyType, args.BucketName, args.Prefix) policyInfo.Statements = miniogopolicy.SetPolicy(policyInfo.Statements, policyType, args.BucketName, args.Prefix)
if len(policyInfo.Statements) == 0 { if len(policyInfo.Statements) == 0 {
if err = objectAPI.DeleteBucketPolicy(ctx, args.BucketName); err != nil { if err = objectAPI.DeleteBucketPolicy(ctx, args.BucketName); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
globalPolicySys.Remove(args.BucketName) globalPolicySys.Remove(args.BucketName)
@ -1743,12 +1776,12 @@ func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolic
bucketPolicy, err = BucketAccessPolicyToPolicy(policyInfo) bucketPolicy, err = BucketAccessPolicyToPolicy(policyInfo)
if err != nil { if err != nil {
// This should not happen. // This should not happen.
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
// Parse validate and save bucket policy. // Parse validate and save bucket policy.
if err := objectAPI.SetBucketPolicy(ctx, args.BucketName, bucketPolicy); err != nil { if err := objectAPI.SetBucketPolicy(ctx, args.BucketName, bucketPolicy); err != nil {
return toJSONError(err, args.BucketName) return toJSONError(ctx, err, args.BucketName)
} }
globalPolicySys.Set(args.BucketName, *bucketPolicy) globalPolicySys.Set(args.BucketName, *bucketPolicy)
@ -1782,16 +1815,17 @@ type PresignedGetRep struct {
// PresignedGET - returns presigned-Get url. // PresignedGET - returns presigned-Get url.
func (web *webAPIHandlers) PresignedGet(r *http.Request, args *PresignedGetArgs, reply *PresignedGetRep) error { func (web *webAPIHandlers) PresignedGet(r *http.Request, args *PresignedGetArgs, reply *PresignedGetRep) error {
ctx := newWebContext(r, "webPresignedGet")
claims, owner, authErr := webRequestAuthenticate(r) claims, owner, authErr := webRequestAuthenticate(r)
if authErr != nil { if authErr != nil {
return toJSONError(authErr) return toJSONError(ctx, authErr)
} }
var creds auth.Credentials var creds auth.Credentials
if !owner { if !owner {
var ok bool var ok bool
creds, ok = globalIAMSys.GetUser(claims.Subject) creds, ok = globalIAMSys.GetUser(claims.Subject)
if !ok { if !ok {
return toJSONError(errInvalidAccessKeyID) return toJSONError(ctx, errInvalidAccessKeyID)
} }
} else { } else {
creds = globalServerConfig.GetCredential() creds = globalServerConfig.GetCredential()
@ -1806,7 +1840,7 @@ func (web *webAPIHandlers) PresignedGet(r *http.Request, args *PresignedGetArgs,
// Check if bucket is a reserved bucket name or invalid. // Check if bucket is a reserved bucket name or invalid.
if isReservedOrInvalidBucket(args.BucketName, false) { if isReservedOrInvalidBucket(args.BucketName, false) {
return toJSONError(errInvalidBucketName) return toJSONError(ctx, errInvalidBucketName)
} }
reply.UIVersion = browser.UIVersion reply.UIVersion = browser.UIVersion
@ -1852,8 +1886,8 @@ func presignedGet(host, bucket, object string, expiry int64, creds auth.Credenti
// toJSONError converts regular errors into more user friendly // toJSONError converts regular errors into more user friendly
// and consumable error message for the browser UI. // and consumable error message for the browser UI.
func toJSONError(err error, params ...string) (jerr *json2.Error) { func toJSONError(ctx context.Context, err error, params ...string) (jerr *json2.Error) {
apiErr := toWebAPIError(err) apiErr := toWebAPIError(ctx, err)
jerr = &json2.Error{ jerr = &json2.Error{
Message: apiErr.Description, Message: apiErr.Description,
} }
@ -1892,7 +1926,7 @@ func toJSONError(err error, params ...string) (jerr *json2.Error) {
} }
// toWebAPIError - convert into error into APIError. // toWebAPIError - convert into error into APIError.
func toWebAPIError(err error) APIError { func toWebAPIError(ctx context.Context, err error) APIError {
switch err { switch err {
case errServerNotInitialized: case errServerNotInitialized:
return APIError{ return APIError{
@ -1973,7 +2007,7 @@ func toWebAPIError(err error) APIError {
} }
// Log unexpected and unhandled errors. // Log unexpected and unhandled errors.
logger.LogIf(context.Background(), err) logger.LogIf(ctx, err)
return APIError{ return APIError{
Code: "InternalError", Code: "InternalError",
HTTPStatusCode: http.StatusInternalServerError, HTTPStatusCode: http.StatusInternalServerError,
@ -1983,7 +2017,11 @@ func toWebAPIError(err error) APIError {
// writeWebErrorResponse - set HTTP status code and write error description to the body. // writeWebErrorResponse - set HTTP status code and write error description to the body.
func writeWebErrorResponse(w http.ResponseWriter, err error) { func writeWebErrorResponse(w http.ResponseWriter, err error) {
apiErr := toWebAPIError(err) reqInfo := &logger.ReqInfo{
DeploymentID: globalDeploymentID,
}
ctx := logger.SetReqInfo(context.Background(), reqInfo)
apiErr := toWebAPIError(ctx, err)
w.WriteHeader(apiErr.HTTPStatusCode) w.WriteHeader(apiErr.HTTPStatusCode)
w.Write([]byte(apiErr.Description)) w.Write([]byte(apiErr.Description))
} }