Log x-amz-request-id as log and XML error response (#6173)

Currently, requestid field in logEntry is not populated, as the
requestid field gets set at the very end.
It is now set before regular handler functions. This is also
useful in setting it as part of the XML error response.

Travis build for ppc64le has been quite inconsistent and stays queued
for most of the time. Removing this build as part of Travis.yml for
the time being.
master
kannappanr 6 years ago committed by Harshavardhana
parent 7b91bd71fe
commit 76ddf4d32f
  1. 4
      cmd/acl-handlers.go
  2. 4
      cmd/admin-handlers.go
  3. 4
      cmd/api-errors.go
  4. 2
      cmd/api-headers.go
  5. 2
      cmd/api-response-multipart.go
  6. 4
      cmd/api-response.go
  7. 4
      cmd/bucket-handlers-listobjects.go
  8. 16
      cmd/bucket-handlers.go
  9. 8
      cmd/bucket-notification-handlers.go
  10. 6
      cmd/bucket-policy-handlers.go
  11. 20
      cmd/generic-handlers.go
  12. 22
      cmd/object-handlers.go
  13. 28
      cmd/object-handlers_test.go
  14. 2
      cmd/routers.go
  15. 4
      cmd/test-utils_test.go
  16. 3
      cmd/utils.go

@ -54,7 +54,7 @@ type accessControlPolicy struct {
// This operation uses the ACL // This operation uses the ACL
// subresource to return the ACL of a specified bucket. // subresource to return the ACL of a specified bucket.
func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "GetBucketACL") ctx := newContext(r, w, "GetBucketACL")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -101,7 +101,7 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.
// This operation uses the ACL // This operation uses the ACL
// subresource to return the ACL of a specified object. // subresource to return the ACL of a specified object.
func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "GetObjectACL") ctx := newContext(r, w, "GetObjectACL")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

@ -356,7 +356,7 @@ func (a adminAPIHandlers) ListLocksHandler(w http.ResponseWriter, r *http.Reques
// --------- // ---------
// Clear locks held on a given bucket, prefix and duration it was held for. // Clear locks held on a given bucket, prefix and duration it was held for.
func (a adminAPIHandlers) ClearLocksHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) ClearLocksHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ClearLocks") ctx := newContext(r, w, "ClearLocks")
// Get object layer instance. // Get object layer instance.
objLayer := newObjectLayerFn() objLayer := newObjectLayerFn()
@ -464,7 +464,7 @@ func extractHealInitParams(r *http.Request) (bucket, objPrefix string,
// sequence. However, if the force-start flag is provided, the server // sequence. However, if the force-start flag is provided, the server
// aborts the running heal sequence and starts a new one. // aborts the running heal sequence and starts a new one.
func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "Heal") ctx := newContext(r, w, "Heal")
// Get object layer instance. // Get object layer instance.
objLayer := newObjectLayerFn() objLayer := newObjectLayerFn()

@ -1012,12 +1012,12 @@ func getAPIError(code APIErrorCode) APIError {
// getErrorResponse gets in standard error and resource value and // getErrorResponse gets in standard error and resource value and
// provides a encodable populated response values // provides a encodable populated response values
func getAPIErrorResponse(err APIError, resource string) APIErrorResponse { func getAPIErrorResponse(err APIError, resource, requestid string) APIErrorResponse {
return APIErrorResponse{ return APIErrorResponse{
Code: err.Code, Code: err.Code,
Message: err.Description, Message: err.Description,
Resource: resource, Resource: resource,
RequestID: "3L137", RequestID: requestid,
HostID: "3L137", HostID: "3L137",
} }
} }

@ -34,8 +34,6 @@ func mustGetRequestID(t time.Time) string {
// Write http common headers // Write http common headers
func setCommonHeaders(w http.ResponseWriter) { func setCommonHeaders(w http.ResponseWriter) {
// Set unique request ID for each reply.
w.Header().Set(responseRequestIDKey, mustGetRequestID(UTCNow()))
w.Header().Set("Server", globalServerUserAgent) w.Header().Set("Server", globalServerUserAgent)
// Set `x-amz-bucket-region` only if region is set on the server // Set `x-amz-bucket-region` only if region is set on the server
// by default minio uses an empty region. // by default minio uses an empty region.

@ -44,7 +44,7 @@ func writePartSmallErrorResponse(w http.ResponseWriter, r *http.Request, err Par
apiError := getAPIError(toAPIErrorCode(err)) apiError := getAPIError(toAPIErrorCode(err))
// Generate complete multipart error response. // Generate complete multipart error response.
errorResponse := getAPIErrorResponse(apiError, r.URL.Path) errorResponse := getAPIErrorResponse(apiError, r.URL.Path, w.Header().Get(responseRequestIDKey))
cmpErrResp := completeMultipartAPIError{err.PartSize, int64(5242880), err.PartNumber, err.PartETag, errorResponse} cmpErrResp := completeMultipartAPIError{err.PartSize, int64(5242880), err.PartNumber, err.PartETag, errorResponse}
encodedErrorResponse := encodeResponse(cmpErrResp) encodedErrorResponse := encodeResponse(cmpErrResp)

@ -577,7 +577,7 @@ func writeErrorResponse(w http.ResponseWriter, errorCode APIErrorCode, reqURL *u
} }
apiError := getAPIError(errorCode) apiError := getAPIError(errorCode)
// Generate error response. // Generate error response.
errorResponse := getAPIErrorResponse(apiError, reqURL.Path) errorResponse := getAPIErrorResponse(apiError, reqURL.Path, w.Header().Get(responseRequestIDKey))
encodedErrorResponse := encodeResponse(errorResponse) encodedErrorResponse := encodeResponse(errorResponse)
writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeXML) writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeXML)
} }
@ -592,7 +592,7 @@ func writeErrorResponseHeadersOnly(w http.ResponseWriter, errorCode APIErrorCode
func writeErrorResponseJSON(w http.ResponseWriter, errorCode APIErrorCode, reqURL *url.URL) { func writeErrorResponseJSON(w http.ResponseWriter, errorCode APIErrorCode, reqURL *url.URL) {
apiError := getAPIError(errorCode) apiError := getAPIError(errorCode)
// Generate error response. // Generate error response.
errorResponse := getAPIErrorResponse(apiError, reqURL.Path) errorResponse := getAPIErrorResponse(apiError, reqURL.Path, w.Header().Get(responseRequestIDKey))
encodedErrorResponse := encodeResponseJSON(errorResponse) encodedErrorResponse := encodeResponseJSON(errorResponse)
writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeJSON) writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeJSON)
} }

@ -54,7 +54,7 @@ func validateListObjectsArgs(prefix, marker, delimiter string, maxKeys int) APIE
// NOTE: It is recommended that this API to be used for application development. // NOTE: It is recommended that this API to be used for application development.
// Minio continues to support ListObjectsV1 for supporting legacy tools. // Minio continues to support ListObjectsV1 for supporting legacy tools.
func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ListObjectsV2") ctx := newContext(r, w, "ListObjectsV2")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -123,7 +123,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
// criteria to return a subset of the objects in a bucket. // criteria to return a subset of the objects in a bucket.
// //
func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ListObjectsV1") ctx := newContext(r, w, "ListObjectsV1")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

@ -87,7 +87,7 @@ func initFederatorBackend(objLayer ObjectLayer) {
// ------------------------- // -------------------------
// This operation returns bucket location. // This operation returns bucket location.
func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "GetBucketLocation") ctx := newContext(r, w, "GetBucketLocation")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -141,7 +141,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
// uploads in the response. // uploads in the response.
// //
func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ListMultipartUploads") ctx := newContext(r, w, "ListMultipartUploads")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -188,7 +188,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
// This implementation of the GET operation returns a list of all buckets // This implementation of the GET operation returns a list of all buckets
// owned by the authenticated sender of the request. // owned by the authenticated sender of the request.
func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ListBuckets") ctx := newContext(r, w, "ListBuckets")
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -244,7 +244,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
// DeleteMultipleObjectsHandler - deletes multiple objects. // DeleteMultipleObjectsHandler - deletes multiple objects.
func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "DeleteMultipleObjects") ctx := newContext(r, w, "DeleteMultipleObjects")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -398,7 +398,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
// ---------- // ----------
// This implementation of the PUT operation creates a new bucket for authenticated request // This implementation of the PUT operation creates a new bucket for authenticated request
func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "PutBucket") ctx := newContext(r, w, "PutBucket")
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -474,7 +474,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
// This implementation of the POST operation handles object creation with a specified // This implementation of the POST operation handles object creation with a specified
// signature policy in multipart/form-data // signature policy in multipart/form-data
func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "PostPolicyBucket") ctx := newContext(r, w, "PostPolicyBucket")
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -694,7 +694,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
// have permission to access it. Otherwise, the operation might // have permission to access it. Otherwise, the operation might
// return responses such as 404 Not Found and 403 Forbidden. // return responses such as 404 Not Found and 403 Forbidden.
func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "HeadBucket") ctx := newContext(r, w, "HeadBucket")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -724,7 +724,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re
// DeleteBucketHandler - Delete bucket // DeleteBucketHandler - Delete bucket
func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "DeleteBucket") ctx := newContext(r, w, "DeleteBucket")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

@ -42,7 +42,7 @@ var errNoSuchNotifications = errors.New("The specified bucket does not have buck
// as per http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html. // as per http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html.
// It returns empty configuration if its not set. // It returns empty configuration if its not set.
func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "GetBucketNotification") ctx := newContext(r, w, "GetBucketNotification")
vars := mux.Vars(r) vars := mux.Vars(r)
bucketName := vars["bucket"] bucketName := vars["bucket"]
@ -94,7 +94,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter,
// PutBucketNotificationHandler - This HTTP handler stores given notification configuration as per // PutBucketNotificationHandler - This HTTP handler stores given notification configuration as per
// http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html. // http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html.
func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "PutBucketNotification") ctx := newContext(r, w, "PutBucketNotification")
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -154,7 +154,7 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter,
// ListenBucketNotificationHandler - This HTTP handler sends events to the connected HTTP client. // ListenBucketNotificationHandler - This HTTP handler sends events to the connected HTTP client.
// Client should send prefix/suffix object name to match and events to watch as query parameters. // Client should send prefix/suffix object name to match and events to watch as query parameters.
func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ListenBucketNotification") ctx := newContext(r, w, "ListenBucketNotification")
// Validate if bucket exists. // Validate if bucket exists.
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
@ -235,7 +235,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
rulesMap := event.NewRulesMap(eventNames, pattern, target.ID()) rulesMap := event.NewRulesMap(eventNames, pattern, target.ID())
if err := globalNotificationSys.AddRemoteTarget(bucketName, target, rulesMap); err != nil { if err = globalNotificationSys.AddRemoteTarget(bucketName, target, rulesMap); err != nil {
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name) logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
writeErrorResponse(w, toAPIErrorCode(err), r.URL) writeErrorResponse(w, toAPIErrorCode(err), r.URL)

@ -38,7 +38,7 @@ const (
// PutBucketPolicyHandler - This HTTP handler stores given bucket policy configuration as per // PutBucketPolicyHandler - This HTTP handler stores given bucket policy configuration as per
// https://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html // https://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "PutBucketPolicy") ctx := newContext(r, w, "PutBucketPolicy")
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
if objAPI == nil { if objAPI == nil {
@ -99,7 +99,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht
// DeleteBucketPolicyHandler - This HTTP handler removes bucket policy configuration. // DeleteBucketPolicyHandler - This HTTP handler removes bucket policy configuration.
func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "DeleteBucketPolicy") ctx := newContext(r, w, "DeleteBucketPolicy")
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
if objAPI == nil { if objAPI == nil {
@ -135,7 +135,7 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r
// GetBucketPolicyHandler - This HTTP handler returns bucket policy configuration. // GetBucketPolicyHandler - This HTTP handler returns bucket policy configuration.
func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "GetBucketPolicy") ctx := newContext(r, w, "GetBucketPolicy")
objAPI := api.ObjectAPI() objAPI := api.ObjectAPI()
if objAPI == nil { if objAPI == nil {

@ -723,6 +723,26 @@ func (l rateLimit) ServeHTTP(w http.ResponseWriter, r *http.Request) {
l.handler.ServeHTTP(w, r) l.handler.ServeHTTP(w, r)
} }
// requestIDHeaderHandler sets x-amz-request-id header.
// Previously, this value was set right before a response
// was sent to the client.So, logger and Error response XML
// were not using this value.
// This is set here so that this header can be logged as
// part of the log entry and Error response XML.
type requestIDHeaderHandler struct {
handler http.Handler
}
func addrequestIDHeader(h http.Handler) http.Handler {
return requestIDHeaderHandler{handler: h}
}
func (s requestIDHeaderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Set unique request ID for each response.
w.Header().Set(responseRequestIDKey, mustGetRequestID(UTCNow()))
s.handler.ServeHTTP(w, r)
}
type securityHeaderHandler struct { type securityHeaderHandler struct {
handler http.Handler handler http.Handler
} }

@ -68,7 +68,7 @@ func setHeadGetRespHeaders(w http.ResponseWriter, reqParams url.Values) {
// This implementation of the GET operation retrieves object. To use GET, // This implementation of the GET operation retrieves object. To use GET,
// you must have READ access to the object. // you must have READ access to the object.
func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "GetObject") ctx := newContext(r, w, "GetObject")
var object, bucket string var object, bucket string
vars := mux.Vars(r) vars := mux.Vars(r)
@ -218,7 +218,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
// ----------- // -----------
// The HEAD operation retrieves metadata from an object without returning the object itself. // The HEAD operation retrieves metadata from an object without returning the object itself.
func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "HeadObject") ctx := newContext(r, w, "HeadObject")
var object, bucket string var object, bucket string
vars := mux.Vars(r) vars := mux.Vars(r)
@ -341,7 +341,7 @@ func getCpObjMetadataFromHeader(ctx context.Context, r *http.Request, userMeta m
// This implementation of the PUT operation adds an object to a bucket // This implementation of the PUT operation adds an object to a bucket
// while reading the object from another source. // while reading the object from another source.
func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "CopyObject") ctx := newContext(r, w, "CopyObject")
vars := mux.Vars(r) vars := mux.Vars(r)
dstBucket := vars["bucket"] dstBucket := vars["bucket"]
@ -638,7 +638,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
// ---------- // ----------
// This implementation of the PUT operation adds an object to a bucket. // This implementation of the PUT operation adds an object to a bucket.
func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "PutObject") ctx := newContext(r, w, "PutObject")
objectAPI := api.ObjectAPI() objectAPI := api.ObjectAPI()
if objectAPI == nil { if objectAPI == nil {
@ -845,7 +845,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
// NewMultipartUploadHandler - New multipart upload. // NewMultipartUploadHandler - New multipart upload.
func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "NewMultipartUpload") ctx := newContext(r, w, "NewMultipartUpload")
var object, bucket string var object, bucket string
vars := mux.Vars(r) vars := mux.Vars(r)
@ -932,7 +932,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r
// CopyObjectPartHandler - uploads a part by copying data from an existing object as data source. // CopyObjectPartHandler - uploads a part by copying data from an existing object as data source.
func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "CopyObjectPart") ctx := newContext(r, w, "CopyObjectPart")
vars := mux.Vars(r) vars := mux.Vars(r)
dstBucket := vars["bucket"] dstBucket := vars["bucket"]
@ -1131,7 +1131,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt
// PutObjectPartHandler - uploads an incoming part for an ongoing multipart operation. // PutObjectPartHandler - uploads an incoming part for an ongoing multipart operation.
func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "PutObjectPart") ctx := newContext(r, w, "PutObjectPart")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -1330,7 +1330,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
// AbortMultipartUploadHandler - Abort multipart upload // AbortMultipartUploadHandler - Abort multipart upload
func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "AbortMultipartUpload") ctx := newContext(r, w, "AbortMultipartUpload")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -1369,7 +1369,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter,
// ListObjectPartsHandler - List object parts // ListObjectPartsHandler - List object parts
func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "ListObjectParts") ctx := newContext(r, w, "ListObjectParts")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -1409,7 +1409,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht
// CompleteMultipartUploadHandler - Complete multipart upload. // CompleteMultipartUploadHandler - Complete multipart upload.
func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "CompleteMultipartUpload") ctx := newContext(r, w, "CompleteMultipartUpload")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
@ -1518,7 +1518,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
// DeleteObjectHandler - delete an object // DeleteObjectHandler - delete an object
func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, "DeleteObject") ctx := newContext(r, w, "DeleteObject")
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]

@ -263,7 +263,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
accessKey: credentials.AccessKey, accessKey: credentials.AccessKey,
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), getGetObjectURL("", bucketName, "abcd"))), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), getGetObjectURL("", bucketName, "abcd"), "")),
expectedRespStatus: http.StatusNotFound, expectedRespStatus: http.StatusNotFound,
}, },
// Test case - 3. // Test case - 3.
@ -287,7 +287,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
accessKey: credentials.AccessKey, accessKey: credentials.AccessKey,
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidRange), getGetObjectURL("", bucketName, objectName))), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidRange), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusRequestedRangeNotSatisfiable, expectedRespStatus: http.StatusRequestedRangeNotSatisfiable,
}, },
// Test case - 5. // Test case - 5.
@ -313,7 +313,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
accessKey: "Invalid-AccessID", accessKey: "Invalid-AccessID",
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), getGetObjectURL("", bucketName, objectName))), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusForbidden, expectedRespStatus: http.StatusForbidden,
}, },
// Test case - 7. // Test case - 7.
@ -326,7 +326,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName),
getGetObjectURL("", bucketName, "../../etc"))), getGetObjectURL("", bucketName, "../../etc"), "")),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 8. // Test case - 8.
@ -339,7 +339,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey),
"/"+bucketName+"/"+". ./. ./etc")), "/"+bucketName+"/"+". ./. ./etc", "")),
expectedRespStatus: http.StatusNotFound, expectedRespStatus: http.StatusNotFound,
}, },
// Test case - 9. // Test case - 9.
@ -352,7 +352,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName),
"/"+bucketName+"/"+". ./../etc")), "/"+bucketName+"/"+". ./../etc", "")),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 10. // Test case - 10.
@ -365,7 +365,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey),
getGetObjectURL("", bucketName, "etc/path/proper/.../etc"))), getGetObjectURL("", bucketName, "etc/path/proper/.../etc"), "")),
expectedRespStatus: http.StatusNotFound, expectedRespStatus: http.StatusNotFound,
}, },
} }
@ -2238,7 +2238,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})),
getGetObjectURL("", bucketName, objectName))), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 2. // Test case - 2.
@ -2253,7 +2253,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrMalformedXML), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrMalformedXML),
getGetObjectURL("", bucketName, objectName))), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 3. // Test case - 3.
@ -2268,7 +2268,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidUploadID{UploadID: "abc"})), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidUploadID{UploadID: "abc"})),
getGetObjectURL("", bucketName, objectName))), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusNotFound, expectedRespStatus: http.StatusNotFound,
}, },
// Test case - 4. // Test case - 4.
@ -2283,7 +2283,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
expectedContent: encodeResponse(completeMultipartAPIError{int64(4), int64(5242880), 1, "e2fc714c4727ee9395f324cd2e7f331f", expectedContent: encodeResponse(completeMultipartAPIError{int64(4), int64(5242880), 1, "e2fc714c4727ee9395f324cd2e7f331f",
getAPIErrorResponse(getAPIError(toAPIErrorCode(PartTooSmall{PartNumber: 1})), getAPIErrorResponse(getAPIError(toAPIErrorCode(PartTooSmall{PartNumber: 1})),
getGetObjectURL("", bucketName, objectName))}), getGetObjectURL("", bucketName, objectName), "")}),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 5. // Test case - 5.
@ -2297,7 +2297,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})),
getGetObjectURL("", bucketName, objectName))), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 6. // Test case - 6.
@ -2312,7 +2312,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidPartOrder), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidPartOrder),
getGetObjectURL("", bucketName, objectName))), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusBadRequest, expectedRespStatus: http.StatusBadRequest,
}, },
// Test case - 7. // Test case - 7.
@ -2327,7 +2327,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
secretKey: credentials.SecretKey, secretKey: credentials.SecretKey,
expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID),
getGetObjectURL("", bucketName, objectName))), getGetObjectURL("", bucketName, objectName), "")),
expectedRespStatus: http.StatusForbidden, expectedRespStatus: http.StatusForbidden,
}, },
// Test case - 8. // Test case - 8.

@ -47,6 +47,8 @@ func registerDistXLRouters(router *mux.Router, endpoints EndpointList) {
// List of some generic handlers which are applied for all incoming requests. // List of some generic handlers which are applied for all incoming requests.
var globalHandlers = []HandlerFunc{ var globalHandlers = []HandlerFunc{
// set x-amz-request-id header.
addrequestIDHeader,
// set HTTP security headers such as Content-Security-Policy. // set HTTP security headers such as Content-Security-Policy.
addSecurityHeaders, addSecurityHeaders,
// Forward path style requests to actual host in a bucket federated setup. // Forward path style requests to actual host in a bucket federated setup.

@ -1855,7 +1855,7 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, obj ObjectLayer, testName, bucketN
} }
// expected error response in bytes when objectLayer is not initialized, or set to `nil`. // expected error response in bytes when objectLayer is not initialized, or set to `nil`.
expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName))) expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName), ""))
// HEAD HTTTP request doesn't contain response body. // HEAD HTTTP request doesn't contain response body.
if anonReq.Method != "HEAD" { if anonReq.Method != "HEAD" {
@ -1958,7 +1958,7 @@ func ExecObjectLayerAPINilTest(t TestErrHandler, bucketName, objectName, instanc
} }
// expected error response in bytes when objectLayer is not initialized, or set to `nil`. // expected error response in bytes when objectLayer is not initialized, or set to `nil`.
expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrServerNotInitialized), expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrServerNotInitialized),
getGetObjectURL("", bucketName, objectName))) getGetObjectURL("", bucketName, objectName), ""))
// HEAD HTTP Request doesn't contain body in its response, // HEAD HTTP Request doesn't contain body in its response,
// for other type of HTTP requests compare the response body content with the expected one. // for other type of HTTP requests compare the response body content with the expected one.

@ -331,7 +331,7 @@ func ceilFrac(numerator, denominator int64) (ceil int64) {
} }
// Returns context with ReqInfo details set in the context. // Returns context with ReqInfo details set in the context.
func newContext(r *http.Request, api string) context.Context { func newContext(r *http.Request, w http.ResponseWriter, api string) context.Context {
vars := mux.Vars(r) vars := mux.Vars(r)
bucket := vars["bucket"] bucket := vars["bucket"]
object := vars["object"] object := vars["object"]
@ -341,6 +341,7 @@ func newContext(r *http.Request, api string) context.Context {
object = prefix object = prefix
} }
reqInfo := &logger.ReqInfo{ reqInfo := &logger.ReqInfo{
RequestID: w.Header().Get(responseRequestIDKey),
RemoteHost: handlers.GetSourceIP(r), RemoteHost: handlers.GetSourceIP(r),
UserAgent: r.Header.Get("user-agent"), UserAgent: r.Header.Get("user-agent"),
API: api, API: api,

Loading…
Cancel
Save