diff --git a/cmd/acl-handlers.go b/cmd/acl-handlers.go index 9f6ab9e92..f871a1db8 100644 --- a/cmd/acl-handlers.go +++ b/cmd/acl-handlers.go @@ -54,7 +54,7 @@ type accessControlPolicy struct { // This operation uses the ACL // subresource to return the ACL of a specified bucket. func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "GetBucketACL") + ctx := newContext(r, w, "GetBucketACL") vars := mux.Vars(r) bucket := vars["bucket"] @@ -101,7 +101,7 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http. // This operation uses the ACL // subresource to return the ACL of a specified object. func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "GetObjectACL") + ctx := newContext(r, w, "GetObjectACL") vars := mux.Vars(r) bucket := vars["bucket"] diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 88306ac53..c55f269d0 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -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. func (a adminAPIHandlers) ClearLocksHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "ClearLocks") + ctx := newContext(r, w, "ClearLocks") // Get object layer instance. 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 // aborts the running heal sequence and starts a new one. func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "Heal") + ctx := newContext(r, w, "Heal") // Get object layer instance. objLayer := newObjectLayerFn() diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 21b99a71e..dbcff9629 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -1012,12 +1012,12 @@ func getAPIError(code APIErrorCode) APIError { // getErrorResponse gets in standard error and resource value and // provides a encodable populated response values -func getAPIErrorResponse(err APIError, resource string) APIErrorResponse { +func getAPIErrorResponse(err APIError, resource, requestid string) APIErrorResponse { return APIErrorResponse{ Code: err.Code, Message: err.Description, Resource: resource, - RequestID: "3L137", + RequestID: requestid, HostID: "3L137", } } diff --git a/cmd/api-headers.go b/cmd/api-headers.go index cd678e2dd..ac030c4e6 100644 --- a/cmd/api-headers.go +++ b/cmd/api-headers.go @@ -34,8 +34,6 @@ func mustGetRequestID(t time.Time) string { // Write http common headers func setCommonHeaders(w http.ResponseWriter) { - // Set unique request ID for each reply. - w.Header().Set(responseRequestIDKey, mustGetRequestID(UTCNow())) w.Header().Set("Server", globalServerUserAgent) // Set `x-amz-bucket-region` only if region is set on the server // by default minio uses an empty region. diff --git a/cmd/api-response-multipart.go b/cmd/api-response-multipart.go index 51563944a..d5e8212cc 100644 --- a/cmd/api-response-multipart.go +++ b/cmd/api-response-multipart.go @@ -44,7 +44,7 @@ func writePartSmallErrorResponse(w http.ResponseWriter, r *http.Request, err Par apiError := getAPIError(toAPIErrorCode(err)) // 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} encodedErrorResponse := encodeResponse(cmpErrResp) diff --git a/cmd/api-response.go b/cmd/api-response.go index 417be54c1..9d7348f13 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -577,7 +577,7 @@ func writeErrorResponse(w http.ResponseWriter, errorCode APIErrorCode, reqURL *u } apiError := getAPIError(errorCode) // Generate error response. - errorResponse := getAPIErrorResponse(apiError, reqURL.Path) + errorResponse := getAPIErrorResponse(apiError, reqURL.Path, w.Header().Get(responseRequestIDKey)) encodedErrorResponse := encodeResponse(errorResponse) 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) { apiError := getAPIError(errorCode) // Generate error response. - errorResponse := getAPIErrorResponse(apiError, reqURL.Path) + errorResponse := getAPIErrorResponse(apiError, reqURL.Path, w.Header().Get(responseRequestIDKey)) encodedErrorResponse := encodeResponseJSON(errorResponse) writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeJSON) } diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index 57d532c4c..905b63530 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -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. // Minio continues to support ListObjectsV1 for supporting legacy tools. func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "ListObjectsV2") + ctx := newContext(r, w, "ListObjectsV2") vars := mux.Vars(r) 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. // func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "ListObjectsV1") + ctx := newContext(r, w, "ListObjectsV1") vars := mux.Vars(r) bucket := vars["bucket"] diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 9e2fecaad..eec7e693a 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -87,7 +87,7 @@ func initFederatorBackend(objLayer ObjectLayer) { // ------------------------- // This operation returns bucket location. func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "GetBucketLocation") + ctx := newContext(r, w, "GetBucketLocation") vars := mux.Vars(r) bucket := vars["bucket"] @@ -141,7 +141,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r * // uploads in the response. // func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "ListMultipartUploads") + ctx := newContext(r, w, "ListMultipartUploads") vars := mux.Vars(r) 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 // owned by the authenticated sender of the request. func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "ListBuckets") + ctx := newContext(r, w, "ListBuckets") objectAPI := api.ObjectAPI() if objectAPI == nil { @@ -244,7 +244,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R // DeleteMultipleObjectsHandler - deletes multiple objects. func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "DeleteMultipleObjects") + ctx := newContext(r, w, "DeleteMultipleObjects") vars := mux.Vars(r) 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 func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "PutBucket") + ctx := newContext(r, w, "PutBucket") objectAPI := api.ObjectAPI() 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 // signature policy in multipart/form-data func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "PostPolicyBucket") + ctx := newContext(r, w, "PostPolicyBucket") objectAPI := api.ObjectAPI() 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 // return responses such as 404 Not Found and 403 Forbidden. func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "HeadBucket") + ctx := newContext(r, w, "HeadBucket") vars := mux.Vars(r) bucket := vars["bucket"] @@ -724,7 +724,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re // DeleteBucketHandler - Delete bucket func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "DeleteBucket") + ctx := newContext(r, w, "DeleteBucket") vars := mux.Vars(r) bucket := vars["bucket"] diff --git a/cmd/bucket-notification-handlers.go b/cmd/bucket-notification-handlers.go index c67999286..792d7dbc5 100644 --- a/cmd/bucket-notification-handlers.go +++ b/cmd/bucket-notification-handlers.go @@ -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. // It returns empty configuration if its not set. func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "GetBucketNotification") + ctx := newContext(r, w, "GetBucketNotification") vars := mux.Vars(r) bucketName := vars["bucket"] @@ -94,7 +94,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, // PutBucketNotificationHandler - This HTTP handler stores given notification configuration as per // http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html. func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "PutBucketNotification") + ctx := newContext(r, w, "PutBucketNotification") objectAPI := api.ObjectAPI() 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. // 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) { - ctx := newContext(r, "ListenBucketNotification") + ctx := newContext(r, w, "ListenBucketNotification") // Validate if bucket exists. objAPI := api.ObjectAPI() @@ -235,7 +235,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit 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.LogIf(ctx, err) writeErrorResponse(w, toAPIErrorCode(err), r.URL) diff --git a/cmd/bucket-policy-handlers.go b/cmd/bucket-policy-handlers.go index 72a57a8b1..c61a4b249 100644 --- a/cmd/bucket-policy-handlers.go +++ b/cmd/bucket-policy-handlers.go @@ -38,7 +38,7 @@ const ( // PutBucketPolicyHandler - This HTTP handler stores given bucket policy configuration as per // https://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "PutBucketPolicy") + ctx := newContext(r, w, "PutBucketPolicy") objAPI := api.ObjectAPI() if objAPI == nil { @@ -99,7 +99,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht // DeleteBucketPolicyHandler - This HTTP handler removes bucket policy configuration. func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "DeleteBucketPolicy") + ctx := newContext(r, w, "DeleteBucketPolicy") objAPI := api.ObjectAPI() if objAPI == nil { @@ -135,7 +135,7 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r // GetBucketPolicyHandler - This HTTP handler returns bucket policy configuration. func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "GetBucketPolicy") + ctx := newContext(r, w, "GetBucketPolicy") objAPI := api.ObjectAPI() if objAPI == nil { diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index fcf2ed7b5..c058d401e 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -723,6 +723,26 @@ func (l rateLimit) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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 { handler http.Handler } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 29c78604c..8274841d8 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -68,7 +68,7 @@ func setHeadGetRespHeaders(w http.ResponseWriter, reqParams url.Values) { // This implementation of the GET operation retrieves object. To use GET, // you must have READ access to the object. func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "GetObject") + ctx := newContext(r, w, "GetObject") var object, bucket string 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. func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "HeadObject") + ctx := newContext(r, w, "HeadObject") var object, bucket string 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 // while reading the object from another source. func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "CopyObject") + ctx := newContext(r, w, "CopyObject") vars := mux.Vars(r) 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. func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "PutObject") + ctx := newContext(r, w, "PutObject") objectAPI := api.ObjectAPI() if objectAPI == nil { @@ -845,7 +845,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // NewMultipartUploadHandler - New multipart upload. func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "NewMultipartUpload") + ctx := newContext(r, w, "NewMultipartUpload") var object, bucket string 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. func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "CopyObjectPart") + ctx := newContext(r, w, "CopyObjectPart") vars := mux.Vars(r) 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. func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "PutObjectPart") + ctx := newContext(r, w, "PutObjectPart") vars := mux.Vars(r) bucket := vars["bucket"] @@ -1330,7 +1330,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // AbortMultipartUploadHandler - Abort multipart upload func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "AbortMultipartUpload") + ctx := newContext(r, w, "AbortMultipartUpload") vars := mux.Vars(r) bucket := vars["bucket"] @@ -1369,7 +1369,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, // ListObjectPartsHandler - List object parts func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "ListObjectParts") + ctx := newContext(r, w, "ListObjectParts") vars := mux.Vars(r) bucket := vars["bucket"] @@ -1409,7 +1409,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht // CompleteMultipartUploadHandler - Complete multipart upload. func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "CompleteMultipartUpload") + ctx := newContext(r, w, "CompleteMultipartUpload") vars := mux.Vars(r) bucket := vars["bucket"] @@ -1518,7 +1518,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite // DeleteObjectHandler - delete an object func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := newContext(r, "DeleteObject") + ctx := newContext(r, w, "DeleteObject") vars := mux.Vars(r) bucket := vars["bucket"] diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index 4dd12b74e..91ae35cfd 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -263,7 +263,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), getGetObjectURL("", bucketName, "abcd"))), + expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), getGetObjectURL("", bucketName, "abcd"), "")), expectedRespStatus: http.StatusNotFound, }, // Test case - 3. @@ -287,7 +287,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidRange), getGetObjectURL("", bucketName, objectName))), + expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidRange), getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusRequestedRangeNotSatisfiable, }, // Test case - 5. @@ -313,7 +313,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: "Invalid-AccessID", secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), getGetObjectURL("", bucketName, objectName))), + expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusForbidden, }, // Test case - 7. @@ -326,7 +326,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName), - getGetObjectURL("", bucketName, "../../etc"))), + getGetObjectURL("", bucketName, "../../etc"), "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 8. @@ -339,7 +339,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), - "/"+bucketName+"/"+". ./. ./etc")), + "/"+bucketName+"/"+". ./. ./etc", "")), expectedRespStatus: http.StatusNotFound, }, // Test case - 9. @@ -352,7 +352,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName), - "/"+bucketName+"/"+". ./../etc")), + "/"+bucketName+"/"+". ./../etc", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 10. @@ -365,7 +365,7 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), - getGetObjectURL("", bucketName, "etc/path/proper/.../etc"))), + getGetObjectURL("", bucketName, "etc/path/proper/.../etc"), "")), expectedRespStatus: http.StatusNotFound, }, } @@ -2238,7 +2238,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})), - getGetObjectURL("", bucketName, objectName))), + getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 2. @@ -2253,7 +2253,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrMalformedXML), - getGetObjectURL("", bucketName, objectName))), + getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 3. @@ -2268,7 +2268,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidUploadID{UploadID: "abc"})), - getGetObjectURL("", bucketName, objectName))), + getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusNotFound, }, // Test case - 4. @@ -2283,7 +2283,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s expectedContent: encodeResponse(completeMultipartAPIError{int64(4), int64(5242880), 1, "e2fc714c4727ee9395f324cd2e7f331f", getAPIErrorResponse(getAPIError(toAPIErrorCode(PartTooSmall{PartNumber: 1})), - getGetObjectURL("", bucketName, objectName))}), + getGetObjectURL("", bucketName, objectName), "")}), expectedRespStatus: http.StatusBadRequest, }, // Test case - 5. @@ -2297,7 +2297,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})), - getGetObjectURL("", bucketName, objectName))), + getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 6. @@ -2312,7 +2312,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidPartOrder), - getGetObjectURL("", bucketName, objectName))), + getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 7. @@ -2327,7 +2327,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), - getGetObjectURL("", bucketName, objectName))), + getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusForbidden, }, // Test case - 8. diff --git a/cmd/routers.go b/cmd/routers.go index aa665c4c2..306dad881 100644 --- a/cmd/routers.go +++ b/cmd/routers.go @@ -47,6 +47,8 @@ func registerDistXLRouters(router *mux.Router, endpoints EndpointList) { // List of some generic handlers which are applied for all incoming requests. var globalHandlers = []HandlerFunc{ + // set x-amz-request-id header. + addrequestIDHeader, // set HTTP security headers such as Content-Security-Policy. addSecurityHeaders, // Forward path style requests to actual host in a bucket federated setup. diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index e5a26f1ca..cc4a77d9e 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -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`. - expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName))) + expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName), "")) // HEAD HTTTP request doesn't contain response body. 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`. expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrServerNotInitialized), - getGetObjectURL("", bucketName, objectName))) + getGetObjectURL("", bucketName, objectName), "")) // 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. diff --git a/cmd/utils.go b/cmd/utils.go index f5a5b95ce..904d00a91 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -331,7 +331,7 @@ func ceilFrac(numerator, denominator int64) (ceil int64) { } // 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) bucket := vars["bucket"] object := vars["object"] @@ -341,6 +341,7 @@ func newContext(r *http.Request, api string) context.Context { object = prefix } reqInfo := &logger.ReqInfo{ + RequestID: w.Header().Get(responseRequestIDKey), RemoteHost: handlers.GetSourceIP(r), UserAgent: r.Header.Get("user-agent"), API: api,