package captiveportal import ( "net/http" "github.com/pkg/errors" ) type Service struct { redirectURL string identifier Identifier options *Options registry *Registry } func (s *Service) ClientID(r *http.Request) (string, error) { id, err := s.identifier.Identify(r) if err != nil { return "", errors.Wrap(err, ErrClientIdentificationFailed.Error()) } return id, nil } func (s *Service) IsCaptive(r *http.Request) (bool, error) { id, err := s.ClientID(r) if err != nil { return false, errors.WithStack(err) } if id == "" { return true, nil } return s.registry.IsCaptive(id), nil } func (s *Service) Release(r *http.Request) error { id, err := s.ClientID(r) if err != nil { return errors.WithStack(err) } if id == "" { return nil } s.registry.Release(id) return nil } func (s *Service) Lie(r *http.Request) error { id, err := s.ClientID(r) if err != nil { return errors.WithStack(err) } if id == "" { return nil } s.registry.Lie(id) return nil } func (s *Service) ClientOS(r *http.Request) (OS, error) { id, err := s.ClientID(r) if err != nil { return OSUnknown, errors.WithStack(err) } if id == "" { return OSUnknown, nil } return s.registry.ClientOS(id), nil } func New(redirectURL string, identifier Identifier, opts ...OptionsFunc) *Service { options := DefaultOptions() for _, o := range opts { o(options) } service := &Service{ identifier: identifier, redirectURL: redirectURL, options: options, registry: NewRegistry(), } identifier.OnOffline(func(id string) { service.registry.Delete(id) }) return service }