2019-11-27 00:58:05 +01:00
|
|
|
package wasmhttp
|
|
|
|
|
|
|
|
import (
|
2024-10-14 09:14:50 +02:00
|
|
|
"context"
|
2019-11-27 08:20:40 +01:00
|
|
|
"fmt"
|
2019-11-27 00:58:05 +01:00
|
|
|
"net/http"
|
2019-11-27 11:20:52 +01:00
|
|
|
"strings"
|
2019-11-27 00:58:05 +01:00
|
|
|
"syscall/js"
|
2021-08-16 23:40:53 +02:00
|
|
|
|
2024-10-14 22:24:46 +02:00
|
|
|
"github.com/nlepage/go-wasm-http-server/v2/internal/safejs"
|
2024-10-14 09:14:50 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
wasmhttp = safejs.Safe(js.Global().Get("wasmhttp"))
|
2019-11-27 00:58:05 +01:00
|
|
|
)
|
|
|
|
|
2019-11-27 07:59:57 +01:00
|
|
|
// Serve serves HTTP requests using handler or http.DefaultServeMux if handler is nil.
|
2024-10-14 09:14:50 +02:00
|
|
|
func Serve(handler http.Handler) (func(), error) {
|
|
|
|
h := handler
|
2019-11-27 00:58:05 +01:00
|
|
|
if h == nil {
|
|
|
|
h = http.DefaultServeMux
|
|
|
|
}
|
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
prefix, err := wasmhttp.GetString("path")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-01-22 00:58:30 +01:00
|
|
|
for strings.HasSuffix(prefix, "/") {
|
|
|
|
prefix = strings.TrimSuffix(prefix, "/")
|
2019-11-27 11:20:52 +01:00
|
|
|
}
|
|
|
|
|
2021-01-22 00:58:30 +01:00
|
|
|
if prefix != "" {
|
2024-10-14 09:14:50 +02:00
|
|
|
mux := http.NewServeMux()
|
2021-01-22 00:58:30 +01:00
|
|
|
mux.Handle(prefix+"/", http.StripPrefix(prefix, h))
|
2019-11-27 11:20:52 +01:00
|
|
|
h = mux
|
|
|
|
}
|
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
handlerValue, err := safejs.FuncOf(func(_ safejs.Value, args []safejs.Value) interface{} {
|
|
|
|
res, err := NewResponse()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-01-27 23:21:59 +01:00
|
|
|
|
|
|
|
go func() {
|
2024-10-14 09:14:50 +02:00
|
|
|
ctx, cancel := context.WithCancel(res.Context())
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
cancel()
|
|
|
|
}()
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := res.Close(); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2021-01-27 23:21:59 +01:00
|
|
|
defer func() {
|
|
|
|
if r := recover(); r != nil {
|
2024-10-14 09:14:50 +02:00
|
|
|
var errStr string
|
2021-01-27 23:21:59 +01:00
|
|
|
if err, ok := r.(error); ok {
|
2024-10-14 09:14:50 +02:00
|
|
|
errStr = err.Error()
|
2021-01-27 23:21:59 +01:00
|
|
|
} else {
|
2024-10-14 09:14:50 +02:00
|
|
|
errStr = fmt.Sprintf("%s", r)
|
2019-11-27 08:20:40 +01:00
|
|
|
}
|
2024-10-14 09:14:50 +02:00
|
|
|
res.WriteError(errStr)
|
2021-01-27 23:21:59 +01:00
|
|
|
}
|
|
|
|
}()
|
2019-11-27 08:20:40 +01:00
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
req, err := Request(safejs.Unsafe(args[0]))
|
|
|
|
if err != nil {
|
|
|
|
res.WriteError(err.Error())
|
|
|
|
return
|
|
|
|
}
|
2019-11-27 00:58:05 +01:00
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
req = req.WithContext(ctx)
|
2019-11-27 00:58:05 +01:00
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
h.ServeHTTP(res, req)
|
2021-01-27 23:21:59 +01:00
|
|
|
}()
|
2019-11-27 00:58:05 +01:00
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
return res.JSValue()
|
2019-11-27 00:58:05 +01:00
|
|
|
})
|
2024-10-14 09:14:50 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-11-27 00:58:05 +01:00
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
if _, err = wasmhttp.Call("setHandler", handlerValue); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-11-27 00:58:05 +01:00
|
|
|
|
2024-10-14 09:14:50 +02:00
|
|
|
return handlerValue.Release, nil
|
2019-11-27 00:58:05 +01:00
|
|
|
}
|