4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-06 14:14:07 +00:00

Update vendor (#1297)

This commit is contained in:
Wim
2020-11-22 15:55:57 +01:00
committed by GitHub
parent cbb46293ab
commit 4cc2c914e6
166 changed files with 25790 additions and 14376 deletions

View File

@ -7,7 +7,7 @@ import (
const minInt = -int(^uint(0)>>1) - 1
// The error returned when the read rate exceeds our specification.
// ErrRateExceeded is the error returned when the read rate exceeds our specification.
var ErrRateExceeded = errors.New("Read rate exceeded.")
// Limiter is an interface for a rate limiter.
@ -27,7 +27,7 @@ type simpleLimiter struct {
}
// NewSimpleLimiter creates a Limiter that restricts a given number of bytes per frequency.
func NewSimpleLimiter(amount int, frequency time.Duration) Limiter {
func NewSimpleLimiter(amount int, frequency time.Duration) *simpleLimiter {
return &simpleLimiter{
Amount: amount,
Frequency: frequency,
@ -38,7 +38,7 @@ func NewSimpleLimiter(amount int, frequency time.Duration) Limiter {
// SimpleLimiter but adds a grace period at the start of the rate
// limiting where it allows unlimited bytes to be read during that
// period.
func NewGracefulLimiter(amount int, frequency time.Duration, grace time.Duration) Limiter {
func NewGracefulLimiter(amount int, frequency time.Duration, grace time.Duration) *simpleLimiter {
return &simpleLimiter{
Amount: amount,
Frequency: frequency,
@ -60,3 +60,12 @@ func (limit *simpleLimiter) Count(n int) error {
}
return nil
}
// Delay returns a channel that can be used to block until next window
func (limit *simpleLimiter) Delay() <-chan time.Time {
waitTill := time.Now()
if limit.numRead >= limit.Amount {
waitTill = waitTill.Add(limit.Frequency)
}
return time.NewTimer(time.Until(waitTill)).C
}

View File

@ -19,6 +19,7 @@ type Auth interface {
}
// MakeAuth makes an ssh.ServerConfig which performs authentication against an Auth implementation.
// TODO: Switch to using ssh.AuthMethod instead?
func MakeAuth(auth Auth) *ssh.ServerConfig {
config := ssh.ServerConfig{
NoClientAuth: false,

View File

@ -6,8 +6,8 @@ import "encoding/binary"
// parsePtyRequest parses the payload of the pty-req message and extracts the
// dimensions of the terminal. See RFC 4254, section 6.2.
func parsePtyRequest(s []byte) (width, height int, ok bool) {
_, s, ok = parseString(s)
func parsePtyRequest(s []byte) (term string, width, height int, ok bool) {
term, s, ok = parseString(s)
if !ok {
return
}

View File

@ -55,6 +55,29 @@ func (c sshConn) Name() string {
return c.User()
}
// EnvVar is an environment variable key-value pair
type EnvVar struct {
Key string
Value string
}
func (v EnvVar) String() string {
return v.Key + "=" + v.Value
}
// Env is a wrapper type around []EnvVar with some helper methods
type Env []EnvVar
// Get returns the latest value for a given key, or empty string if not found
func (e Env) Get(key string) string {
for i := len(e) - 1; i >= 0; i-- {
if e[i].Key == key {
return e[i].Value
}
}
return ""
}
// Terminal extends ssh/terminal to include a close method
type Terminal struct {
terminal.Terminal
@ -63,9 +86,14 @@ type Terminal struct {
done chan struct{}
closeOnce sync.Once
mu sync.Mutex
env []EnvVar
term string
}
// Make new terminal from a session channel
// TODO: For v2, make a separate `Serve(ctx context.Context) error` method to activate the Terminal
func NewTerminal(conn *ssh.ServerConn, ch ssh.NewChannel) (*Terminal, error) {
if ch.ChannelType() != "session" {
return nil, ErrNotSessionChannel
@ -75,14 +103,15 @@ func NewTerminal(conn *ssh.ServerConn, ch ssh.NewChannel) (*Terminal, error) {
return nil, err
}
term := Terminal{
Terminal: *terminal.NewTerminal(channel, "Connecting..."),
Terminal: *terminal.NewTerminal(channel, ""),
Conn: sshConn{conn},
Channel: channel,
done: make(chan struct{}),
}
go term.listen(requests)
ready := make(chan struct{})
go term.listen(requests, ready)
go func() {
// Keep-Alive Ticker
@ -103,7 +132,18 @@ func NewTerminal(conn *ssh.ServerConn, ch ssh.NewChannel) (*Terminal, error) {
}
}()
return &term, nil
// We need to wait for term.ready to acquire a shell before we return, this
// gives the SSH session a chance to populate the env vars and other state.
// TODO: Make the timeout configurable
// TODO: Use context.Context for abort/timeout in the future, will need to change the API.
select {
case <-ready: // shell acquired
return &term, nil
case <-term.done:
return nil, errors.New("terminal aborted")
case <-time.NewTimer(time.Minute).C:
return nil, errors.New("timed out starting terminal")
}
}
// NewSession Finds a session channel and make a Terminal from it
@ -133,8 +173,9 @@ func (t *Terminal) Close() error {
return err
}
// Negotiate terminal type and settings
func (t *Terminal) listen(requests <-chan *ssh.Request) {
// listen negotiates the terminal type and state
// ready is closed when the terminal is ready.
func (t *Terminal) listen(requests <-chan *ssh.Request, ready chan<- struct{}) {
hasShell := false
for req := range requests {
@ -146,13 +187,19 @@ func (t *Terminal) listen(requests <-chan *ssh.Request) {
if !hasShell {
ok = true
hasShell = true
close(ready)
}
case "pty-req":
width, height, ok = parsePtyRequest(req.Payload)
var term string
term, width, height, ok = parsePtyRequest(req.Payload)
if ok {
// TODO: Hardcode width to 100000?
err := t.SetSize(width, height)
ok = err == nil
// Save the term:
t.mu.Lock()
t.term = term
t.mu.Unlock()
}
case "window-change":
width, height, ok = parseWinchRequest(req.Payload)
@ -161,6 +208,14 @@ func (t *Terminal) listen(requests <-chan *ssh.Request) {
err := t.SetSize(width, height)
ok = err == nil
}
case "env":
var v EnvVar
if err := ssh.Unmarshal(req.Payload, &v); err == nil {
t.mu.Lock()
t.env = append(t.env, v)
t.mu.Unlock()
ok = true
}
}
if req.WantReply {
@ -168,3 +223,24 @@ func (t *Terminal) listen(requests <-chan *ssh.Request) {
}
}
}
// Env returns a list of environment key-values that have been set. They are
// returned in the order that they have been set, there is no deduplication or
// other pre-processing applied.
func (t *Terminal) Env() Env {
t.mu.Lock()
defer t.mu.Unlock()
return Env(t.env)
}
// Term returns the terminal string value as set by the pty.
// If there was no pty request, it falls back to the TERM value passed in as an
// Env variable.
func (t *Terminal) Term() string {
t.mu.Lock()
defer t.mu.Unlock()
if t.term != "" {
return t.term
}
return Env(t.env).Get("TERM")
}

View File

@ -10,6 +10,8 @@ import (
"strconv"
"sync"
"unicode/utf8"
"golang.org/x/text/width"
)
// EscapeCodes contains escape sequences that can be written to the terminal in
@ -262,7 +264,7 @@ func (t *Terminal) moveCursorToPos(pos int) {
return
}
x := visualLength(t.prompt) + pos
x := visualLength(t.prompt) + visualLength(t.line[:pos])
y := x / t.termWidth
x = x % t.termWidth
@ -351,6 +353,7 @@ func (t *Terminal) setLine(newLine []rune, newPos int) {
for i := len(newLine); i < len(t.line); i++ {
t.writeLine(space)
}
t.line = newLine
t.moveCursorToPos(newPos)
}
t.line = newLine
@ -462,6 +465,10 @@ func visualLength(runes []rune) int {
inEscapeSeq = true
default:
length++
kind := width.LookupRune(r).Kind()
if kind == width.EastAsianFullwidth || kind == width.EastAsianWide {
length++
}
}
}