diff --git a/go.mod b/go.mod index 6f7c4fe2c2..4a53ce5c6b 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/google/go-querystring v1.1.0 github.com/hashicorp/go-retryablehttp v0.7.1 github.com/olekukonko/tablewriter v0.0.5 + github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.1 github.com/urfave/cli/v2 v2.23.5 golang.org/x/net v0.0.0-20220722155237-a158d28d115b diff --git a/go.sum b/go.sum index 310708a4bf..0e9a72190e 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= diff --git a/workers.go b/workers.go index cda92a03fc..95d489580d 100644 --- a/workers.go +++ b/workers.go @@ -38,6 +38,8 @@ type WorkerScriptParams struct { // Compatibility options CompatibilityFlags []string CompatibilityDate string + + Logpush *bool } // WorkerRoute is used to map traffic matching a URL pattern to a workers @@ -711,7 +713,7 @@ func (api *API) ListWorkerScripts(ctx context.Context) (WorkerListResponse, erro // // API reference: https://api.cloudflare.com/#worker-script-upload-worker func (api *API) UploadWorker(ctx context.Context, requestParams *WorkerRequestParams, params *WorkerScriptParams) (WorkerScriptResponse, error) { - if params.Module { + if params.Module || params.Logpush != nil { return api.UploadWorkerWithBindings(ctx, requestParams, params) } @@ -807,10 +809,12 @@ func formatMultipartBody(params *WorkerScriptParams) (string, []byte, error) { Bindings []workerBindingMeta `json:"bindings"` CompatibilityFlags []string `json:"compatibility_flags"` CompatibilityDate string `json:"compatibility_date"` + Logpush *bool `json:"logpush,omitempty"` }{ Bindings: make([]workerBindingMeta, 0, len(params.Bindings)), CompatibilityFlags: params.CompatibilityFlags, CompatibilityDate: params.CompatibilityDate, + Logpush: params.Logpush, } if params.Module { diff --git a/workers_test.go b/workers_test.go index 09cffe699f..a3770b3df7 100644 --- a/workers_test.go +++ b/workers_test.go @@ -26,6 +26,9 @@ const ( "result": { "script": "addEventListener('fetch', event => {\n event.passThroughOnException()\n event.respondWith(handleRequest(event.request))\n})\n\nasync function handleRequest(request) {\n return fetch(request)\n}", "etag": "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + "etag_bypass": "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a.bypass", + "compatibility_flags": ["streams_enable_constructors"], + "compatibility_date": "2021-12-10", "size": 191, "modified_on": "2018-06-09T15:17:01.989141Z" }, @@ -48,18 +51,6 @@ const ( "errors": [], "messages": [] }` - - uploadWorkerModuleResponseData = `{ - "result": { - "script": "export default {\n async fetch(request, env, event) {\n event.passThroughOnException()\n return fetch(request)\n }\n}", - "etag": "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", - "size": 191, - "modified_on": "2018-06-09T15:17:01.989141Z" - }, - "success": true, - "errors": [], - "messages": [] -}` updateWorkerRouteResponse = `{ "result": { "id": "e7a57d8746e74ae49c25994dadb421b1", @@ -291,8 +282,6 @@ export default { var ( successResponse = Response{Success: true, Errors: []ResponseInfo{}, Messages: []ResponseInfo{}} - workerScript = "addEventListener('fetch', event => {\n event.passThroughOnException()\nevent.respondWith(handleRequest(event.request))\n})\n\nasync function handleRequest(request) {\n return fetch(request)\n}" - workerModuleScript = "export default {\n async fetch(request, env, event) {\n event.passThroughOnException()\n return fetch(request)\n }\n}" deleteWorkerRouteResponseData = createWorkerRouteResponse attachWorkerToDomainResponse = fmt.Sprintf(`{ "result": { @@ -352,26 +341,12 @@ func getFileDetails(r *http.Request, key string) (*multipart.FileHeader, error) return nil, fmt.Errorf("no value found for key %v", key) } -func getFileDetails(r *http.Request, key string) (*multipart.FileHeader, error) { - err := r.ParseMultipartForm(1024 * 1024) - if err != nil { - return nil, err - } - - fileHeaders := r.MultipartForm.File[key] - - if len(fileHeaders) > 0 { - return fileHeaders[0], nil - } - - return nil, fmt.Errorf("no value found for key %v", key) -} - type multipartUpload struct { Script string BindingMeta map[string]workerBindingMeta CompatibilityFlags []string CompatibilityDate string + Logpush *bool } func parseMultipartUpload(r *http.Request) (multipartUpload, error) { @@ -387,6 +362,7 @@ func parseMultipartUpload(r *http.Request) (multipartUpload, error) { Bindings []workerBindingMeta `json:"bindings"` CompatibilityFlags []string `json:"compatibility_flags"` CompatibilityDate string `json:"compatibility_date"` + Logpush *bool `json:"logpush,omitempty"` } err = json.Unmarshal(mdBytes, &metadata) if err != nil { @@ -417,6 +393,7 @@ func parseMultipartUpload(r *http.Request) (multipartUpload, error) { BindingMeta: bindingMeta, CompatibilityFlags: metadata.CompatibilityFlags, CompatibilityDate: metadata.CompatibilityDate, + Logpush: metadata.Logpush, }, nil } @@ -628,9 +605,12 @@ func TestWorkers_UploadWorkerAsModule(t *testing.T) { WorkerScript{ Script: workerModuleScript, WorkerMetaData: WorkerMetaData{ - ETAG: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", - Size: 191, - ModifiedOn: formattedTime, + ETAG: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + ETAGBypass: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a.bypass", + CompatibiltyDate: "2021-12-10", + CompatibiltyFlags: []string{"streams_enable_constructors"}, + Size: 191, + ModifiedOn: formattedTime, }, }} if assert.NoError(t, err) { @@ -1066,6 +1046,44 @@ func TestWorkers_UploadWorkerWithServiceBinding(t *testing.T) { assert.NoError(t, err) } +func TestWorkers_UploadWorkerWithLogpush(t *testing.T) { + setup(UsingAccount("foo")) + defer teardown() + + t.Log("testing started") + + mux.HandleFunc("/accounts/foo/workers/scripts/bar", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) + mpUpload, err := parseMultipartUpload(r) + assert.NoError(t, err) + + expected := true + assert.Equal(t, &expected, mpUpload.Logpush) + + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, uploadWorkerResponseData) + }) + res, err := client.UploadWorker(context.Background(), &WorkerRequestParams{ScriptName: "bar"}, &WorkerScriptParams{Script: workerScript, Logpush: BoolPtr(true)}) + formattedTime, _ := time.Parse(time.RFC3339Nano, "2018-06-09T15:17:01.989141Z") + want := WorkerScriptResponse{ + successResponse, + false, + WorkerScript{ + Script: workerScript, + WorkerMetaData: WorkerMetaData{ + ETAG: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a", + ETAGBypass: "279cf40d86d70b82f6cd3ba90a646b3ad995912da446836d7371c21c6a43977a.bypass", + CompatibiltyDate: "2021-12-10", + CompatibiltyFlags: []string{"streams_enable_constructors"}, + Size: 191, + ModifiedOn: formattedTime, + }, + }} + if assert.NoError(t, err) { + assert.Equal(t, want, res) + } +} + func TestWorkers_UploadWorkerWithCompatibilityFlags(t *testing.T) { setup(UsingAccount("foo")) defer teardown()