router

package
v3.0.0-...-7d4fba5 Latest Latest
Warning

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

Go to latest
Published: Nov 27, 2023 License: MIT Imports: 25 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

View Source
var (
	ErrPPTNotSupportedByPeer = errors.New("peer is trying to use Payload PassThru Mode while it was not" +
		" announced during HELLO handshake")
)
View Source
var Version string

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 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
	// Interval in seconds for logging memory stats.  O to disable.
	// Logs Alloc, Mallocs, Frees, and NumGC.  For a description of these, see
	// https://golang.org/pkg/runtime/#MemStats
	MemStatsLogSec int `json:"mem_stats_log_sec"`
}

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

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 {
	// RecvLimit is the maximum length of messages the server is willing to
	// receive.  Defaults to maximum allowed for protocol: 16M.
	RecvLimit int

	// KeepAlive is the TCP keep-alive period.  Default is disable keep-alive.
	KeepAlive time.Duration

	// OutQueueSize is the maximum number of pending outbound messages, per
	// client.  The default is defaultOutQueueSize.
	OutQueueSize int
	// contains filtered or unexported fields
}

RawSocketServer handles socket connections.

func NewRawSocketServer

func NewRawSocketServer(r Router) *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"`

	TopicEventHistoryConfigs []*TopicEventHistoryConfig `json:"event_history"`

	// 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)

	// RouterFeatures exposes WAMP features current version provides
	// When Nexus is used as a pluggable library sometimes it is
	// usefully to expose WAMP features current version provides.
	RouterFeatures() *wamp.Dict

	GetRealm(wamp.URI) (*realm, error)
}

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 TopicEventHistoryConfig

type TopicEventHistoryConfig struct {
	Topic       wamp.URI `json:"topic"` // Topic URI
	MatchPolicy string   `json:"match"` // Matching policy (exact|prefix|wildcard)
	Limit       int      `json:"limit"` // Number of most recent events to store
}

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

	// OutQueueSize is the maximum number of pending outbound messages, per
	// client.  The default is defaultOutQueueSize.
	OutQueueSize int
	// 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.

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