diff --git a/docs/hello-sse/api.wasm b/docs/hello-sse/api.wasm index dbd4ba5..1e8eeac 100755 Binary files a/docs/hello-sse/api.wasm and b/docs/hello-sse/api.wasm differ diff --git a/docs/hello-state/api.wasm b/docs/hello-state/api.wasm index e1cbdc5..e77fd53 100755 Binary files a/docs/hello-state/api.wasm and b/docs/hello-state/api.wasm differ diff --git a/docs/hello/api.wasm b/docs/hello/api.wasm index d21eaf1..aab5867 100755 Binary files a/docs/hello/api.wasm and b/docs/hello/api.wasm differ diff --git a/internal/readablestream/reader.go b/internal/readablestream/reader.go new file mode 100644 index 0000000..f56c950 --- /dev/null +++ b/internal/readablestream/reader.go @@ -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 +} diff --git a/internal/readablestream/readable_stream.go b/internal/readablestream/writer.go similarity index 100% rename from internal/readablestream/readable_stream.go rename to internal/readablestream/writer.go diff --git a/request.go b/request.go index b653bc3..36357e6 100644 --- a/request.go +++ b/request.go @@ -1,49 +1,34 @@ package wasmhttp import ( - "bytes" "net/http" "net/http/httptest" "syscall/js" - promise "github.com/nlepage/go-js-promise" - - "github.com/nlepage/go-wasm-http-server/internal/jstype" + "github.com/nlepage/go-wasm-http-server/internal/readablestream" "github.com/nlepage/go-wasm-http-server/internal/safejs" ) // Request builds and returns the equivalent http.Request -func Request(ur js.Value) (*http.Request, error) { - r := safejs.Safe(ur) +func Request(uvalue js.Value) (*http.Request, error) { + value := safejs.Safe(uvalue) - ab, err := r.Call("arrayBuffer") + body, err := value.Get("body") if err != nil { return nil, err } - u8a, err := jstype.Uint8Array.New(promise.Await(safejs.Unsafe(ab))) + r, err := body.Call("getReader") if err != nil { return nil, err } - l, err := u8a.GetInt("length") + method, err := value.GetString("method") if err != nil { return nil, err } - b := make([]byte, l) - - _, 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") + url, err := value.GetString("url") if err != nil { return nil, err } @@ -51,15 +36,18 @@ func Request(ur js.Value) (*http.Request, error) { req := httptest.NewRequest( method, url, - bytes.NewReader(b), + readablestream.NewReader(r), ) - headers, err := r.Get("headers") + headers, err := value.Get("headers") if err != nil { return nil, err } headersIt, err := headers.Call("entries") + if err != nil { + return nil, err + } for { e, err := headersIt.Call("next") if err != nil {