diff --git a/api/admin/api.go b/api/admin/api.go index 82c278d..1eb5ea2 100644 --- a/api/admin/api.go +++ b/api/admin/api.go @@ -198,6 +198,9 @@ func (a *API) executeRequest(ctx context.Context, method string, path interface{ req = req.WithContext(ctx) + if a.Config.API.BeforeSend != nil { + a.Config.API.BeforeSend(req) + } resp, err := a.Client.Do(req) if err != nil { return nil, err diff --git a/api/admin/api_acceptance_test.go b/api/admin/api_acceptance_test.go index a7e7f6b..10f555a 100644 --- a/api/admin/api_acceptance_test.go +++ b/api/admin/api_acceptance_test.go @@ -5,12 +5,14 @@ package admin_test import ( "context" "fmt" + "net/http" + "reflect" + "testing" + "github.com/cloudinary/cloudinary-go/v2/api" "github.com/cloudinary/cloudinary-go/v2/api/admin" "github.com/cloudinary/cloudinary-go/v2/config" "github.com/cloudinary/cloudinary-go/v2/internal/cldtest" - "reflect" - "testing" ) var oAuthTokenConfig, _ = config.NewFromOAuthToken(cldtest.CloudName, "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI4") @@ -148,10 +150,34 @@ func getAuthorizationTestCases() []AdminAPIAcceptanceTestCase { } } +// Acceptance test cases for before send +func getBeforeSendTestCases() []AdminAPIAcceptanceTestCase { + return []AdminAPIAcceptanceTestCase{ + { + Name: "Ping Test Before Send", + RequestTest: func(api *admin.API, ctx context.Context) (interface{}, error) { + api.Config.API.BeforeSend = func(req *http.Request) { + req.Header.Set("X-Test-Header", "test") + } + return api.Ping(ctx) + }, + ResponseTest: func(response interface{}, t *testing.T) {}, + ExpectedRequest: cldtest.ExpectedRequestParams{ + Method: "GET", + URI: "/ping", + Headers: &map[string]string{"X-Test-Header": "test"}, + }, + JsonResponse: "{\"status\": \"OK\"}", + ExpectedCallCount: 1, + }, + } +} + // Run tests func TestAdminAPI_Acceptance(t *testing.T) { t.Parallel() testAdminAPIByTestCases(getPingTestCases(), t) testAdminAPIByTestCases(getUserAgentTestCases(), t) testAdminAPIByTestCases(getAuthorizationTestCases(), t) + testAdminAPIByTestCases(getBeforeSendTestCases(), t) } diff --git a/api/uploader/upload.go b/api/uploader/upload.go index 9c71fe9..68cb4d9 100644 --- a/api/uploader/upload.go +++ b/api/uploader/upload.go @@ -350,6 +350,9 @@ func (u *API) postBody(ctx context.Context, urlPath interface{}, bodyReader io.R req = req.WithContext(ctx) + if u.Config.API.BeforeSend != nil { + u.Config.API.BeforeSend(req) + } resp, err := u.Client.Do(req) if err != nil { return nil, err diff --git a/api/uploader/upload_acceptance_test.go b/api/uploader/upload_acceptance_test.go index 705b1f2..7939da7 100644 --- a/api/uploader/upload_acceptance_test.go +++ b/api/uploader/upload_acceptance_test.go @@ -5,12 +5,14 @@ package uploader_test import ( "context" "fmt" + "net/http" + "testing" + "github.com/cloudinary/cloudinary-go/v2/api" "github.com/cloudinary/cloudinary-go/v2/api/uploader" "github.com/cloudinary/cloudinary-go/v2/config" "github.com/cloudinary/cloudinary-go/v2/internal/cldtest" "github.com/cloudinary/cloudinary-go/v2/internal/signature" - "testing" ) var oAuthTokenConfig, _ = config.NewFromOAuthToken(cldtest.CloudName, "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI4") @@ -186,6 +188,35 @@ func getUploadConfigTestCases() []UploadAPIAcceptanceTestCase { } } +// Acceptance test cases for before send +func getBeforeSendTestCases() []UploadAPIAcceptanceTestCase { + body := "file=data%3Aimage%2Fgif%3Bbase64%2CR0lGODlhAQABAIAAAAAAAP%2F%2F%2FyH5BAEAAAAALAAAAAABAAEAAAIBRAA7" + + "×tamp=123456789&unsigned=true" + + return []UploadAPIAcceptanceTestCase{ + { + Name: "Upload Test Before Send", + RequestTest: func(uploadAPI *uploader.API, ctx context.Context) (interface{}, error) { + uploadAPI.Config.API.BeforeSend = func(req *http.Request) { + req.Header.Set("X-Test-Header", "test") + } + return uploadAPI.Upload(ctx, cldtest.Base64Image, uploader.UploadParams{ + Timestamp: 123456789, + Unsigned: api.Bool(true), + }) + }, + ResponseTest: func(response interface{}, t *testing.T) {}, + ExpectedRequest: cldtest.ExpectedRequestParams{ + Method: "POST", + URI: "/auto/upload", + Body: &body, + Headers: &map[string]string{"X-Test-Header": "test"}, + }, + ExpectedCallCount: 1, + }, + } +} + // Run tests func TestUploadAPI_Acceptance(t *testing.T) { t.Parallel() @@ -195,4 +226,5 @@ func TestUploadAPI_Acceptance(t *testing.T) { testUploadAPIByTestCases(getBooleanValuesTestCases(), t) testUploadAPIByTestCases(getVariousValuesTestCases(), t) testUploadAPIByTestCases(getUploadConfigTestCases(), t) + testUploadAPIByTestCases(getBeforeSendTestCases(), t) } diff --git a/config/api.go b/config/api.go index 66ca813..c891c9d 100644 --- a/config/api.go +++ b/config/api.go @@ -1,9 +1,12 @@ package config +import "net/http" + // API defines the configuration for making requests to the Cloudinary API. type API struct { UploadPrefix string `schema:"upload_prefix" default:"https://api.cloudinary.com"` Timeout int64 `schema:"timeout" default:"60"` // seconds UploadTimeout int64 `schema:"upload_timeout"` ChunkSize int64 `schema:"chunk_size" default:"20000000"` // bytes + BeforeSend func(req *http.Request) }