From 94f29ebdf119a5cac32acbe22a80fc149fe787f8 Mon Sep 17 00:00:00 2001 From: syumai Date: Thu, 1 Feb 2024 09:33:52 +0900 Subject: [PATCH] move fetch's stream logic to jshttp.ToStreamResponse --- cloudflare/fetch/bind.go | 16 +--------------- internal/jshttp/response.go | 34 +++++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/cloudflare/fetch/bind.go b/cloudflare/fetch/bind.go index 28c08e5..72e69dd 100644 --- a/cloudflare/fetch/bind.go +++ b/cloudflare/fetch/bind.go @@ -3,7 +3,6 @@ package fetch import ( "errors" "net/http" - "strconv" "syscall/js" "github.com/syumai/workers/internal/jshttp" @@ -31,18 +30,5 @@ func fetch(namespace js.Value, req *http.Request, init *RequestInit) (*http.Resp return nil, err } - // Create TransformStream - ts := js.Global().Get("IdentityTransformStream").New() - readable := ts.Get("readable") - writable := ts.Get("writable") - jsRes.Get("body").Call("pipeTo", writable) - - // Create response - res := new(http.Response) - res.StatusCode = jsRes.Get("status").Int() - res.Status = strconv.Itoa(res.StatusCode) + " " + jsRes.Get("statusText").String() - res.Header = jshttp.ToHeader(jsRes.Get("headers")) - res.Body = jsutil.ConvertReadableStreamToReadCloser(readable) - - return res, nil + return jshttp.ToStreamResponse(jsRes) } diff --git a/internal/jshttp/response.go b/internal/jshttp/response.go index 3f48c34..407ee37 100644 --- a/internal/jshttp/response.go +++ b/internal/jshttp/response.go @@ -9,15 +9,8 @@ import ( "github.com/syumai/workers/internal/jsutil" ) -// ToResponse converts JavaScript sides Response to *http.Response. -// - Response: https://developer.mozilla.org/docs/Web/API/Response -func ToResponse(res js.Value) (*http.Response, error) { +func toResponse(res js.Value, body io.ReadCloser) (*http.Response, error) { status := res.Get("status").Int() - promise := res.Call("blob") - blob, err := jsutil.AwaitPromise(promise) - if err != nil { - return nil, err - } header := ToHeader(res.Get("headers")) contentLength, _ := strconv.ParseInt(header.Get("Content-Length"), 10, 64) @@ -25,11 +18,34 @@ func ToResponse(res js.Value) (*http.Response, error) { Status: strconv.Itoa(status) + " " + res.Get("statusText").String(), StatusCode: status, Header: header, - Body: jsutil.ConvertReadableStreamToReadCloser(blob.Call("stream")), + Body: body, ContentLength: contentLength, }, nil } +// ToResponse converts JavaScript sides Response to *http.Response. +// - Response: https://developer.mozilla.org/docs/Web/API/Response +func ToResponse(res js.Value) (*http.Response, error) { + promise := res.Call("blob") + blob, err := jsutil.AwaitPromise(promise) + if err != nil { + return nil, err + } + body := jsutil.ConvertReadableStreamToReadCloser(blob.Call("stream")) + return toResponse(res, body) +} + +// ToStreamResponse pipes JavaScript sides Response to TransformStream and converts to *http.Response. +// - see: https://developers.cloudflare.com/workers/runtime-apis/streams/ +func ToStreamResponse(res js.Value) (*http.Response, error) { + ts := js.Global().Get("IdentityTransformStream").New() + readable := ts.Get("readable") + writable := ts.Get("writable") + res.Get("body").Call("pipeTo", writable) + body := jsutil.ConvertReadableStreamToReadCloser(readable) + return toResponse(res, body) +} + // 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, nil)