From 78444c3c6718d2f2e53217d622af59c2c461fca0 Mon Sep 17 00:00:00 2001 From: syumai Date: Sat, 29 Apr 2023 11:56:21 +0900 Subject: [PATCH] commonize ToJSResponse func --- cloudflare/cache/method.go | 18 +----------------- handler.go | 3 ++- internal/jshttp/response.go | 20 ++++++++++++-------- internal/jshttp/responsewriter.go | 7 +++++++ 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/cloudflare/cache/method.go b/cloudflare/cache/method.go index c64b767..1476944 100644 --- a/cloudflare/cache/method.go +++ b/cloudflare/cache/method.go @@ -9,22 +9,6 @@ import ( "github.com/syumai/workers/internal/jsutil" ) -// toJSResponse converts *http.Response to JS Response -func toJSResponse(res *http.Response) js.Value { - status := res.StatusCode - if status == 0 { - status = http.StatusOK - } - respInit := jsutil.NewObject() - respInit.Set("status", status) - respInit.Set("statusText", http.StatusText(status)) - respInit.Set("headers", jshttp.ToJSHeader(res.Header)) - - readableStream := jsutil.ConvertReaderToReadableStream(res.Body) - - return jsutil.ResponseClass.New(readableStream, respInit) -} - // Put attempts to add a response to the cache, using the given request as the key. // Returns an error for the following conditions // - the request passed is a method other than GET. @@ -32,7 +16,7 @@ func toJSResponse(res *http.Response) js.Value { // - Cache-Control instructs not to cache or if the response is too large. // docs: https://developers.cloudflare.com/workers/runtime-apis/cache/#put func (c *Cache) Put(req *http.Request, res *http.Response) error { - _, err := jsutil.AwaitPromise(c.instance.Call("put", jshttp.ToJSRequest(req), toJSResponse(res))) + _, err := jsutil.AwaitPromise(c.instance.Call("put", jshttp.ToJSRequest(req), jshttp.ToJSResponse(res))) if err != nil { return err } diff --git a/handler.go b/handler.go index ba114c5..d07bc1e 100644 --- a/handler.go +++ b/handler.go @@ -67,7 +67,8 @@ func handleRequest(reqObj js.Value, runtimeCtxObj js.Value) (js.Value, error) { defer writer.Close() httpHandler.ServeHTTP(w, req) }() - return jshttp.ToJSResponse(w) + <-w.ReadyCh + return w.ToJSResponse(), nil } // Server serves http.Handler on Cloudflare Workers. diff --git a/internal/jshttp/response.go b/internal/jshttp/response.go index cc56023..edffb90 100644 --- a/internal/jshttp/response.go +++ b/internal/jshttp/response.go @@ -31,24 +31,28 @@ func ToResponse(res js.Value) (*http.Response, error) { }, nil } -// ToJSResponse converts *http.Response to JavaScript sides Response. +// ToJSResponse converts *http.Response to JavaScript sides Response class object. +func ToJSResponse(res *http.Response) js.Value { + return newJSResponse(res.StatusCode, res.Header, res.Body) +} + +// newJSResponse creates JavaScript sides Response class object. // - Response: https://developer.mozilla.org/docs/Web/API/Response -func ToJSResponse(w *ResponseWriterBuffer) (js.Value, error) { - <-w.ReadyCh // wait until ready - status := w.StatusCode +func newJSResponse(statusCode int, headers http.Header, body io.ReadCloser) js.Value { + status := statusCode if status == 0 { status = http.StatusOK } respInit := jsutil.NewObject() respInit.Set("status", status) respInit.Set("statusText", http.StatusText(status)) - respInit.Set("headers", ToJSHeader(w.Header())) + respInit.Set("headers", ToJSHeader(headers)) if status == http.StatusSwitchingProtocols || status == http.StatusNoContent || status == http.StatusResetContent || status == http.StatusNotModified { - return jsutil.ResponseClass.New(jsutil.Null, respInit), nil + return jsutil.ResponseClass.New(jsutil.Null, respInit) } - readableStream := jsutil.ConvertReaderToReadableStream(w.Reader) - return jsutil.ResponseClass.New(readableStream, respInit), nil + readableStream := jsutil.ConvertReaderToReadableStream(body) + return jsutil.ResponseClass.New(readableStream, respInit) } diff --git a/internal/jshttp/responsewriter.go b/internal/jshttp/responsewriter.go index b58e0f6..d1944d2 100644 --- a/internal/jshttp/responsewriter.go +++ b/internal/jshttp/responsewriter.go @@ -4,6 +4,7 @@ import ( "io" "net/http" "sync" + "syscall/js" ) type ResponseWriterBuffer struct { @@ -36,3 +37,9 @@ func (w *ResponseWriterBuffer) Header() http.Header { func (w *ResponseWriterBuffer) WriteHeader(statusCode int) { w.StatusCode = statusCode } + +// ToJSResponse converts *ResponseWriterBuffer to JavaScript sides Response. +// - Response: https://developer.mozilla.org/docs/Web/API/Response +func (w *ResponseWriterBuffer) ToJSResponse() js.Value { + return newJSResponse(w.StatusCode, w.HeaderValue, w.Reader) +}