Documentation ¶
Overview ¶
Package guac implements a HTTP client and a WebSocket client that connects to an Apache Guacamole server.
Index ¶
- Constants
- type Config
- type CountedLock
- type ErrGuac
- type ErrKind
- type Instruction
- type InstructionReader
- type LastAccessedTunnel
- type MemorySessionStore
- type MessageReader
- type MessageWriter
- type Server
- type SimpleTunnel
- func (t *SimpleTunnel) AcquireReader() InstructionReader
- func (t *SimpleTunnel) AcquireWriter() io.Writer
- func (t *SimpleTunnel) Close() (err error)
- func (t *SimpleTunnel) ConnectionID() string
- func (t *SimpleTunnel) GetUUID() string
- func (t *SimpleTunnel) HasQueuedReaderThreads() bool
- func (t *SimpleTunnel) HasQueuedWriterThreads() bool
- func (t *SimpleTunnel) ReleaseReader()
- func (t *SimpleTunnel) ReleaseWriter()
- type Status
- type Stream
- func (s *Stream) AssertOpcode(opcode string) (instruction *Instruction, err error)
- func (s *Stream) Available() bool
- func (s *Stream) Close() error
- func (s *Stream) Flush()
- func (s *Stream) Handshake(config *Config) error
- func (s *Stream) ReadSome() (instruction []byte, err error)
- func (s *Stream) Write(data []byte) (n int, err error)
- type Tunnel
- type TunnelMap
- type WebsocketServer
Constants ¶
const ( SocketTimeout = 15 * time.Second MaxGuacMessage = 8192 // TODO is this bytes or runes? )
const InternalDataOpcode = ""
The Guacamole protocol instruction Opcode reserved for arbitrary internal use by tunnel implementations. The value of this Opcode is guaranteed to be the empty string (""). Tunnel implementations may use this Opcode for any purpose. It is currently used by the HTTP tunnel to mark the end of the HTTP response, and by the WebSocket tunnel to transmit the tunnel UUID.
const TunnelTimeout = 15 * time.Second
TunnelTimeout is the number of seconds to wait between tunnel accesses before timing out. Note that this will be enforced only within a factor of 2. If a tunnel is unused, it will take between TUNNEL_TIMEOUT and TUNNEL_TIMEOUT*2 seconds before that tunnel is closed and removed.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { // ConnectionID is used to reconnect to an existing session, otherwise leave blank for a new session. ConnectionID string // Protocol is the protocol of the connection from guacd to the remote (rdp, ssh, etc). Protocol string // Parameters are used to configure protocol specific options like sla for rdp or terminal color schemes. Parameters map[string]string // OptimalScreenWidth is the desired width of the screen OptimalScreenWidth int // OptimalScreenHeight is the desired height of the screen OptimalScreenHeight int // OptimalResolution is the desired resolution of the screen OptimalResolution int // AudioMimetypes is an array of the supported audio types AudioMimetypes []string // VideoMimetypes is an array of the supported video types VideoMimetypes []string // ImageMimetypes is an array of the supported image types ImageMimetypes []string }
Config is the data sent to guacd to configure the session during the handshake.
func NewGuacamoleConfiguration ¶
func NewGuacamoleConfiguration() *Config
NewGuacamoleConfiguration returns a Config with sane defaults
type CountedLock ¶
type CountedLock struct {
// contains filtered or unexported fields
}
CountedLock counts how many goroutines are waiting on the lock
func (*CountedLock) HasQueued ¶
func (r *CountedLock) HasQueued() bool
HasQueued returns true if a goroutine is waiting on the lock
type ErrKind ¶
type ErrKind int
const ( ErrClientBadType ErrKind = iota ErrClient ErrClientOverrun ErrClientTimeout ErrClientTooMany ErrConnectionClosed ErrOther ErrResourceClosed ErrResourceConflict ErrResourceNotFound ErrSecurity ErrServerBusy ErrServer ErrSessionClosed ErrSessionConflict ErrSessionTimeout ErrUnsupported ErrUpstream ErrUpstreamNotFound ErrUpstreamTimeout )
type Instruction ¶
Instruction represents a Guacamole instruction
func NewInstruction ¶
func NewInstruction(opcode string, args ...string) *Instruction
NewInstruction creates an instruction
func Parse ¶ added in v1.3.0
func Parse(buf []byte) (*Instruction, error)
func ReadOne ¶
func ReadOne(stream *Stream) (instruction *Instruction, err error)
ReadOne takes an instruction from the stream and parses it into an Instruction
func (*Instruction) Byte ¶
func (i *Instruction) Byte() []byte
func (*Instruction) String ¶
func (i *Instruction) String() string
String returns the on-wire representation of the instruction
type InstructionReader ¶
type InstructionReader interface { // ReadSome returns the next complete guacd message from the stream ReadSome() ([]byte, error) // Available returns true if there are bytes buffered in the stream Available() bool // Flush resets the internal buffer for reuse Flush() }
InstructionReader provides reading functionality to a Stream
type LastAccessedTunnel ¶
LastAccessedTunnel tracks the last time a particular Tunnel was accessed. This information is not necessary for tunnels associated with WebSocket connections, as each WebSocket connection has its own read thread which continuously checks the state of the tunnel and which will automatically timeout when the underlying stream times out, but the HTTP tunnel has no such thread. Because the HTTP tunnel requires the stream to be split across multiple requests, tracking of activity on the tunnel must be performed independently of the HTTP requests.
func NewLastAccessedTunnel ¶
func NewLastAccessedTunnel(tunnel Tunnel) (ret LastAccessedTunnel)
func (*LastAccessedTunnel) Access ¶
func (t *LastAccessedTunnel) Access()
func (*LastAccessedTunnel) GetLastAccessedTime ¶
func (t *LastAccessedTunnel) GetLastAccessedTime() time.Time
type MemorySessionStore ¶
MemorySessionStore is a simple in-memory store of connected sessions that is used by the WebsocketServer to store active sessions.
func NewMemorySessionStore ¶
func NewMemorySessionStore() *MemorySessionStore
NewMemorySessionStore creates a new store
func (*MemorySessionStore) Add ¶
func (s *MemorySessionStore) Add(id string, req *http.Request)
Add inserts a new connection by uuid
func (*MemorySessionStore) Delete ¶
func (s *MemorySessionStore) Delete(id string, req *http.Request, tunnel Tunnel)
Delete removes a connection by uuid
func (*MemorySessionStore) Get ¶
func (s *MemorySessionStore) Get(id string) int
Get returns a connection by uuid
type MessageReader ¶
type MessageReader interface { // ReadMessage should return a single complete message to send to guac ReadMessage() (int, []byte, error) }
MessageReader wraps a websocket connection and only permits Reading
type MessageWriter ¶
type MessageWriter interface { // WriteMessage writes one or more complete guac commands to the websocket WriteMessage(int, []byte) error }
MessageWriter wraps a websocket connection and only permits Writing
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server uses HTTP requests to talk to guacd (as opposed to WebSockets in ws_server.go)
type SimpleTunnel ¶
type SimpleTunnel struct {
// contains filtered or unexported fields
}
Base Tunnel implementation which synchronizes access to the underlying reader and writer with locks
func NewSimpleTunnel ¶
func NewSimpleTunnel(stream *Stream) *SimpleTunnel
NewSimpleTunnel creates a new tunnel
func (*SimpleTunnel) AcquireReader ¶
func (t *SimpleTunnel) AcquireReader() InstructionReader
AcquireReader acquires the reader lock
func (*SimpleTunnel) AcquireWriter ¶
func (t *SimpleTunnel) AcquireWriter() io.Writer
AcquireWriter locks the writer lock
func (*SimpleTunnel) Close ¶
func (t *SimpleTunnel) Close() (err error)
Close closes the underlying stream
func (*SimpleTunnel) ConnectionID ¶
func (t *SimpleTunnel) ConnectionID() string
ConnectionID returns the underlying Guacamole connection ID
func (*SimpleTunnel) GetUUID ¶
func (t *SimpleTunnel) GetUUID() string
GetUUID returns the tunnel's UUID
func (*SimpleTunnel) HasQueuedReaderThreads ¶
func (t *SimpleTunnel) HasQueuedReaderThreads() bool
HasQueuedReaderThreads returns true if more than one goroutine is trying to read
func (*SimpleTunnel) HasQueuedWriterThreads ¶
func (t *SimpleTunnel) HasQueuedWriterThreads() bool
HasQueuedWriterThreads returns true if more than one goroutine is trying to write
func (*SimpleTunnel) ReleaseReader ¶
func (t *SimpleTunnel) ReleaseReader()
ReleaseReader releases the reader
func (*SimpleTunnel) ReleaseWriter ¶
func (t *SimpleTunnel) ReleaseWriter()
ReleaseWriter releases the writer lock
type Status ¶
type Status int
const ( // Undefined Add to instead null Undefined Status = -1 // Success indicates the operation succeeded. Success Status = iota // Unsupported indicates the requested operation is unsupported. Unsupported // ServerError indicates the operation could not be performed due to an internal failure. ServerError // ServerBusy indicates the operation could not be performed as the server is busy. ServerBusy // UpstreamTimeout indicates the operation could not be performed because the upstream server is not responding. UpstreamTimeout // UpstreamError indicates the operation was unsuccessful due to an error or otherwise unexpected // condition of the upstream server. UpstreamError // ResourceNotFound indicates the operation could not be performed as the requested resource does not exist. ResourceNotFound // ResourceConflict indicates the operation could not be performed as the requested resource is already in use. ResourceConflict // ResourceClosed indicates the operation could not be performed as the requested resource is now closed. ResourceClosed // UpstreamNotFound indicates the operation could not be performed because the upstream server does // not appear to exist. UpstreamNotFound // available to service the request. UpstreamUnavailable // SessionConflict indicates the session within the upstream server has ended because it conflicted // with another session. SessionConflict // SessionTimeout indicates the session within the upstream server has ended because it appeared to be inactive. SessionTimeout // SessionClosed indicates the session within the upstream server has been forcibly terminated. SessionClosed // ClientBadRequest indicates the operation could not be performed because bad parameters were given. ClientBadRequest ClientUnauthorized // ClientForbidden indicates the user is not allowed to do the operation. ClientForbidden // ClientTimeout indicates the client took too long to respond. ClientTimeout // ClientOverrun indicates the client sent too much data. ClientOverrun // ClientBadType indicates the client sent data of an unsupported or unexpected type. ClientBadType // ClientTooMany indivates the operation failed because the current client is already using too many resources. ClientTooMany )
func FromGuacamoleStatusCode ¶
FromGuacamoleStatusCode returns the Status corresponding to the given Guacamole protocol Status code.
func (Status) GetGuacamoleStatusCode ¶
GetGuacamoleStatusCode returns the corresponding Guacamole protocol Status code.
func (Status) GetHTTPStatusCode ¶
GetHTTPStatusCode returns the most applicable HTTP error code.
func (Status) GetWebSocketCode ¶
GetWebSocketCode returns the most applicable HTTP error code.
type Stream ¶
type Stream struct { // ConnectionID is the ID Guacamole gives and can be used to reconnect or share sessions ConnectionID string // contains filtered or unexported fields }
Stream wraps the connection to Guacamole providing timeouts and reading a single instruction at a time (since returning partial instructions would be an error)
func (*Stream) AssertOpcode ¶
func (s *Stream) AssertOpcode(opcode string) (instruction *Instruction, err error)
AssertOpcode checks the next opcode in the stream matches what is expected. Useful during handshake.
type Tunnel ¶
type Tunnel interface { // AcquireReader returns a reader to the tunnel if it isn't locked AcquireReader() InstructionReader // ReleaseReader releases the lock on the reader ReleaseReader() // HasQueuedReaderThreads returns true if there is a reader locked HasQueuedReaderThreads() bool // AcquireWriter returns a writer to the tunnel if it isn't locked AcquireWriter() io.Writer // ReleaseWriter releases the lock on the writer ReleaseWriter() // HasQueuedWriterThreads returns true if there is a writer locked HasQueuedWriterThreads() bool // GetUUID returns the uuid of the tunnel GetUUID() string // ConnectionId returns the guacd Connection ID of the tunnel ConnectionID() string // Close closes the tunnel Close() error }
Tunnel provides a unique identifier and synchronized access to the InstructionReader and Writer associated with a Stream.
type TunnelMap ¶
TunnelMap tracks in-use HTTP tunnels, automatically removing and closing tunnels which have not been used recently. This class is intended for use only within the Server implementation, and has no real utility outside that implementation.
func NewTunnelMap ¶
func NewTunnelMap() *TunnelMap
NewTunnelMap creates a new TunnelMap and starts the scheduled job with the default timeout.
func (*TunnelMap) Get ¶
func (m *TunnelMap) Get(uuid string) (tunnel *LastAccessedTunnel, ok bool)
Get returns the Tunnel having the given UUID, wrapped within a LastAccessedTunnel.
func (*TunnelMap) Put ¶
Add registers that a new connection has been established using HTTP via the given Tunnel.
type WebsocketServer ¶
type WebsocketServer struct { // OnConnect is an optional callback called when a websocket connects. // Deprecated: use OnConnectWs OnConnect func(string, *http.Request) // OnDisconnect is an optional callback called when the websocket disconnects. // Deprecated: use OnDisconnectWs OnDisconnect func(string, *http.Request, Tunnel) // OnConnectWs is an optional callback called when a websocket connects. OnConnectWs func(string, *websocket.Conn, *http.Request) // OnDisconnectWs is an optional callback called when the websocket disconnects. OnDisconnectWs func(string, *websocket.Conn, *http.Request, Tunnel) // contains filtered or unexported fields }
WebsocketServer implements a websocket-based connection to guacd.
func NewWebsocketServer ¶
func NewWebsocketServer(connect func(*http.Request) (Tunnel, error)) *WebsocketServer
NewWebsocketServer creates a new server with a simple connect method.
func NewWebsocketServerWs ¶ added in v1.2.0
func NewWebsocketServerWs(connect func(*websocket.Conn, *http.Request) (Tunnel, error)) *WebsocketServer
NewWebsocketServerWs creates a new server with a connect method that takes a websocket.
func (*WebsocketServer) ServeHTTP ¶
func (s *WebsocketServer) ServeHTTP(w http.ResponseWriter, r *http.Request)