123 lines
2.6 KiB
Go
123 lines
2.6 KiB
Go
|
package fetch
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"forge.cadoles.com/arcad/edge/pkg/app"
|
||
|
"forge.cadoles.com/arcad/edge/pkg/bus"
|
||
|
"github.com/dop251/goja"
|
||
|
"github.com/pkg/errors"
|
||
|
"gitlab.com/wpetit/goweb/logger"
|
||
|
)
|
||
|
|
||
|
type Module struct {
|
||
|
server *app.Server
|
||
|
bus bus.Bus
|
||
|
}
|
||
|
|
||
|
func (m *Module) Name() string {
|
||
|
return "fetch"
|
||
|
}
|
||
|
|
||
|
func (m *Module) Export(export *goja.Object) {
|
||
|
funcs := map[string]any{
|
||
|
"get": m.get,
|
||
|
}
|
||
|
|
||
|
for name, fn := range funcs {
|
||
|
if err := export.Set(name, fn); err != nil {
|
||
|
panic(errors.Wrapf(err, "could not set '%s' function", name))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (m *Module) get(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
|
||
|
// ctx := util.AssertContext(call.Argument(0), rt)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (m *Module) handleMessages() {
|
||
|
ctx := context.Background()
|
||
|
|
||
|
err := m.bus.Reply(ctx, MessageNamespaceFetchRequest, func(msg bus.Message) (bus.Message, error) {
|
||
|
fetchRequest, ok := msg.(*MessageFetchRequest)
|
||
|
if !ok {
|
||
|
return nil, errors.Wrapf(bus.ErrUnexpectedMessage, "expected message fetch request, got '%T'", msg)
|
||
|
}
|
||
|
|
||
|
res, err := m.handleFetchRequest(fetchRequest)
|
||
|
if err != nil {
|
||
|
logger.Error(ctx, "could not handle fetch request", logger.E(errors.WithStack(err)))
|
||
|
|
||
|
return nil, errors.WithStack(err)
|
||
|
}
|
||
|
|
||
|
logger.Debug(ctx, "fetch request response", logger.F("response", res))
|
||
|
|
||
|
return res, nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
panic(errors.WithStack(err))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (m *Module) handleFetchRequest(req *MessageFetchRequest) (*MessageFetchResponse, error) {
|
||
|
res := NewMessageFetchResponse(req.RequestID)
|
||
|
|
||
|
ctx := logger.With(
|
||
|
req.Context,
|
||
|
logger.F("url", req.URL.String()),
|
||
|
logger.F("remoteAddr", req.RemoteAddr),
|
||
|
logger.F("requestID", req.RequestID),
|
||
|
)
|
||
|
|
||
|
rawResult, err := m.server.ExecFuncByName(ctx, "onClientFetch", ctx, req.URL.String(), req.RemoteAddr)
|
||
|
if err != nil {
|
||
|
if errors.Is(err, app.ErrFuncDoesNotExist) {
|
||
|
res.Allow = false
|
||
|
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
return nil, errors.WithStack(err)
|
||
|
}
|
||
|
|
||
|
result, ok := rawResult.Export().(map[string]interface{})
|
||
|
if !ok {
|
||
|
return nil, errors.Errorf(
|
||
|
"unexpected onClientFetch result: expected 'map[string]interface{}', got '%T'",
|
||
|
rawResult.Export(),
|
||
|
)
|
||
|
}
|
||
|
|
||
|
var allow bool
|
||
|
|
||
|
rawAllow, exists := result["allow"]
|
||
|
if !exists {
|
||
|
allow = false
|
||
|
} else {
|
||
|
allow, ok = rawAllow.(bool)
|
||
|
if !ok {
|
||
|
return nil, errors.Errorf("invalid 'allow' result property: got type '%T', expected type '%T'", rawAllow, false)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
res.Allow = allow
|
||
|
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
func ModuleFactory(bus bus.Bus) app.ServerModuleFactory {
|
||
|
return func(server *app.Server) app.ServerModule {
|
||
|
mod := &Module{
|
||
|
bus: bus,
|
||
|
server: server,
|
||
|
}
|
||
|
|
||
|
go mod.handleMessages()
|
||
|
|
||
|
return mod
|
||
|
}
|
||
|
}
|