mirror of
https://github.com/sorenisanerd/gotty.git
synced 2024-11-24 21:04:24 +00:00
Merge profile and config files and support custom index file
This commit is contained in:
parent
25a5bc0b89
commit
d3e48aa3ae
19
Makefile
19
Makefile
@ -3,7 +3,7 @@ gotty: app/resource.go main.go app/*.go
|
||||
|
||||
resource: app/resource.go
|
||||
|
||||
app/resource.go: bindata/static/hterm.js bindata/static/gotty.js bindata/static/index.html
|
||||
app/resource.go: bindata/static/js/hterm.js bindata/static/js/gotty.js bindata/static/index.html
|
||||
go-bindata -prefix bindata -pkg app -ignore=\\.gitkeep -o app/resource.go bindata/...
|
||||
gofmt -w app/resource.go
|
||||
|
||||
@ -13,12 +13,15 @@ bindata:
|
||||
bindata/static: bindata
|
||||
mkdir bindata/static
|
||||
|
||||
bindata/static/hterm.js: bindata/static libapps/hterm/js/*.js
|
||||
cd libapps && \
|
||||
LIBDOT_SEARCH_PATH=`pwd` ./libdot/bin/concat.sh -i ./hterm/concat/hterm_all.concat -o ../bindata/static/hterm.js
|
||||
|
||||
bindata/static/gotty.js: bindata/static resources/gotty.js
|
||||
cp resources/gotty.js bindata/static/gotty.js
|
||||
|
||||
bindata/static/index.html: bindata/static resources/index.html
|
||||
cp resources/index.html bindata/static/index.html
|
||||
|
||||
bindata/static/js: bindata/static
|
||||
mkdir bindata/static/js
|
||||
|
||||
bindata/static/js/hterm.js: bindata/static/js libapps/hterm/js/*.js
|
||||
cd libapps && \
|
||||
LIBDOT_SEARCH_PATH=`pwd` ./libdot/bin/concat.sh -i ./hterm/concat/hterm_all.concat -o ../bindata/static/js/hterm.js
|
||||
|
||||
bindata/static/js/gotty.js: bindata/static/js resources/gotty.js
|
||||
cp resources/gotty.js bindata/static/js/gotty.js
|
||||
|
32
README.md
32
README.md
@ -58,26 +58,36 @@ By default, gotty starts a web server at port 8080. Open the URL on your web bro
|
||||
--tls, -t Enable TLS/SSL [$GOTTY_TLS]
|
||||
--tls-crt "~/.gotty.key" TLS/SSL crt file path [$GOTTY_TLS_CRT]
|
||||
--tls-key "~/.gotty.crt" TLS/SSL key file path [$GOTTY_TLS_KEY]
|
||||
--profile "~/.gotty.prf" Profile file path [$GOTTY_PROFILE]
|
||||
--index Custom index file [$GOTTY_INDEX]
|
||||
--title-format "GoTTY - {{ .Command }} ({{ .Hostname }})" Title format of browser window [$GOTTY_TITLE_FORMAT]
|
||||
--reconnect Enable reconnection [$GOTTY_RECONNECT]
|
||||
--reconnect-time "10" Time to reconnect [$GOTTY_RECONNECT_TIME]
|
||||
--once Accept only one client and exit on disconnection [$GOTTY_ONCE]
|
||||
--config "~/.gotty" Config file path [$GOTTY_CONFIG]
|
||||
```
|
||||
|
||||
### Profile File
|
||||
|
||||
You can customize your terminal (hterm) by providing a profile file to the `gotty` command, which is a HCL file that has a map of preference keys and values. Gotty loads a profile file at `~/.gotty` by default when it exists.
|
||||
|
||||
The following example makes the font size smaller and the background color a little bit blue.
|
||||
--version, -v print the version
|
||||
|
||||
```
|
||||
font-size = 5,
|
||||
background-color = "rgb(16, 16, 32)"
|
||||
|
||||
### Config File
|
||||
|
||||
You can customize default options and your terminal (hterm) by providing a config file to the `gotty` command. Gotty loads a profile file at `~/.gotty` by default when it exists.
|
||||
|
||||
```
|
||||
// Listen at port 9000 by default
|
||||
port = "9000"
|
||||
|
||||
// Enable TSL/SSL by default
|
||||
enable_tls = true
|
||||
|
||||
// hterm preferences
|
||||
// Smaller font and a little bit bluer background color
|
||||
preferences {
|
||||
font_size = 5,
|
||||
background_color = "rgb(16, 16, 32)"
|
||||
}
|
||||
```
|
||||
|
||||
Available preferences are listed in [the hterm source code](https://chromium.googlesource.com/apps/libapps/+/master/hterm/js/hterm_preference_manager.js)
|
||||
Available hterm preference options are listed in [the hterm source code](https://chromium.googlesource.com/apps/libapps/+/master/hterm/js/hterm_preference_manager.js). Note that hifens (`-`) in the preference names must be replaced by underscores (`_`).
|
||||
|
||||
### Security Options
|
||||
|
||||
|
67
app/app.go
67
app/app.go
@ -32,7 +32,6 @@ type App struct {
|
||||
upgrader *websocket.Upgrader
|
||||
server *manners.GracefulServer
|
||||
|
||||
preferences map[string]interface{}
|
||||
titleTemplate *template.Template
|
||||
}
|
||||
|
||||
@ -44,7 +43,7 @@ type Options struct {
|
||||
Credential string
|
||||
EnableRandomUrl bool
|
||||
RandomUrlLength int
|
||||
ProfileFile string
|
||||
IndexFile string
|
||||
EnableTLS bool
|
||||
TLSCrtFile string
|
||||
TLSKeyFile string
|
||||
@ -52,6 +51,7 @@ type Options struct {
|
||||
EnableReconnect bool
|
||||
ReconnectTime int
|
||||
Once bool
|
||||
Preferences map[string]interface{}
|
||||
}
|
||||
|
||||
var DefaultOptions = Options{
|
||||
@ -62,7 +62,7 @@ var DefaultOptions = Options{
|
||||
Credential: "",
|
||||
EnableRandomUrl: false,
|
||||
RandomUrlLength: 8,
|
||||
ProfileFile: "~/.gotty.prf",
|
||||
IndexFile: "",
|
||||
EnableTLS: false,
|
||||
TLSCrtFile: "~/.gotty.key",
|
||||
TLSKeyFile: "~/.gotty.crt",
|
||||
@ -70,6 +70,7 @@ var DefaultOptions = Options{
|
||||
EnableReconnect: false,
|
||||
ReconnectTime: 10,
|
||||
Once: false,
|
||||
Preferences: make(map[string]interface{}),
|
||||
}
|
||||
|
||||
func New(command []string, options *Options) (*App, error) {
|
||||
@ -78,11 +79,6 @@ func New(command []string, options *Options) (*App, error) {
|
||||
return nil, errors.New("Title format string syntax error")
|
||||
}
|
||||
|
||||
prefMap, err := loadProfileFile(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &App{
|
||||
command: command,
|
||||
options: options,
|
||||
@ -93,7 +89,6 @@ func New(command []string, options *Options) (*App, error) {
|
||||
Subprotocols: []string{"gotty"},
|
||||
},
|
||||
|
||||
preferences: prefMap,
|
||||
titleTemplate: titleTemplate,
|
||||
}, nil
|
||||
}
|
||||
@ -126,12 +121,25 @@ func applyConfigFile(options *Options, filePath string) error {
|
||||
if val, ok := config[configName]; ok {
|
||||
field, ok := o.FieldOk(name)
|
||||
if !ok {
|
||||
return errors.New("No such field: " + name)
|
||||
return errors.New("No such option: " + name)
|
||||
}
|
||||
err := field.Set(val)
|
||||
|
||||
var err error
|
||||
if name == "Preferences" {
|
||||
prefs := val.([]map[string]interface{})[0]
|
||||
htermPrefs := make(map[string]interface{})
|
||||
for key, value := range prefs {
|
||||
htermPrefs[strings.Replace(key, "_", "-", -1)] = value
|
||||
}
|
||||
err = field.Set(htermPrefs)
|
||||
} else {
|
||||
err = field.Set(val)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,28 +154,6 @@ func ExpandHomeDir(path string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func loadProfileFile(options *Options) (map[string]interface{}, error) {
|
||||
prefString := []byte{}
|
||||
prefPath := options.ProfileFile
|
||||
if options.ProfileFile == DefaultOptions.ProfileFile {
|
||||
prefPath = os.Getenv("HOME") + "/.gotty.prf"
|
||||
}
|
||||
if _, err := os.Stat(prefPath); os.IsNotExist(err) {
|
||||
if options.ProfileFile != DefaultOptions.ProfileFile {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
log.Printf("Loading profile path: %s", prefPath)
|
||||
prefString, _ = ioutil.ReadFile(prefPath)
|
||||
}
|
||||
var prefMap map[string]interface{}
|
||||
err := hcl.Decode(&prefMap, string(prefString))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return prefMap, nil
|
||||
}
|
||||
|
||||
func (app *App) Run() error {
|
||||
if app.options.PermitWrite {
|
||||
log.Printf("Permitting clients to write input to the PTY.")
|
||||
@ -190,7 +176,20 @@ func (app *App) Run() error {
|
||||
}
|
||||
|
||||
var siteMux = http.NewServeMux()
|
||||
siteMux.Handle(path+"/", http.StripPrefix(path+"/", staticHandler))
|
||||
|
||||
if app.options.IndexFile != "" {
|
||||
log.Printf("Using index file at " + app.options.IndexFile)
|
||||
indexHandler := http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, ExpandHomeDir(app.options.IndexFile))
|
||||
},
|
||||
)
|
||||
siteMux.Handle(path+"/", indexHandler)
|
||||
} else {
|
||||
siteMux.Handle(path+"/", http.StripPrefix(path+"/", staticHandler))
|
||||
}
|
||||
|
||||
siteMux.Handle(path+"/js/", http.StripPrefix(path+"/", staticHandler))
|
||||
siteMux.Handle(path+"/ws", wsHandler)
|
||||
|
||||
siteHandler := http.Handler(siteMux)
|
||||
|
@ -126,7 +126,7 @@ func (context *clientContext) sendInitialize() error {
|
||||
}
|
||||
writer.Close()
|
||||
|
||||
prefs, _ := json.Marshal(context.app.preferences)
|
||||
prefs, _ := json.Marshal(context.app.options.Preferences)
|
||||
context.connection.WriteMessage(
|
||||
websocket.TextMessage,
|
||||
append([]byte{SetPreferences}, prefs...),
|
||||
|
File diff suppressed because one or more lines are too long
4
main.go
4
main.go
@ -28,7 +28,7 @@ func main() {
|
||||
flag{"tls", "t", "Enable TLS/SSL"},
|
||||
flag{"tls-crt", "", "TLS/SSL crt file path"},
|
||||
flag{"tls-key", "", "TLS/SSL key file path"},
|
||||
flag{"profile", "", "Profile file path"},
|
||||
flag{"index", "", "Custom index file"},
|
||||
flag{"title-format", "", "Title format of browser window"},
|
||||
flag{"reconnect", "", "Enable reconnection"},
|
||||
flag{"reconnect-time", "", "Time to reconnect"},
|
||||
@ -36,7 +36,7 @@ func main() {
|
||||
}
|
||||
|
||||
mappingHint := map[string]string{
|
||||
"profile": "ProfileFile",
|
||||
"index": "IndexFile",
|
||||
"tls": "EnableTLS",
|
||||
"tls-crt": "TLSCrtFile",
|
||||
"tls-key": "TLSKeyFile",
|
||||
|
@ -40,7 +40,7 @@
|
||||
term.installKeyboard();
|
||||
};
|
||||
|
||||
term.decorate(document.body);
|
||||
term.decorate(document.getElementById("terminal"));
|
||||
};
|
||||
|
||||
ws.onmessage = function(event) {
|
||||
|
@ -2,10 +2,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>GoTTY</title>
|
||||
<style>body {position: absolute; height: 100%; width: 100%; margin: 0px;}</style>
|
||||
<style>body, #terminal {position: absolute; height: 100%; width: 100%; margin: 0px;}</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="hterm.js"></script>
|
||||
<script src="gotty.js"></script>
|
||||
<div id="terminal"></div>
|
||||
<script src="./js/hterm.js"></script>
|
||||
<script src="./js/gotty.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user