Documentation ¶
Overview ¶
Package web implements web proxy handler that provides web interface to view and connect to teleport nodes
Package web implements web proxy handler that provides web interface to view and connect to teleport nodes
Index ¶
- Constants
- Variables
- func CheckResourceUpsertableByError(err error, httpMethod, resourceName string) error
- func ClearSession(w http.ResponseWriter)
- func ConstructSSHResponse(response AuthParams) (*url.URL, error)
- func EncodeCookie(user, sid string) (string, error)
- func ExtractResourceAndValidate(yaml string) (*services.UnknownResource, error)
- func NewDebugFileSystem(assetsPath string) (http.FileSystem, error)
- func OK() interface{}
- func RedirectURLWithError(clientRedirectURL string, errReply error) (*url.URL, error)
- func SSOSetWebSessionAndRedirectURL(w http.ResponseWriter, r *http.Request, response *SSOCallbackResponse, ...) error
- func SetSessionCookie(w http.ResponseWriter, user, sid string) error
- type APIHandler
- type AuthParams
- type AuthProvider
- type ClusterClientHandler
- type ClusterClientProvider
- type ClusterHandler
- type Config
- type ConnectionHandler
- type ContextHandler
- type CreateAppSessionRequest
- type CreateAppSessionResponse
- type CreateSessionReq
- type CreateSessionResponse
- type Envelope
- func (*Envelope) Descriptor() ([]byte, []int)
- func (m *Envelope) GetPayload() string
- func (m *Envelope) GetType() string
- func (m *Envelope) GetVersion() string
- func (m *Envelope) Marshal() (dAtA []byte, err error)
- func (m *Envelope) MarshalTo(dAtA []byte) (int, error)
- func (m *Envelope) MarshalToSizedBuffer(dAtA []byte) (int, error)
- func (*Envelope) ProtoMessage()
- func (m *Envelope) Reset()
- func (m *Envelope) Size() (n int)
- func (m *Envelope) String() string
- func (m *Envelope) Unmarshal(dAtA []byte) error
- func (m *Envelope) XXX_DiscardUnknown()
- func (m *Envelope) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- func (m *Envelope) XXX_Merge(src proto.Message)
- func (m *Envelope) XXX_Size() int
- func (m *Envelope) XXX_Unmarshal(b []byte) error
- type GetAppFQDNRequest
- type GetAppFQDNResponse
- type Handler
- func (h *Handler) AuthenticateRequest(w http.ResponseWriter, r *http.Request, checkBearerToken bool) (*SessionContext, error)
- func (h *Handler) Close() error
- func (h *Handler) GetProxyClient() auth.ClientI
- func (h *Handler) ProxyHostPort() string
- func (h *Handler) ProxyWithRoles(ctx *SessionContext) (reversetunnel.Tunnel, error)
- func (h *Handler) String() string
- func (h *Handler) WithAuth(fn ContextHandler) httprouter.Handle
- func (h *Handler) WithClusterAuth(fn ClusterHandler) httprouter.Handle
- func (h *Handler) WithClusterClientProvider(fn ClusterClientHandler) httprouter.Handle
- func (h *Handler) WithMetaRedirect(fn redirectHandlerFunc) httprouter.Handle
- func (h *Handler) WithProvisionTokenAuth(fn ProvisionTokenHandler) httprouter.Handle
- func (h *Handler) WithRedirect(fn redirectHandlerFunc) httprouter.Handle
- type HandlerOption
- type JWKSResponse
- type ProvisionTokenHandler
- type ResourceMap
- type SSOCallbackResponse
- type SSORequestParams
- type SessionContext
- func (c *SessionContext) AddClosers(closers ...io.Closer)
- func (c *SessionContext) ClientTLSConfig(clusterName ...string) (*tls.Config, error)
- func (c *SessionContext) Close() error
- func (c *SessionContext) GetAgent() (agent.ExtendedAgent, *ssh.Certificate, error)
- func (c *SessionContext) GetClient() (auth.ClientI, error)
- func (c *SessionContext) GetClientConnection() *grpc.ClientConn
- func (c *SessionContext) GetIdentity() (*tlsca.Identity, error)
- func (c *SessionContext) GetProxyListenerMode(ctx context.Context) (types.ProxyListenerMode, error)
- func (c *SessionContext) GetSSHCertificate() (*ssh.Certificate, error)
- func (c *SessionContext) GetSessionID() string
- func (c *SessionContext) GetUser() string
- func (c *SessionContext) GetUserAccessChecker() (services.AccessChecker, error)
- func (c *SessionContext) GetUserClient(site reversetunnel.RemoteSite) (auth.ClientI, error)
- func (c *SessionContext) GetX509Certificate() (*x509.Certificate, error)
- func (c *SessionContext) Invalidate(ctx context.Context) error
- func (c *SessionContext) RemoveCloser(closer io.Closer)
- func (c *SessionContext) String() string
- type SessionCookie
- type TerminalHandler
- type TerminalRequest
- type WebsocketIO
Constants ¶
const (
// CookieName is the name of the session cookie.
CookieName = "__Host-session"
)
const (
// SSOLoginFailureMessage is a generic error message to avoid disclosing sensitive SSO failure messages.
SSOLoginFailureMessage = "Failed to login. Please check Teleport's log for more details."
)
Variables ¶
Functions ¶
func CheckResourceUpsertableByError ¶
CheckResourceUpsertableByError checks if the resource is upsertable by the state of error with the request http method used.
func ClearSession ¶ added in v1.0.0
func ClearSession(w http.ResponseWriter)
func ConstructSSHResponse ¶ added in v1.0.0
func ConstructSSHResponse(response AuthParams) (*url.URL, error)
ConstructSSHResponse creates a special SSH response for SSH login method that encodes everything using the client's secret key
func EncodeCookie ¶
func ExtractResourceAndValidate ¶
func ExtractResourceAndValidate(yaml string) (*services.UnknownResource, error)
ExtractResourceAndValidate extracts resource information from given string and validates basic fields.
func NewDebugFileSystem ¶
func NewDebugFileSystem(assetsPath string) (http.FileSystem, error)
NewDebugFileSystem returns the HTTP file system implementation rooted at the specified assetsPath.
func RedirectURLWithError ¶
RedirectURLWithError adds an err query parameter to the given redirect URL with the given errReply message and returns the new URL. If the given URL cannot be parsed, an error is returned with a nil URL. It is used to return an error back to the original URL in an SSO callback when validation fails.
func SSOSetWebSessionAndRedirectURL ¶
func SSOSetWebSessionAndRedirectURL(w http.ResponseWriter, r *http.Request, response *SSOCallbackResponse, verifyCSRF bool) error
SSOSetWebSessionAndRedirectURL validates the CSRF token in the response against that in the request, validates that the callback URL in the response can be parsed, and sets a session cookie with the username and session name from the response. On success, nil is returned. If the validation fails, an error is returned.
func SetSessionCookie ¶
func SetSessionCookie(w http.ResponseWriter, user, sid string) error
Types ¶
type APIHandler ¶
type APIHandler struct {
// contains filtered or unexported fields
}
func NewHandler ¶ added in v1.0.0
func NewHandler(cfg Config, opts ...HandlerOption) (*APIHandler, error)
NewHandler returns a new instance of web proxy handler
func (*APIHandler) Close ¶
func (h *APIHandler) Close() error
func (*APIHandler) HandleConnection ¶
HandleConnection handles connections from plain TCP applications.
func (*APIHandler) ServeHTTP ¶
func (h *APIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Check if this request should be forwarded to an application handler to be handled by the UI and handle the request appropriately.
type AuthParams ¶
type AuthParams struct { // Username is authenticated teleport username Username string // Identity contains validated OIDC identity Identity types.ExternalIdentity // Web session will be generated by auth server if requested in OIDCAuthRequest Session types.WebSession // Cert will be generated by certificate authority Cert []byte // TLSCert is PEM encoded TLS certificate TLSCert []byte // HostSigners is a list of signing host public keys // trusted by proxy, used in console login HostSigners []types.CertAuthority // ClientRedirectURL is a URL to redirect client to ClientRedirectURL string // FIPS mode means Teleport started in a FedRAMP/FIPS 140-2 compliant // configuration. FIPS bool }
AuthParams are used to construct redirect URL containing auth information back to tsh login
type AuthProvider ¶
type AuthProvider interface { GetNodes(ctx context.Context, namespace string) ([]types.Server, error) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]events.EventFields, error) GetSessionTracker(ctx context.Context, sessionID string) (types.SessionTracker, error) }
AuthProvider is a subset of the full Auth API.
type ClusterClientHandler ¶
type ClusterClientHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *SessionContext, ClusterClientProvider) (interface{}, error)
ClusterClientHandler is an authenticated handler which can get a client for any remote cluster.
type ClusterClientProvider ¶
type ClusterClientProvider interface { // UserClientForCluster returns a client to the local or remote cluster // identified by clusterName and is authenticated with the identity of the // user. UserClientForCluster(clusterName string) (auth.ClientI, error) }
ClusterClientProvider is an interface for a type which can provide authenticated clients to remote clusters.
type ClusterHandler ¶
type ClusterHandler func(w http.ResponseWriter, r *http.Request, p httprouter.Params, ctx *SessionContext, site reversetunnel.RemoteSite) (interface{}, error)
ClusterHandler is a authenticated handler that is called for some existing remote cluster
type Config ¶ added in v1.0.0
type Config struct { // PluginRegistry handles plugin registration PluginRegistry plugin.Registry // Proxy is a reverse tunnel proxy that handles connections // to local cluster or remote clusters using unified interface Proxy reversetunnel.Tunnel // AuthServers is a list of auth servers this proxy talks to AuthServers utils.NetAddr // DomainName is a domain name served by web handler DomainName string // ProxyClient is a client that authenticated as proxy ProxyClient auth.ClientI // ProxySSHAddr points to the SSH address of the proxy ProxySSHAddr utils.NetAddr // ProxyKubeAddr points to the Kube address of the proxy ProxyKubeAddr utils.NetAddr // ProxyWebAddr points to the web (HTTPS) address of the proxy ProxyWebAddr utils.NetAddr // ProxyPublicAddr contains web proxy public addresses. ProxyPublicAddrs []utils.NetAddr // CipherSuites is the list of cipher suites Teleport suppports. CipherSuites []uint16 // FIPS mode means Teleport started in a FedRAMP/FIPS 140-2 compliant // configuration. FIPS bool // AccessPoint holds a cache to the Auth Server. AccessPoint auth.ProxyAccessPoint // Emitter is event emitter Emitter events.StreamEmitter // HostUUID is the UUID of this process. HostUUID string // Context is used to signal process exit. Context context.Context // StaticFS optionally specifies the HTTP file system to use. // Enables web UI if set. StaticFS http.FileSystem // CachedSessionLingeringThreshold specifies the time the session will linger // in the cache before getting purged after it has expired. // Defaults to cachedSessionLingeringThreshold if unspecified. CachedSessionLingeringThreshold *time.Duration // ClusterFeatures contains flags for supported/unsupported features. ClusterFeatures proto.Features // ProxySettings allows fetching the current proxy settings. ProxySettings proxySettingsGetter // MinimalReverseTunnelRoutesOnly mode handles only the endpoints required for // a reverse tunnel agent to establish a connection. MinimalReverseTunnelRoutesOnly bool // PublicProxyAddr is used to template the public proxy address // into the installer script responses PublicProxyAddr string // ALPNHandler is the ALPN connection handler for handling upgraded ALPN // connection through a HTTP upgrade call. ALPNHandler ConnectionHandler }
Config represents web handler configuration parameters
type ConnectionHandler ¶
ConnectionHandler defines a function for serving incoming connections.
type ContextHandler ¶
type ContextHandler func(w http.ResponseWriter, r *http.Request, p httprouter.Params, ctx *SessionContext) (interface{}, error)
ContextHandler is a handler called with the auth context, what means it is authenticated and ready to work
type CreateAppSessionRequest ¶
type CreateAppSessionRequest resolveAppParams
type CreateSessionReq ¶
type CreateSessionReq struct { // User is the Teleport username. User string `json:"user"` // Pass is the password. Pass string `json:"pass"` // SecondFactorToken is the OTP. SecondFactorToken string `json:"second_factor_token"` }
CreateSessionReq is a request to create session from username, password and second factor token.
type CreateSessionResponse ¶ added in v1.0.0
type CreateSessionResponse struct { // TokenType is token type (bearer) TokenType string `json:"type"` // Token value Token string `json:"token"` // TokenExpiresIn sets seconds before this token is not valid TokenExpiresIn int `json:"expires_in"` // SessionExpires is when this session expires. SessionExpires time.Time `json:"sessionExpires,omitempty"` // SessionInactiveTimeoutMS specifies how long in milliseconds // a user WebUI session can be left idle before being logged out // by the server. A zero value means there is no idle timeout set. SessionInactiveTimeoutMS int `json:"sessionInactiveTimeout"` }
CreateSessionResponse returns OAuth compabible data about access token: https://tools.ietf.org/html/rfc6749
func (*CreateSessionResponse) String ¶
func (r *CreateSessionResponse) String() string
String returns text description of this response
type Envelope ¶
type Envelope struct { // Version is the version of the protocol. Version string `protobuf:"bytes,1,opt,name=Version,proto3" json:"Version,omitempty"` // Type is the type of message. For version 1 of the protocol this must // not be longer than 1 character. Type string `protobuf:"bytes,2,opt,name=Type,proto3" json:"Type,omitempty"` // Payload is the actual data to send. Payload string `protobuf:"bytes,3,opt,name=Payload,proto3" json:"Payload,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` }
Envelope is used to wrap and transend and receive messages between the web client and proxy.
func (*Envelope) Descriptor ¶
func (*Envelope) GetPayload ¶
func (*Envelope) GetVersion ¶
func (*Envelope) MarshalToSizedBuffer ¶
func (*Envelope) ProtoMessage ¶
func (*Envelope) ProtoMessage()
func (*Envelope) XXX_DiscardUnknown ¶
func (m *Envelope) XXX_DiscardUnknown()
func (*Envelope) XXX_Marshal ¶
func (*Envelope) XXX_Unmarshal ¶
type GetAppFQDNRequest ¶
type GetAppFQDNRequest resolveAppParams
type GetAppFQDNResponse ¶
type GetAppFQDNResponse struct { // FQDN is application FQDN. FQDN string `json:"fqdn"` }
type Handler ¶ added in v1.0.0
type Handler struct { sync.Mutex httprouter.Router // ClusterFeatures contain flags for supported and unsupported features. ClusterFeatures proto.Features // contains filtered or unexported fields }
Handler is HTTP web proxy handler
func (*Handler) AuthenticateRequest ¶ added in v1.0.0
func (h *Handler) AuthenticateRequest(w http.ResponseWriter, r *http.Request, checkBearerToken bool) (*SessionContext, error)
AuthenticateRequest authenticates request using combination of a session cookie and bearer token
func (*Handler) GetProxyClient ¶
GetProxyClient returns authenticated auth server client
func (*Handler) ProxyHostPort ¶
ProxyHostPort returns the address of the proxy server using --proxy notation, i.e. "localhost:8030,8023"
func (*Handler) ProxyWithRoles ¶
func (h *Handler) ProxyWithRoles(ctx *SessionContext) (reversetunnel.Tunnel, error)
ProxyWithRoles returns a reverse tunnel proxy verifying the permissions of the given user.
func (*Handler) WithAuth ¶
func (h *Handler) WithAuth(fn ContextHandler) httprouter.Handle
WithAuth ensures that a request is authenticated.
func (*Handler) WithClusterAuth ¶
func (h *Handler) WithClusterAuth(fn ClusterHandler) httprouter.Handle
WithClusterAuth wraps a ClusterHandler to ensure that a request is authenticated to this proxy (the same as WithAuth), as well as to grab the RemoteSite (which can represent this local cluster or a remote trusted cluster) as specified by the ":site" url parameter.
func (*Handler) WithClusterClientProvider ¶
func (h *Handler) WithClusterClientProvider(fn ClusterClientHandler) httprouter.Handle
WithClusterClientProvider wraps a ClusterClientHandler to ensure that a request is authenticated to this proxy (the same as WithAuth), and passes a ClusterClientProvider so that the handler can access remote clusters. Use this instead of WithClusterAuth when the remote cluster cannot be encoded in the path or multiple clusters may need to be accessed from a single handler.
func (*Handler) WithMetaRedirect ¶
func (h *Handler) WithMetaRedirect(fn redirectHandlerFunc) httprouter.Handle
WithMetaRedirect is a handler that redirects to the path specified using HTML rather than HTTP. This is needed for redirects that can have a header size larger than 8kb, which some middlewares will drop. See https://github.com/gravitational/teleport/issues/7467.
func (*Handler) WithProvisionTokenAuth ¶
func (h *Handler) WithProvisionTokenAuth(fn ProvisionTokenHandler) httprouter.Handle
WithProvisionTokenAuth ensures that request is authenticated with a provision token. Provision tokens, when used like this are invalidated as soon as used. Doesn't matter if the underlying response was a success or an error.
func (*Handler) WithRedirect ¶
func (h *Handler) WithRedirect(fn redirectHandlerFunc) httprouter.Handle
WithRedirect is a handler that redirects to the path specified in the returned value.
type HandlerOption ¶ added in v1.0.0
HandlerOption is a functional argument - an option that can be passed to NewHandler function
func SetClock ¶
func SetClock(clock clockwork.Clock) HandlerOption
SetClock sets the clock on a handler
func SetSessionStreamPollPeriod ¶ added in v1.0.0
func SetSessionStreamPollPeriod(period time.Duration) HandlerOption
SetSessionStreamPollPeriod sets polling period for session streams
type JWKSResponse ¶
type ProvisionTokenHandler ¶
type ProvisionTokenHandler func(w http.ResponseWriter, r *http.Request, p httprouter.Params, site reversetunnel.RemoteSite, token types.ProvisionToken) (interface{}, error)
ProvisionTokenHandler is a authenticated handler that is called for some existing Token
type ResourceMap ¶ added in v1.2.6
type SSOCallbackResponse ¶
type SSOCallbackResponse struct { // CSRFToken is the token provided in the originating SSO login request // to be validated against. CSRFToken string // Username is the authenticated teleport username of the user that has // logged in, provided by the SSO provider. Username string // SessionName is the name of the session generated by auth server if // requested in the SSO request. SessionName string // ClientRedirectURL is the URL to redirect back to on completion of // the SSO login process. ClientRedirectURL string }
SSOCallbackResponse holds the parameters for validating and executing an SSO callback URL. See SSOSetWebSessionAndRedirectURL().
type SSORequestParams ¶
type SSORequestParams struct { // ClientRedirectURL is the URL specified in the query parameter // redirect_url, which will be unescaped here. ClientRedirectURL string // ConnectorID identifies the SSO connector to use to log in, from // the connector_id query parameter. ConnectorID string // CSRFToken is the token in the CSRF cookie header. CSRFToken string }
SSORequestParams holds parameters parsed out of a HTTP request initiating an SSO login. See ParseSSORequestParams().
func ParseSSORequestParams ¶
func ParseSSORequestParams(r *http.Request) (*SSORequestParams, error)
ParseSSORequestParams extracts the SSO request parameters from an http.Request, returning them in an SSORequestParams struct. If any fields are not present, an error is returned.
type SessionContext ¶ added in v1.0.0
type SessionContext struct {
// contains filtered or unexported fields
}
SessionContext is a context associated with a user's web session. An instance of the context is created for each web session generated for the user and provides a basic client cache for remote auth server connections.
func (*SessionContext) AddClosers ¶ added in v1.0.0
func (c *SessionContext) AddClosers(closers ...io.Closer)
AddClosers adds the specified closers to this context
func (*SessionContext) ClientTLSConfig ¶
func (c *SessionContext) ClientTLSConfig(clusterName ...string) (*tls.Config, error)
ClientTLSConfig returns client TLS authentication associated with the web session context
func (*SessionContext) Close ¶ added in v1.0.0
func (c *SessionContext) Close() error
Close cleans up resources associated with this context and removes it from the user context
func (*SessionContext) GetAgent ¶ added in v1.0.0
func (c *SessionContext) GetAgent() (agent.ExtendedAgent, *ssh.Certificate, error)
GetAgent returns agent that can be used to answer challenges for the web to ssh connection as well as certificate
func (*SessionContext) GetClient ¶ added in v1.0.0
func (c *SessionContext) GetClient() (auth.ClientI, error)
GetClient returns the client connected to the auth server
func (*SessionContext) GetClientConnection ¶
func (c *SessionContext) GetClientConnection() *grpc.ClientConn
GetClientConnection returns a connection to Auth Service
func (*SessionContext) GetIdentity ¶
func (c *SessionContext) GetIdentity() (*tlsca.Identity, error)
GetIdentity returns identity parsed from the session's TLS certificate.
func (*SessionContext) GetProxyListenerMode ¶
func (c *SessionContext) GetProxyListenerMode(ctx context.Context) (types.ProxyListenerMode, error)
GetProxyListenerMode returns cluster proxy listener mode form cluster networking config.
func (*SessionContext) GetSSHCertificate ¶
func (c *SessionContext) GetSSHCertificate() (*ssh.Certificate, error)
GetSSHCertificate returns the *ssh.Certificate associated with this session.
func (*SessionContext) GetSessionID ¶
func (c *SessionContext) GetSessionID() string
GetSessionID returns the ID of the underlying user web session.
func (*SessionContext) GetUser ¶ added in v1.0.0
func (c *SessionContext) GetUser() string
GetUser returns the authenticated teleport user
func (*SessionContext) GetUserAccessChecker ¶
func (c *SessionContext) GetUserAccessChecker() (services.AccessChecker, error)
GetUserAccessChecker returns AccessChecker derived from the SSH certificate associated with this session.
func (*SessionContext) GetUserClient ¶
func (c *SessionContext) GetUserClient(site reversetunnel.RemoteSite) (auth.ClientI, error)
GetUserClient will return an auth.ClientI with the role of the user at the requested site. If the site is local a client with the users local role is returned. If the site is remote a client with the users remote role is returned.
func (*SessionContext) GetX509Certificate ¶
func (c *SessionContext) GetX509Certificate() (*x509.Certificate, error)
GetX509Certificate returns the *x509.Certificate associated with this session.
func (*SessionContext) Invalidate ¶ added in v1.0.0
func (c *SessionContext) Invalidate(ctx context.Context) error
Invalidate invalidates this context by removing the underlying session and closing all underlying closers
func (*SessionContext) RemoveCloser ¶
func (c *SessionContext) RemoveCloser(closer io.Closer)
RemoveCloser removes the specified closer from this context
func (*SessionContext) String ¶
func (c *SessionContext) String() string
String returns the text representation of this context
type SessionCookie ¶ added in v1.0.0
SessionCookie stores information about active user and session
func DecodeCookie ¶
func DecodeCookie(b string) (*SessionCookie, error)
type TerminalHandler ¶
type TerminalHandler struct {
// contains filtered or unexported fields
}
TerminalHandler connects together an SSH session with a web-based terminal via a web socket.
func NewTerminal ¶
func NewTerminal(ctx context.Context, req TerminalRequest, authProvider AuthProvider, sessCtx *SessionContext) (*TerminalHandler, error)
NewTerminal creates a web-based terminal based on WebSockets and returns a new TerminalHandler.
func (*TerminalHandler) Serve ¶
func (t *TerminalHandler) Serve(w http.ResponseWriter, r *http.Request)
Serve builds a connect to the remote node and then pumps back two types of events: raw input/output events for what's happening on the terminal itself and audit log events relevant to this session.
type TerminalRequest ¶
type TerminalRequest struct { // Server describes a server to connect to (serverId|hostname[:port]). Server string `json:"server_id"` // Login is Linux username to connect as. Login string `json:"login"` // Term is the initial PTY size. Term session.TerminalParams `json:"term"` // SessionID is a Teleport session ID to join as. SessionID session.ID `json:"sid"` // Namespace is node namespace. Namespace string `json:"namespace"` // ProxyHostPort is the address of the server to connect to. ProxyHostPort string `json:"-"` // Cluster is the name of the remote cluster to connect to. Cluster string `json:"-"` // InteractiveCommand is a command to execut.e InteractiveCommand []string `json:"-"` // KeepAliveInterval is the interval for sending ping frames to web client. // This value is pulled from the cluster network config and // guaranteed to be set to a nonzero value as it's enforced by the configuration. KeepAliveInterval time.Duration }
TerminalRequest describes a request to create a web-based terminal to a remote SSH server.
type WebsocketIO ¶
func (*WebsocketIO) Close ¶
func (ws *WebsocketIO) Close() error