mirror of
https://github.com/syumai/workers.git
synced 2025-03-10 17:29:11 +00:00
Merge pull request #31 from aki-0421/fetch-transport
Add ability to use fetch as a http.Client
This commit is contained in:
commit
2609f2a76f
33
cloudflare/fetch/bind.go
Normal file
33
cloudflare/fetch/bind.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package fetch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"github.com/syumai/workers/internal/jshttp"
|
||||||
|
"github.com/syumai/workers/internal/jsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fetch is a function that reproduces cloudflare fetch.
|
||||||
|
// Docs: https://developers.cloudflare.com/workers/runtime-apis/fetch/
|
||||||
|
func fetch(namespace js.Value, req *http.Request /* TO DO: options here */) (*http.Response, error) {
|
||||||
|
if namespace.IsUndefined() {
|
||||||
|
return nil, errors.New("fetch function not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
promise := namespace.Call("fetch",
|
||||||
|
// The Request object to fetch.
|
||||||
|
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request
|
||||||
|
jshttp.ToJSRequest(req),
|
||||||
|
// The content of the request.
|
||||||
|
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request#requestinit
|
||||||
|
jsutil.NewObject(),
|
||||||
|
)
|
||||||
|
jsRes, err := jsutil.AwaitPromise(promise)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return jshttp.ToResponse(jsRes)
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package fetch
|
package fetch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/syumai/workers/internal/jsutil"
|
"github.com/syumai/workers/internal/jsutil"
|
||||||
@ -19,6 +20,15 @@ func (c *Client) applyOptions(opts []ClientOption) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTPClient returns *http.Client.
|
||||||
|
func (c *Client) HTTPClient() *http.Client {
|
||||||
|
return &http.Client{
|
||||||
|
Transport: &transport{
|
||||||
|
namespace: c.namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ClientOption is a type that represents an optional function.
|
// ClientOption is a type that represents an optional function.
|
||||||
type ClientOption func(*Client)
|
type ClientOption func(*Client)
|
||||||
|
|
||||||
|
@ -2,21 +2,9 @@ package fetch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/syumai/workers/internal/jshttp"
|
|
||||||
"github.com/syumai/workers/internal/jsutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Do sends an HTTP request and returns an HTTP response
|
// Do sends an HTTP request and returns an HTTP response
|
||||||
func (c *Client) Do(req *Request) (*http.Response, error) {
|
func (c *Client) Do(req *Request) (*http.Response, error) {
|
||||||
jsReq := jshttp.ToJSRequest(req.Request)
|
return fetch(c.namespace, req.Request)
|
||||||
|
|
||||||
init := jsutil.NewObject()
|
|
||||||
promise := c.namespace.Call("fetch", jsReq, init)
|
|
||||||
jsRes, err := jsutil.AwaitPromise(promise)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return jshttp.ToResponse(jsRes)
|
|
||||||
}
|
}
|
||||||
|
17
cloudflare/fetch/transport.go
Normal file
17
cloudflare/fetch/transport.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package fetch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
// transport is an implementation of http.RoundTripper
|
||||||
|
type transport struct {
|
||||||
|
// namespace - Objects that Fetch API belongs to. Default is Global
|
||||||
|
namespace js.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip replaces http.DefaultTransport.RoundTrip to use cloudflare fetch
|
||||||
|
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
return fetch(t.namespace, req)
|
||||||
|
}
|
@ -5,7 +5,8 @@ dev:
|
|||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
tinygo build -o ./dist/app.wasm -target wasm ./...
|
#tinygo build -o ./dist/app.wasm -target wasm ./...
|
||||||
|
tinygo build -o ./dist/app.wasm -target wasm -no-debug ./...
|
||||||
|
|
||||||
.PHONY: publish
|
.PHONY: publish
|
||||||
publish:
|
publish:
|
||||||
|
@ -13,17 +13,11 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
|
bind := cloudflare.GetBinding(ctx, "hello")
|
||||||
|
fc := fetch.NewClient(fetch.WithBinding(bind))
|
||||||
|
|
||||||
obj := cloudflare.GetBinding(ctx, "hello")
|
hc := fc.HTTPClient()
|
||||||
cli := fetch.NewClient(fetch.WithBinding(obj))
|
res, err := hc.Do(req)
|
||||||
r, err := fetch.NewRequest(ctx, http.MethodGet, req.URL.String(), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := cli.Do(r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user