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.CapturedE(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 } }