router

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2019 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package router provides a WAMP router implementation that supports most of the WAMP advanced profile, offers multiple transports and TLS, and extends publication filtering functionality.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Authorizer

type Authorizer interface {
	// Authorize returns true if the sending session is authorized to send the
	// message.  Otherwise, it returns or false if not authorized.  An error is
	// returned if there is a failure to determine authorization.  This error
	// is included in the ERROR response to the client.
	//
	// Since the Authorizer accesses both the sending session and the message
	// through a pointer, the authorizer can alter the content of both the
	// sending session and the message.  This allows the authorizer to also
	// work as an interceptor of messages that can change their content and/or
	// change the sending session based on the intercepted message.  This
	// functionality may be used to set values in the session upon encountering
	// certain messages sent by that session.
	Authorize(*wamp.Session, wamp.Message) (bool, error)
}

Authorizer is the interface implemented by a type that provides the ability to authorize sending messages.

type Broker

type Broker struct {
	// contains filtered or unexported fields
}

func NewBroker

func NewBroker(logger stdlog.StdLog, strictURI, allowDisclose, debug bool, publishFilter FilterFactory) *Broker

NewBroker returns a new default broker implementation instance.

func (*Broker) Close

func (b *Broker) Close()

Close stops the broker, letting already queued actions finish.

func (*Broker) Publish

func (b *Broker) Publish(pub *session, msg *wamp.Publish)

Publish finds all subscriptions for the topic being published to, including those matching the topic by pattern, and sends an event to the subscribers of that topic.

When a single event matches more than one of a Subscriber's subscriptions, the event will be delivered for each subscription.

The Subscriber can detect the delivery of that same event on multiple subscriptions via EVENT.PUBLISHED.Publication, which will be identical.

func (*Broker) RemoveSession

func (b *Broker) RemoveSession(sess *session)

RemoveSession removes all subscriptions of the subscriber. This is called when a client leaves the realm by sending a GOODBYE message or by disconnecting from the router. If there are any subscriptions for this session a wamp.subscription.on_delete meta event is published for each.

func (*Broker) Role

func (b *Broker) Role() wamp.Dict

Role returns the role information for the "broker" role. The data returned is suitable for use as broker role info in a WELCOME message.

func (*Broker) SubCountSubscribers

func (b *Broker) SubCountSubscribers(msg *wamp.Invocation) wamp.Message

SubCountSubscribers obtains the number of sessions currently attached to the subscription.

func (*Broker) SubGet

func (b *Broker) SubGet(msg *wamp.Invocation) wamp.Message

SubGet retrieves information on a particular subscription.

func (*Broker) SubList

func (b *Broker) SubList(msg *wamp.Invocation) wamp.Message

SubList retrieves subscription IDs listed according to match policies.

func (*Broker) SubListSubscribers

func (b *Broker) SubListSubscribers(msg *wamp.Invocation) wamp.Message

SubListSubscribers retrieves a list of session IDs for sessions currently attached to the subscription.

func (*Broker) SubLookup

func (b *Broker) SubLookup(msg *wamp.Invocation) wamp.Message

SubLookup obtains the subscription (if any) managing a topic, according to some match policy.

func (*Broker) SubMatch

func (b *Broker) SubMatch(msg *wamp.Invocation) wamp.Message

SubMatch retrieves a list of IDs of subscriptions matching a topic URI, irrespective of match policy.

func (*Broker) Subscribe

func (b *Broker) Subscribe(sub *session, msg *wamp.Subscribe)

Subscribe subscribes the client to the given topic.

In case of receiving a SUBSCRIBE message from the same Subscriber and to already subscribed topic, Broker should answer with SUBSCRIBED message, containing the existing Subscription|id.

By default, Subscribers subscribe to topics with exact matching policy. A Subscriber might want to subscribe to topics based on a pattern. If the Broker and the Subscriber support pattern-based subscriptions, this matching can happen by prefix-matching policy or wildcard-matching policy.

func (*Broker) Unsubscribe

func (b *Broker) Unsubscribe(sub *session, msg *wamp.Unsubscribe)

Unsubscribe removes the requested subscription.

type Config

type Config struct {
	// RealmConfigs defines the configurations for realms within the router.
	RealmConfigs []*RealmConfig `json:"realms"`

	// RealmTemplate, if defined, is used by the router to create new realms
	// when a client requests to join a realm that does not yet exist.  If
	// RealmTemplate is nil (the default), then clients must join existing
	// realms.
	//
	// Caution, enabling a realm template that allows anonymous authentication
	// allows unauthenticated clients to create new realms.
	RealmTemplate *RealmConfig `json:"realm_template"`

	// Enable debug logging for router, realm, broker, dealer
	Debug bool
}

Config configures the router with realms, and optionally a template for creating new realms.

type Dealer

type Dealer struct {
	// contains filtered or unexported fields
}

func NewDealer

func NewDealer(logger stdlog.StdLog, strictURI, allowDisclose, debug bool) *Dealer

NewDealer creates the default Dealer implementation.

Messages are routed serially by the dealer's message handling goroutine. This serialization is limited to the work of determining the message's destination, and then the message is handed off to the next goroutine, typically the receiving client's send handler.

func (*Dealer) Call

func (d *Dealer) Call(caller *session, msg *wamp.Call)

Call invokes a registered remote procedure.

func (*Dealer) Cancel

func (d *Dealer) Cancel(caller *session, msg *wamp.Cancel)

Cancel actively cancels a call that is in progress.

Cancellation behaves differently depending on the mode:

"skip": The pending call is canceled and ERROR is send immediately back to the caller. No INTERRUPT is sent to the callee and the result is discarded when received.

"kill": INTERRUPT is sent to the client, but ERROR is not returned to the caller until after the callee has responded to the canceled call. In this case the caller may receive RESULT or ERROR depending whether the callee finishes processing the invocation or the interrupt first.

"killnowait": The pending call is canceled and ERROR is send immediately back to the caller. INTERRUPT is sent to the callee and any response to the invocation or interrupt from the callee is discarded when received.

If the callee does not support call canceling, then behavior is "skip".

func (*Dealer) Close

func (d *Dealer) Close()

Close stops the dealer, letting already queued actions finish.

func (*Dealer) Error

func (d *Dealer) Error(msg *wamp.Error)

Error handles an invocation error returned by the callee.

func (*Dealer) RegCountCallees

func (d *Dealer) RegCountCallees(msg *wamp.Invocation) wamp.Message

RegCountCallees obtains the number of sessions currently attached to the registration.

func (*Dealer) RegGet

func (d *Dealer) RegGet(msg *wamp.Invocation) wamp.Message

RegGet retrieves information on a particular registration.

func (*Dealer) RegList

func (d *Dealer) RegList(msg *wamp.Invocation) wamp.Message

RegList retrieves registration IDs listed according to match policies.

func (*Dealer) RegListCallees

func (d *Dealer) RegListCallees(msg *wamp.Invocation) wamp.Message

RegListCallees retrieves a list of session IDs for sessions currently attached to the registration.

func (*Dealer) RegLookup

func (d *Dealer) RegLookup(msg *wamp.Invocation) wamp.Message

RegLookup obtains the registration (if any) managing a procedure, according to some match policy.

func (*Dealer) RegMatch

func (d *Dealer) RegMatch(msg *wamp.Invocation) wamp.Message

RegMatch obtains the registration best matching a given procedure URI.

func (*Dealer) Register

func (d *Dealer) Register(callee *session, msg *wamp.Register)

Register registers a callee to handle calls to a procedure.

If the shared_registration feature is supported, and if allowed by the invocation policy, multiple callees may register to handle the same procedure.

func (*Dealer) RemoveSession

func (d *Dealer) RemoveSession(sess *session)

Remove a callee's registrations. This is called when a client leaves the realm by sending a GOODBYE message or by disconnecting from the router. If there are any registrations for this session wamp.registration.on_unregister and wamp.registration.on_delete meta events are published for each.

func (*Dealer) Role

func (d *Dealer) Role() wamp.Dict

Role returns the role information for the "dealer" role. The data returned is suitable for use as broker role info in a WELCOME message.

func (*Dealer) SetMetaPeer

func (d *Dealer) SetMetaPeer(metaPeer wamp.Peer)

SetMetaPeer sets the client that the dealer uses to publish meta events.

func (*Dealer) Unregister

func (d *Dealer) Unregister(callee *session, msg *wamp.Unregister)

Unregister removes a remote procedure previously registered by the callee.

func (*Dealer) Yield

func (d *Dealer) Yield(callee *session, msg *wamp.Yield)

Yield handles the result of successfully processing and finishing the execution of a call, send from callee to dealer.

type FilterFactory

type FilterFactory func(msg *wamp.Publish) PublishFilter

FilterFactory is a function which creates a PublishFilter from a publication

type PublishFilter

type PublishFilter interface {
	Allowed(sess *wamp.Session) bool
}

PublishFilter is an interface to check whether a publication should be sent to a specific session

func NewSimplePublishFilter

func NewSimplePublishFilter(msg *wamp.Publish) PublishFilter

NewSimplePublishFilter gets any blacklists and whitelists included in a PUBLISH message. If there are no filters defined by the PUBLISH message, then nil is returned.

type RawSocketServer

type RawSocketServer struct {
	// contains filtered or unexported fields
}

RawSocketServer handles socket connections.

func NewRawSocketServer

func NewRawSocketServer(r Router, recvLimit int, keepAlive time.Duration) *RawSocketServer

NewRawSocketServer takes a router instance and creates a new socket server.

func (*RawSocketServer) ListenAndServe

func (s *RawSocketServer) ListenAndServe(network, address string) (io.Closer, error)

ListenAndServe listens on the specified endpoint and starts a goroutine that accepts new client connections until the returned io.closer is closed.

func (*RawSocketServer) ListenAndServeTLS

func (s *RawSocketServer) ListenAndServeTLS(network, address string, tlscfg *tls.Config, certFile, keyFile string) (io.Closer, error)

ListenAndServeTLS listens on the specified endpoint and starts a goroutine that accepts new TLS client connections until the returned io.closer is closed. If tls.Config does not already contain a certificate, then certFile and keyFile, if specified, are used to load an X509 certificate.

type RealmConfig

type RealmConfig struct {
	// URI that identifies the realm.
	URI wamp.URI
	// Enforce strict URI format validation.
	StrictURI bool `json:"strict_uri"`
	// Allow anonymous authentication.  If an auth.AnonymousAuth Authenticator
	// if not supplied, then router supplies on with AuthRole of "anonymous".
	AnonymousAuth bool `json:"anonymous_auth"`
	// Allow publisher and caller identity disclosure when requested.
	AllowDisclose bool `json:"allow_disclose"`
	// Slice of Authenticator interfaces.
	Authenticators []auth.Authenticator
	// Authorizer called for each message.
	Authorizer Authorizer
	// Require authentication for local clients.  Normally local clients are
	// always trusted.  Setting this treats local clients the same as remote.
	RequireLocalAuth bool `json:"require_local_auth"`
	// Require authorization for local clients.  Normally local clients are
	// always authorized, even when the router has an authorizer.  Setting this
	// treats local clients the same as remote.
	RequireLocalAuthz bool `json:"require_local_authz"`

	// When true, only include standard session details in on_join event and
	// session_get response.  Standard details include: session, authid,
	// authrole, authmethod, transport.  When false, all session details are
	// included, except transport.auth.
	MetaStrict bool `json:"meta_strict"`
	// When MetaStrict is true, MetaIncludeSessionDetails specifies session
	// details to include that are in addition to the standard details
	// specified by the WAMP specification.  This is a list of the names of
	// additional session details values to include.
	MetaIncludeSessionDetails []string `json:"meta_include_session_details"`

	// EnableMetaKill enables the wamp.session.kill* session meta procedures.
	// These are disabled by default to avoid requiring Authorizer logic when
	// it may not be needed otherwise.
	EnableMetaKill bool `json:"enable_meta_kill"`
	// EnableMetaModify enables the wamp.session.modify_details session meta
	// procedure.  This is disabled by default to avoid requiring Authorizer
	// logic when it may not be needed otherwise.
	EnableMetaModify bool `json:"enable_meta_modify"`

	// PublishFilterFactory is a function used to create a
	// PublishFilter to check which sessions a publication should be
	// sent to.
	//
	// This value is not set via json config, but is configured when
	// embedding nexus.  A value of nil enables the default filtering.
	PublishFilterFactory FilterFactory
}

RealmConfig configures a single realm in the router. The router configuration may specify a list of realms to configure.

type Router

type Router interface {
	// Attach connects a client to the router and to the requested realm.
	Attach(wamp.Peer) error

	// AttachClient connects a client to the router and to the requested realm.
	// It provides additional transport information details.
	AttachClient(wamp.Peer, wamp.Dict) error

	// Close stops the router and waits message processing to stop.
	Close()

	// Logger returns the logger the router is using.
	Logger() stdlog.StdLog

	// AddRealm will append a realm to this router
	AddRealm(*RealmConfig) error

	// RemoveRealm will attempt to remove a realm from this router
	RemoveRealm(wamp.URI)
}

A Router handles new Peers and routes requests to the requested Realm.

func NewRouter

func NewRouter(config *Config, logger stdlog.StdLog) (Router, error)

NewRouter creates a WAMP router instance.

type RouterConfig deprecated

type RouterConfig = Config

Deprecated: replaced by Config

RouterConfig is a type alias for the deprecated RouterConfig. router.Config replaces router.RouterConfig

type WebsocketServer

type WebsocketServer struct {
	// Upgrader specifies parameters for upgrading an HTTP connection to a
	// websocket connection.  See:
	// https://godoc.org/github.com/gorilla/websocket#Upgrader
	Upgrader *websocket.Upgrader

	// Serializer for text frames.  Defaults to JSONSerializer.
	TextSerializer serialize.Serializer
	// Serializer for binary frames.  Defaults to MessagePackSerializer.
	BinarySerializer serialize.Serializer

	// EnableTrackingCookie tells the server to send a random-value cookie to
	// the websocket client.  A returning client may identify itself by sending
	// a previously issued tracking cookie in a websocket request.  If a
	// request header received by the server contains the tracking cookie, then
	// the cookie is included in the HELLO and session details.  The new
	// tracking cookie that gets sent to the client (the cookie to expect for
	// subsequent connections) is also stored in HELLO and session details.
	//
	// The cookie from the request, and the next cookie to expect, are
	// stored in the HELLO and session details, respectively, as:
	//
	//     Details.transport.auth.cookie|*http.Cookie
	//     Details.transport.auth.nextcookie|*http.Cookie
	//
	// This information is available to auth/authz logic, and can be retrieved
	// from details as follows:
	//
	//     req *http.Request
	//     path := []string{"transport", "auth", "request"}
	//     v, err := wamp.DictValue(details, path)
	//     if err == nil {
	//         req = v.(*http.Request)
	//     }
	//
	// The "cookie" and "nextcookie" values are retrieved similarly.
	EnableTrackingCookie bool
	// EnableRequestCapture tells the server to include the upgrade HTTP
	// request in the HELLO and session details.  It is stored in
	// Details.transport.auth.request|*http.Request making it available to
	// authenticator and authorizer logic.
	EnableRequestCapture bool

	// KeepAlive configures a websocket "ping/pong" heartbeat when set to a
	// non-zero value.  KeepAlive is the interval between websocket "pings".
	// If a "pong" response is not received after 2 intervals have elapsed then
	// the websocket connection is closed.
	KeepAlive time.Duration
	// contains filtered or unexported fields
}

WebsocketServer handles websocket connections.

Origin Considerations

Web browsers allow Javascript applications to open a WebSocket connection to any host. It is up to the server to enforce an origin policy using the Origin request header sent by the browser. To specify origins allowed by the server, call AllowOrigins() to allow origins matching glob patterns, or assign a custom function to the server's Upgrader.CheckOrigin. See AllowOrigins() for details.

func NewWebsocketServer

func NewWebsocketServer(r Router) *WebsocketServer

NewWebsocketServer takes a router instance and creates a new websocket server.

Optional websocket server configuration can be set, after creating the server instance, by setting WebsocketServer.Upgrader and other WebsocketServer members directly. Use then WebsocketServer.AllowOrigins() function to specify what origins to allow for CORS support.

To run the websocket server, call one of the server's ListenAndServe methods:

s := NewWebsocketServer(r)
closer, err := s.ListenAndServe(address)

Or, use the various ListenAndServe functions provided by net/http. This works because WebsocketServer implements the http.Handler interface:

s := NewWebsocketServer(r)
server := &http.Server{
    Handler: s,
    Addr:    address,
}
server.ListenAndServe()

func (*WebsocketServer) AllowOrigins

func (s *WebsocketServer) AllowOrigins(origins []string) error

AllowOrigins configures the server to allow connections when the Origin host matches a specified glob pattern.

If the origin request header in the websocket upgrade request is present, then the connection is allowed if the Origin host is equal to the Host request header or Origin matches one of the allowed patterns. A pattern is in the form of a shell glob as described here: https://golang.org/pkg/path/filepath/#Match Glob matching is case-insensitive.

For example:

s := NewWebsocketServer(r)
s.AllowOrigins([]string{"*.domain.com", "*.domain.net"})

To allow all origins, specify a wildcard only:

s.AllowOrigins([]string{"*"})

Origins with Ports

To allow origins that have a port number, specify the port as part of the origin pattern, or use a wildcard to match the ports.

Allow a specific port, by specifying the expected port number:

s.AllowOrigins([]string{"*.somewhere.com:8080"})

Allow individual ports, by specifying each port:

err := s.AllowOrigins([]string{
    "*.somewhere.com:8080",
    "*.somewhere.com:8905",
    "*.somewhere.com:8908",
})

Allow any port, by specifying a wildcard. Be sure to include the colon ":" so that the pattern does not match a longer origin. Without the ":" this example would also match "x.somewhere.comics.net"

err := s.AllowOrigins([]string{"*.somewhere.com:*"})

Custom Origin Checks

Alternatively, a custom function my be configured to supplied any origin checking logic your application needs. The WebsocketServer calls the function specified in the WebsocketServer.Upgrader.CheckOrigin field to check the origin. If the CheckOrigin function returns false, then the WebSocket handshake fails with HTTP status 403. To supply a CheckOrigin function:

s := NewWebsocketServer(r)
s.Upgrader.CheckOrigin = func(r *http.Request) bool { ... }

Default Behavior

If AllowOrigins() is not called, and Upgrader.CheckOrigin is nil, then a safe default is used: fail the handshake if the Origin request header is present and the Origin host is not equal to the Host request header.

func (*WebsocketServer) ListenAndServe

func (s *WebsocketServer) ListenAndServe(address string) (io.Closer, error)

ListenAndServe listens on the specified TCP address and starts a goroutine that accepts new client connections until the returned io.closer is closed.

func (*WebsocketServer) ListenAndServeTLS

func (s *WebsocketServer) ListenAndServeTLS(address string, tlscfg *tls.Config, certFile, keyFile string) (io.Closer, error)

ListenAndServeTLS listens on the specified TCP address and starts a goroutine that accepts new TLS client connections until the returned io.closer is closed. If tls.Config does not already contain a certificate, then certFile and keyFile, if specified, are used to load an X509 certificate.

func (*WebsocketServer) ServeHTTP

func (s *WebsocketServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles HTTP connections.

func (*WebsocketServer) SetConfig deprecated

func (s *WebsocketServer) SetConfig(wsCfg transport.WebsocketConfig)

Deprecated: Set WebsocketServer.Upgrader and WebsockServer.Xxx members directly.

Directories

Path Synopsis
Package auth provides interfaces for implementing authentication logic that the WAMP router can use.
Package auth provides interfaces for implementing authentication logic that the WAMP router can use.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL