mirror of
https://github.com/sorenisanerd/gotty.git
synced 2024-11-21 20:14:24 +00:00
Add timeout option
This commit is contained in:
parent
c91fef051b
commit
8c9433ff21
5
.gotty
5
.gotty
@ -52,7 +52,10 @@
|
|||||||
|
|
||||||
// [int] Interval time to try reconnection (seconds)
|
// [int] Interval time to try reconnection (seconds)
|
||||||
// To enable reconnection, set `true` to `enable_reconnect`
|
// To enable reconnection, set `true` to `enable_reconnect`
|
||||||
// reconnect_time = false
|
// reconnect_time = 10
|
||||||
|
|
||||||
|
// [int] Timeout seconds for waiting a client (0 to disable)
|
||||||
|
// timeout = 60
|
||||||
|
|
||||||
// [int] Maximum connection to gotty, 0(default) means no limit.
|
// [int] Maximum connection to gotty, 0(default) means no limit.
|
||||||
// max_connection = 0
|
// max_connection = 0
|
||||||
|
@ -64,6 +64,7 @@ By default, GoTTY starts a web server at port 8080. Open the URL on your web bro
|
|||||||
--title-format "GoTTY - {{ .Command }} ({{ .Hostname }})" Title format of browser window [$GOTTY_TITLE_FORMAT]
|
--title-format "GoTTY - {{ .Command }} ({{ .Hostname }})" Title format of browser window [$GOTTY_TITLE_FORMAT]
|
||||||
--reconnect Enable reconnection [$GOTTY_RECONNECT]
|
--reconnect Enable reconnection [$GOTTY_RECONNECT]
|
||||||
--reconnect-time "10" Time to reconnect [$GOTTY_RECONNECT_TIME]
|
--reconnect-time "10" Time to reconnect [$GOTTY_RECONNECT_TIME]
|
||||||
|
--timeout "0" Timeout seconds for waiting a client (0 to disable) [$GOTTY_TIMEOUT]
|
||||||
--once Accept only one client and exit on disconnection [$GOTTY_ONCE]
|
--once Accept only one client and exit on disconnection [$GOTTY_ONCE]
|
||||||
--permit-arguments Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB) [$GOTTY_PERMIT_ARGUMENTS]
|
--permit-arguments Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB) [$GOTTY_PERMIT_ARGUMENTS]
|
||||||
--close-signal "1" Signal sent to the command process when gotty close it (default: SIGHUP) [$GOTTY_CLOSE_SIGNAL]
|
--close-signal "1" Signal sent to the command process when gotty close it (default: SIGHUP) [$GOTTY_CLOSE_SIGNAL]
|
||||||
|
45
app/app.go
45
app/app.go
@ -18,7 +18,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/braintree/manners"
|
"github.com/braintree/manners"
|
||||||
"github.com/elazarl/go-bindata-assetfs"
|
"github.com/elazarl/go-bindata-assetfs"
|
||||||
@ -43,8 +45,11 @@ type App struct {
|
|||||||
titleTemplate *template.Template
|
titleTemplate *template.Template
|
||||||
|
|
||||||
onceMutex *umutex.UnblockingMutex
|
onceMutex *umutex.UnblockingMutex
|
||||||
|
timer *time.Timer
|
||||||
|
|
||||||
connections int
|
// clientContext writes concurrently
|
||||||
|
// Use atomic operations.
|
||||||
|
connections *int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
@ -66,6 +71,7 @@ type Options struct {
|
|||||||
ReconnectTime int `hcl:"reconnect_time"`
|
ReconnectTime int `hcl:"reconnect_time"`
|
||||||
MaxConnection int `hcl:"max_connection"`
|
MaxConnection int `hcl:"max_connection"`
|
||||||
Once bool `hcl:"once"`
|
Once bool `hcl:"once"`
|
||||||
|
Timeout int `hcl:"timeout"`
|
||||||
PermitArguments bool `hcl:"permit_arguments"`
|
PermitArguments bool `hcl:"permit_arguments"`
|
||||||
CloseSignal int `hcl:"close_signal"`
|
CloseSignal int `hcl:"close_signal"`
|
||||||
Preferences HtermPrefernces `hcl:"preferences"`
|
Preferences HtermPrefernces `hcl:"preferences"`
|
||||||
@ -107,6 +113,8 @@ func New(command []string, options *Options) (*App, error) {
|
|||||||
return nil, errors.New("Title format string syntax error")
|
return nil, errors.New("Title format string syntax error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connections := int64(0)
|
||||||
|
|
||||||
return &App{
|
return &App{
|
||||||
command: command,
|
command: command,
|
||||||
options: options,
|
options: options,
|
||||||
@ -119,7 +127,8 @@ func New(command []string, options *Options) (*App, error) {
|
|||||||
|
|
||||||
titleTemplate: titleTemplate,
|
titleTemplate: titleTemplate,
|
||||||
|
|
||||||
onceMutex: umutex.New(),
|
onceMutex: umutex.New(),
|
||||||
|
connections: &connections,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +244,14 @@ func (app *App) Run() error {
|
|||||||
server,
|
server,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if app.options.Timeout > 0 {
|
||||||
|
app.timer = time.NewTimer(time.Duration(app.options.Timeout) * time.Second)
|
||||||
|
go func() {
|
||||||
|
<-app.timer.C
|
||||||
|
app.Exit()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if app.options.EnableTLS {
|
if app.options.EnableTLS {
|
||||||
crtFile := ExpandHomeDir(app.options.TLSCrtFile)
|
crtFile := ExpandHomeDir(app.options.TLSCrtFile)
|
||||||
keyFile := ExpandHomeDir(app.options.TLSKeyFile)
|
keyFile := ExpandHomeDir(app.options.TLSKeyFile)
|
||||||
@ -281,9 +298,24 @@ func (app *App) makeServer(addr string, handler *http.Handler) (*http.Server, er
|
|||||||
return server, nil
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *App) stopTimer() {
|
||||||
|
if app.options.Timeout > 0 {
|
||||||
|
app.timer.Stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *App) restartTimer() {
|
||||||
|
if app.options.Timeout > 0 {
|
||||||
|
app.timer.Reset(time.Duration(app.options.Timeout) * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (app *App) handleWS(w http.ResponseWriter, r *http.Request) {
|
func (app *App) handleWS(w http.ResponseWriter, r *http.Request) {
|
||||||
if app.options.MaxConnection != 0 {
|
app.stopTimer()
|
||||||
if app.connections >= app.options.MaxConnection {
|
|
||||||
|
connections := atomic.AddInt64(app.connections, 1)
|
||||||
|
if int64(app.options.MaxConnection) != 0 {
|
||||||
|
if connections >= int64(app.options.MaxConnection) {
|
||||||
log.Printf("Reached max connection: %d", app.options.MaxConnection)
|
log.Printf("Reached max connection: %d", app.options.MaxConnection)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -357,13 +389,12 @@ func (app *App) handleWS(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.connections++
|
|
||||||
if app.options.MaxConnection != 0 {
|
if app.options.MaxConnection != 0 {
|
||||||
log.Printf("Command is running for client %s with PID %d (args=%q), connections: %d/%d",
|
log.Printf("Command is running for client %s with PID %d (args=%q), connections: %d/%d",
|
||||||
r.RemoteAddr, cmd.Process.Pid, strings.Join(argv, " "), app.connections, app.options.MaxConnection)
|
r.RemoteAddr, cmd.Process.Pid, strings.Join(argv, " "), connections, app.options.MaxConnection)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Command is running for client %s with PID %d (args=%q), connections: %d",
|
log.Printf("Command is running for client %s with PID %d (args=%q), connections: %d",
|
||||||
r.RemoteAddr, cmd.Process.Pid, strings.Join(argv, " "), app.connections)
|
r.RemoteAddr, cmd.Process.Pid, strings.Join(argv, " "), connections)
|
||||||
}
|
}
|
||||||
|
|
||||||
context := &clientContext{
|
context := &clientContext{
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -69,6 +70,21 @@ func (context *clientContext) goHandleClient() {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer context.app.server.FinishRoutine()
|
defer context.app.server.FinishRoutine()
|
||||||
|
defer func() {
|
||||||
|
connections := atomic.AddInt64(context.app.connections, -1)
|
||||||
|
|
||||||
|
if context.app.options.MaxConnection != 0 {
|
||||||
|
log.Printf("Connection closed: %s, connections: %d/%d",
|
||||||
|
context.request.RemoteAddr, connections, context.app.options.MaxConnection)
|
||||||
|
} else {
|
||||||
|
log.Printf("Connection closed: %s, connections: %d",
|
||||||
|
context.request.RemoteAddr, connections)
|
||||||
|
}
|
||||||
|
|
||||||
|
if connections == 0 {
|
||||||
|
context.app.restartTimer()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
<-exit
|
<-exit
|
||||||
context.pty.Close()
|
context.pty.Close()
|
||||||
@ -79,14 +95,6 @@ func (context *clientContext) goHandleClient() {
|
|||||||
|
|
||||||
context.command.Wait()
|
context.command.Wait()
|
||||||
context.connection.Close()
|
context.connection.Close()
|
||||||
context.app.connections--
|
|
||||||
if context.app.options.MaxConnection != 0 {
|
|
||||||
log.Printf("Connection closed: %s, connections: %d/%d",
|
|
||||||
context.request.RemoteAddr, context.app.connections, context.app.options.MaxConnection)
|
|
||||||
} else {
|
|
||||||
log.Printf("Connection closed: %s, connections: %d",
|
|
||||||
context.request.RemoteAddr, context.app.connections)
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
main.go
1
main.go
@ -33,6 +33,7 @@ func main() {
|
|||||||
flag{"title-format", "", "Title format of browser window"},
|
flag{"title-format", "", "Title format of browser window"},
|
||||||
flag{"reconnect", "", "Enable reconnection"},
|
flag{"reconnect", "", "Enable reconnection"},
|
||||||
flag{"reconnect-time", "", "Time to reconnect"},
|
flag{"reconnect-time", "", "Time to reconnect"},
|
||||||
|
flag{"timeout", "", "Timeout seconds for waiting a client (0 to disable)"},
|
||||||
flag{"max-connection", "", "Maximum connection to gotty, 0(default) means no limit"},
|
flag{"max-connection", "", "Maximum connection to gotty, 0(default) means no limit"},
|
||||||
flag{"once", "", "Accept only one client and exit on disconnection"},
|
flag{"once", "", "Accept only one client and exit on disconnection"},
|
||||||
flag{"permit-arguments", "", "Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB)"},
|
flag{"permit-arguments", "", "Permit clients to send command line arguments in URL (e.g. http://example.com:8080/?arg=AAA&arg=BBB)"},
|
||||||
|
Loading…
Reference in New Issue
Block a user