websocket

package
v5.1.1 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2024 License: MIT Imports: 9 Imported by: 2

Documentation

Index

Constants

View Source
const (
	// NormalClosureMessage the message sent with the close frame
	// during the close handshake.
	NormalClosureMessage = "Server closed connection"
)

Variables

This section is empty.

Functions

func IsCloseError

func IsCloseError(err error) bool

IsCloseError returns true if the error is one of the following close errors: CloseNormalClosure (1000), CloseGoingAway (1001) or CloseNoStatusReceived (1005)

Types

type Conn

type Conn struct {
	*ws.Conn
	// contains filtered or unexported fields
}

Conn represents a WebSocket connection.

func (*Conn) Close

func (c *Conn) Close(code int, message string) error

Close performs the closing handshake as specified by RFC 6455 Section 1.4.

This function expects another goroutine to be reading the connection, expecting the close frame in response. This waiting can time out. If so, Close will just close the connection.

Calling this function multiple times is safe and only the first call will write the close frame to the connection.

func (*Conn) CloseNormal

func (c *Conn) CloseNormal() error

CloseNormal performs the closing handshake as specified by RFC 6455 Section 1.4. Sends status code 1000 (normal closure) and message "Server closed connection".

This function expects another goroutine to be reading the connection, expecting the close frame in response. This waiting can time out. If so, Close will just close the connection.

Calling this function multiple times is safe and only the first call will write the close frame to the connection.

func (*Conn) CloseWithError

func (c *Conn) CloseWithError(_ error) error

CloseWithError performs the closing handshake as specified by RFC 6455 Section 1.4 because a server error occurred. Sends status code 1011 (internal server error) and message "Internal server error".

This function starts another goroutine to read the connection, expecting the close frame in response. This waiting can time out. If so, Close will just close the connection. Therefore, it is not safe to call this function if there is already an active reader.

func (*Conn) GetCloseHandshakeTimeout

func (c *Conn) GetCloseHandshakeTimeout() time.Duration

GetCloseHandshakeTimeout return the timeout used when writing and reading close frames during the close handshake.

func (*Conn) SetCloseHandshakeTimeout

func (c *Conn) SetCloseHandshakeTimeout(timeout time.Duration)

SetCloseHandshakeTimeout set the timeout used when writing and reading close frames during the close handshake.

type Controller

type Controller interface {
	goyave.Composable

	// Serve is a handler for websocket connections.
	// The request parameter contains the original upgraded HTTP request.
	//
	// To keep the connection alive, these handlers should run an infinite for loop that
	// can return on error or exit in a predictable manner.
	//
	// They also can start goroutines for reads and writes, but shouldn't return before
	// both of them do. The handler is responsible of synchronizing the goroutines it started,
	// and ensure no reader nor writer are still active when it returns.
	//
	// When the websocket handler returns, the closing handshake is performed (if not already done
	// using "conn.Close()") and the connection is closed.
	//
	// If the websocket handler returns nil, it means that everything went fine and the
	// connection can be closed normally. On the other hand, the websocket handler
	// can return an error, such as a write error, to indicate that the connection should not
	// be closed normally. The behavior used when this happens depend on the implementation
	// of the HTTP handler that upgraded the connection.
	//
	// By default, the server shutdown doesn't wait for hijacked connections to be closed gracefully.
	// It is advised to register a shutdown hook blocking until all the connections are gracefully
	// closed using `*websocket.Conn.CloseNormal()`.
	//
	// The following websocket Handler is a simple example of an "echo" feature using websockets:
	//
	//	func (c *EchoController) Serve(c *websocket.Conn, request *goyave.Request) error {
	//		for {
	//			mt, message, err := c.ReadMessage()
	//			if err != nil {
	//				return errors.New(err)
	//			}
	//			c.Logger().Debug("recv", "message", string(message))
	//			err = c.WriteMessage(mt, message)
	//			if err != nil {
	//				return errors.Errof("write: %w", err)
	//			}
	//		}
	//	}
	Serve(conn *Conn, request *goyave.Request) error
}

Controller component for websockets.

type ErrorHandler

type ErrorHandler interface {
	// ErrorHandler specifies the function handling errors returned by the controller's `Serve` function
	// or if this function panics.
	OnError(request *goyave.Request, err error)
}

ErrorHandler allows a `websocket.Controller` to define a custom behavior in case of error occurring in the controller's `Serve` function. This custom error handler is called for both handled and unhandled errors (panics).

If the `websocket.Controller` doesn't implement this interface, the error is logged at the error level.

type HeaderUpgrader

type HeaderUpgrader interface {
	// UpgradeHeaders function generating headers to be sent with the protocol switching response.
	UpgradeHeaders(r *goyave.Request) http.Header
}

HeaderUpgrader allows a `websocket.Controller` to define custom HTTP headers in the protocol switching response.

type OriginChecker

type OriginChecker interface {
	// CheckOrigin returns true if the request Origin header is acceptable.
	//
	// A CheckOrigin function should carefully validate the request origin to
	// prevent cross-site request forgery.
	CheckOrigin(r *goyave.Request) bool
}

OriginChecker allows a `websocket.Controller` to define custom origin header checking behavior.

If the `websocket.Controller` doesn't implement this interface, a safe default is used: return false if the Origin request header is present and the origin host is not equal to request Host header.

type Registrer

type Registrer interface {
	// RegisterRoute registers the route for the websocket upgrade. The route must only match the
	// GET HTTP method and use the `goyave.Handler` received as a parameter.
	RegisterRoute(router *goyave.Router, handler goyave.Handler)
}

Registrer qualifies a `websocket.Controller` that registers its route itself, allowing to define validation rules, middleware, route meta, etc.

If the `websocket.Controller` doesn't implement this interface, the route is registered for the GET method and an empty path.

type UpgradeErrorHandler

type UpgradeErrorHandler interface {
	// OnUpgradeError specifies the function for generating HTTP error responses if the
	// protocol switching process fails. The error can be a user error or server error.
	OnUpgradeError(response *goyave.Response, request *goyave.Request, status int, reason error)
}

UpgradeErrorHandler allows a `websocket.Controller` to define a custom behavior when the protocol switching process fails.

If the `websocket.Controller` doesn't implement this interface, the default error handler returns a JSON response containing the status text corresponding to the status code returned. If debugging is enabled, the reason error message is returned instead.

{"error": "message"}

type Upgrader

type Upgrader struct {
	goyave.Component

	Controller Controller

	// Settings the parameters for upgrading the connection. "Error" and "CheckOrigin" are
	// ignored: use implementations of the interfaces `UpgradeErrorHandler` and `ErrorHandler`.
	Settings ws.Upgrader
}

Upgrader is responsible for the upgrade of HTTP connections to websocket connections.

func New

func New(controller Controller) *Upgrader

New create a new Upgrader with default settings.

func (*Upgrader) Handler

func (u *Upgrader) Handler() goyave.Handler

Handler create an HTTP handler upgrading the HTTP connection before passing it to the given websocket Handler.

HTTP response's status is set to "101 Switching Protocols".

The connection is closed automatically after the websocket Handler returns, using the closing handshake defined by RFC 6455 Section 1.4 if possible and if not already performed using "conn.Close()".

If the websocket Handler returns an error that is not a CloseError, the Upgrader's error handler will be executed and the close frame sent to the client will have status code 1011 (internal server error) and "Internal server error" as message. If debug is enabled, the message will be the error message returned by the websocket handler. Otherwise the close frame will have status code 1000 (normal closure) and "Server closed connection" as a message.

This HTTP handler features a recovery mechanism. If the websocket Handler panics, the connection will be gracefully closed just like if the websocket Handler returned an error without panicking.

This HTTP Handler returns once the connection has been successfully upgraded. That means that, for example, logging middleware will log the request right away instead of waiting for the websocket connection to be closed.

func (*Upgrader) RegisterRoutes

func (u *Upgrader) RegisterRoutes(router *goyave.Router)

RegisterRoutes implementation of `goyave.Registrer`.

If the `websocket.Controller` implements `websocket.Registrer`, uses its implementation to register the route. Otherwise registers the route for the GET method and an empty path.

Jump to

Keyboard shortcuts

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