feat: uses ReadableStream for request (#16)

This commit is contained in:
Nicolas Lepage 2024-10-14 22:23:22 +02:00 committed by GitHub
parent 3220c94fa5
commit b7e5adfd23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 97 additions and 24 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,85 @@
package readablestream
import (
"io"
promise "github.com/nlepage/go-js-promise"
"github.com/nlepage/go-wasm-http-server/internal/safejs"
)
type Reader struct {
value safejs.Value
buf []byte
off int
}
var _ io.Reader = (*Reader)(nil)
func NewReader(r safejs.Value) *Reader {
return &Reader{
value: r,
}
}
func (r *Reader) Read(p []byte) (int, error) {
if r.off < len(r.buf) {
n := copy(p, r.buf[r.off:])
r.off += n
return n, nil
}
r.off = 0
pRes, err := r.value.Call("read")
if err != nil {
return 0, err
}
ures, err := promise.Await(safejs.Unsafe(pRes))
if err != nil {
return 0, err
}
res := safejs.Safe(ures)
done, err := res.GetBool("done")
if err != nil {
return 0, err
}
if done {
return 0, io.EOF
}
value, err := res.Get("value")
if err != nil {
return 0, err
}
l, err := value.GetInt("length")
if err != nil {
return 0, err
}
if cap(r.buf) < l {
r.buf = make([]byte, l)
}
if len(r.buf) < cap(r.buf) {
r.buf = r.buf[:cap(r.buf)]
}
n, err := safejs.CopyBytesToGo(r.buf, value)
if err != nil {
return 0, err
}
r.buf = r.buf[:n]
n = copy(p, r.buf[r.off:])
r.off += n
return n, nil
}

View File

@ -1,49 +1,34 @@
package wasmhttp package wasmhttp
import ( import (
"bytes"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"syscall/js" "syscall/js"
promise "github.com/nlepage/go-js-promise" "github.com/nlepage/go-wasm-http-server/internal/readablestream"
"github.com/nlepage/go-wasm-http-server/internal/jstype"
"github.com/nlepage/go-wasm-http-server/internal/safejs" "github.com/nlepage/go-wasm-http-server/internal/safejs"
) )
// Request builds and returns the equivalent http.Request // Request builds and returns the equivalent http.Request
func Request(ur js.Value) (*http.Request, error) { func Request(uvalue js.Value) (*http.Request, error) {
r := safejs.Safe(ur) value := safejs.Safe(uvalue)
ab, err := r.Call("arrayBuffer") body, err := value.Get("body")
if err != nil { if err != nil {
return nil, err return nil, err
} }
u8a, err := jstype.Uint8Array.New(promise.Await(safejs.Unsafe(ab))) r, err := body.Call("getReader")
if err != nil { if err != nil {
return nil, err return nil, err
} }
l, err := u8a.GetInt("length") method, err := value.GetString("method")
if err != nil { if err != nil {
return nil, err return nil, err
} }
b := make([]byte, l) url, err := value.GetString("url")
_, err = safejs.CopyBytesToGo(b, u8a)
if err != nil {
return nil, err
}
method, err := r.GetString("method")
if err != nil {
return nil, err
}
url, err := r.GetString("url")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -51,15 +36,18 @@ func Request(ur js.Value) (*http.Request, error) {
req := httptest.NewRequest( req := httptest.NewRequest(
method, method,
url, url,
bytes.NewReader(b), readablestream.NewReader(r),
) )
headers, err := r.Get("headers") headers, err := value.Get("headers")
if err != nil { if err != nil {
return nil, err return nil, err
} }
headersIt, err := headers.Call("entries") headersIt, err := headers.Call("entries")
if err != nil {
return nil, err
}
for { for {
e, err := headersIt.Call("next") e, err := headersIt.Call("next")
if err != nil { if err != nil {