Add redirect mode

This commit is contained in:
aki-0421 2023-05-28 13:04:35 +09:00
parent feafcd580a
commit ed546fec09
No known key found for this signature in database
GPG Key ID: 64A8CF6D437D166A
6 changed files with 78 additions and 34 deletions

View File

@ -11,23 +11,21 @@ import (
// 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) {
func fetch(namespace js.Value, req *http.Request, init *RequestInit) (*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(),
init.ToJS(),
)
jsRes, err := jsutil.AwaitPromise(promise)
if err != nil {
return nil, err
}
return jshttp.ToResponse(jsRes)
}

View File

@ -21,10 +21,11 @@ func (c *Client) applyOptions(opts []ClientOption) {
}
// HTTPClient returns *http.Client.
func (c *Client) HTTPClient() *http.Client {
func (c *Client) HTTPClient(redirect RedirectMode) *http.Client {
return &http.Client{
Transport: &transport{
namespace: c.namespace,
redirect: redirect,
},
}
}

View File

@ -1,10 +1,30 @@
package fetch
import (
"context"
"io"
"net/http"
)
// Do sends an HTTP request and returns an HTTP response
func (c *Client) Do(req *Request) (*http.Response, error) {
return fetch(c.namespace, req.Request)
// Request represents an HTTP request and is part of the Fetch API.
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request/
type Request struct {
*http.Request
}
// NewRequest returns new Request given a method, URL, and optional body
func NewRequest(ctx context.Context, method string, url string, body io.Reader) (*Request, error) {
req, err := http.NewRequestWithContext(ctx, method, url, body)
if err != nil {
return nil, err
}
return &Request{
Request: req,
}, nil
}
// Do sends an HTTP request and returns an HTTP response
func (c *Client) Do(req *Request, init *RequestInit) (*http.Response, error) {
return fetch(c.namespace, req.Request, init)
}

View File

@ -0,0 +1,47 @@
package fetch
import (
"syscall/js"
"github.com/syumai/workers/internal/jsutil"
)
// RedirectMode represents the redirect mode of a fetch() request.
type RedirectMode string
var (
RedirectModeFollow RedirectMode = "follow"
RedirectModeError RedirectMode = "error"
RedirectModeManual RedirectMode = "manual"
)
func (mode RedirectMode) IsValid() bool {
return mode == RedirectModeFollow || mode == RedirectModeError || mode == RedirectModeManual
}
func (mode RedirectMode) String() string {
return string(mode)
}
// RequestInit represents the options passed to a fetch() request.
type RequestInit struct {
CF *RequestInitCF
Redirect RedirectMode
}
// ToJS converts RequestInit to JS object.
func (init *RequestInit) ToJS() js.Value {
if init == nil {
return js.Undefined()
}
obj := jsutil.NewObject()
if init.Redirect.IsValid() {
obj.Set("redirect", init.Redirect.String())
}
return obj
}
// RequestInitCF represents the Cloudflare-specific options passed to a fetch() request.
type RequestInitCF struct {
/* TODO: implement */
}

View File

@ -1,25 +0,0 @@
package fetch
import (
"context"
"io"
"net/http"
)
// Request represents an HTTP request and is part of the Fetch API.
// Docs: https://developers.cloudflare.com/workers/runtime-apis/request/
type Request struct {
*http.Request
}
// NewRequest returns new Request given a method, URL, and optional body
func NewRequest(ctx context.Context, method string, url string, body io.Reader) (*Request, error) {
req, err := http.NewRequestWithContext(ctx, method, url, body)
if err != nil {
return nil, err
}
return &Request{
Request: req,
}, nil
}

View File

@ -9,9 +9,12 @@ import (
type transport struct {
// namespace - Objects that Fetch API belongs to. Default is Global
namespace js.Value
redirect RedirectMode
}
// RoundTrip replaces http.DefaultTransport.RoundTrip to use cloudflare fetch
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
return fetch(t.namespace, req)
return fetch(t.namespace, req, &RequestInit{
Redirect: t.redirect,
})
}