Merge pull request #93 from aki-0421/avoid-memory-error

Support stream in fetch pkg
This commit is contained in:
syumai 2024-02-01 09:22:46 +09:00 committed by GitHub
commit d31baa38b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 91 additions and 3 deletions

View File

@ -0,0 +1,3 @@
build
node_modules
.wrangler

View File

@ -0,0 +1,12 @@
.PHONY: dev
dev:
wrangler dev
.PHONY: build
build:
go run ../../cmd/workers-assets-gen
tinygo build -o ./build/app.wasm -target wasm -no-debug ./...
.PHONY: deploy
deploy:
wrangler deploy

View File

@ -0,0 +1,18 @@
# stream-large-file
## Development
### Requirements
This project requires these tools to be installed globally.
* wrangler
* tinygo
### Commands
```
make dev # run dev server
make build # build Go Wasm binary
make deploy # deploy worker
```

View File

@ -0,0 +1,7 @@
module github.com/syumai/workers/_examples/stream
go 1.21.3
require github.com/syumai/workers v0.0.0
replace github.com/syumai/workers => ../../

View File

@ -0,0 +1,2 @@
github.com/syumai/workers v0.1.0 h1:z5QfQR2X+PCKzom7RodpI5J4D5YF7NT7Qwzb9AM9dgY=
github.com/syumai/workers v0.1.0/go.mod h1:alXIDhTyeTwSzh0ZgQ3cb9HQPyyYfIejupE4Z3efr14=

View File

@ -0,0 +1,26 @@
package main
import (
"fmt"
"io"
"net/http"
"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare/fetch"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
cli := fetch.NewClient().HTTPClient(fetch.RedirectModeFollow)
resp, err := cli.Get("http://tyo.download.datapacket.com/1000mb.bin")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "err: %v", err)
return
}
defer resp.Body.Close()
io.Copy(w, resp.Body)
})
workers.Serve(nil)
}

View File

@ -0,0 +1,6 @@
name = "stream-large-file"
main = "./build/worker.mjs"
compatibility_date = "2023-12-01"
[build]
command = "make build"

View File

@ -3,6 +3,7 @@ package fetch
import (
"errors"
"net/http"
"strconv"
"syscall/js"
"github.com/syumai/workers/internal/jshttp"
@ -15,8 +16,8 @@ func fetch(namespace js.Value, req *http.Request, init *RequestInit) (*http.Resp
if namespace.IsUndefined() {
return nil, errors.New("fetch function not found")
}
fetchObj := namespace.Get("fetch")
promise := fetchObj.Invoke(
fetchFunc := namespace.Get("fetch")
promise := fetchFunc.Invoke(
// The Request object to fetch.
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request
jshttp.ToJSRequest(req),
@ -30,5 +31,18 @@ func fetch(namespace js.Value, req *http.Request, init *RequestInit) (*http.Resp
return nil, err
}
return jshttp.ToResponse(jsRes)
// 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
}