init
parent
6b307111df
commit
37eafbe7d8
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
|
@ -0,0 +1,15 @@
|
||||||
|
module kumoly.io/tools/goshell
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/creack/pty v1.1.17
|
||||||
|
github.com/gorilla/websocket v1.4.2
|
||||||
|
kumoly.io/lib/klog v0.0.8
|
||||||
|
kumoly.io/lib/ksrv v0.0.2-0.20211112060911-0d61b343a298
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
|
||||||
|
)
|
|
@ -0,0 +1,13 @@
|
||||||
|
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
||||||
|
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
kumoly.io/lib/klog v0.0.8 h1:6hTfDlZh7KGnPrd2tUrauCKRImSnyyN9DHXpey3Czn8=
|
||||||
|
kumoly.io/lib/klog v0.0.8/go.mod h1:Snm+c1xRrh/RbXsxQf7UGYbAJGPcIa6bEEN+CmzJh7M=
|
||||||
|
kumoly.io/lib/ksrv v0.0.2-0.20211112060911-0d61b343a298 h1:0raqoIXmNpD6s1SrJbieAyIIkDyhe+aqfaXvx8wenrI=
|
||||||
|
kumoly.io/lib/ksrv v0.0.2-0.20211112060911-0d61b343a298/go.mod h1:pwd+NspxnoxPJAETRY2V4i2qZc+orKLxvWzGUBiqBW8=
|
|
@ -0,0 +1 @@
|
||||||
|
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>{{.AppName}}</title><link href="css/app.0e433876.css" rel="preload" as="style"><link href="css/chunk-vendors.78de0e90.css" rel="preload" as="style"><link href="js/app.5bd01a68.js" rel="preload" as="script"><link href="js/chunk-vendors.3d58276e.js" rel="preload" as="script"><link href="css/chunk-vendors.78de0e90.css" rel="stylesheet"><link href="css/app.0e433876.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but {{.AppName}} doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.3d58276e.js"></script><script src="js/app.5bd01a68.js"></script></body></html>
|
|
@ -0,0 +1,95 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"flag"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/creack/pty"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"kumoly.io/lib/klog"
|
||||||
|
"kumoly.io/lib/ksrv"
|
||||||
|
"kumoly.io/lib/ksrv/engine"
|
||||||
|
"kumoly.io/tools/goshell/public"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed index.html
|
||||||
|
var index string
|
||||||
|
|
||||||
|
var tmpl *engine.Engine
|
||||||
|
var servePublic = http.FileServer(http.FS(public.FS))
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagAppName string
|
||||||
|
flagAddr string
|
||||||
|
flagShell string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.StringVar(&flagAddr, "addr", ":8000", "address to bind")
|
||||||
|
flag.StringVar(&flagShell, "shell", "bash", "the shell behind")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
server := ksrv.New()
|
||||||
|
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
tmpl = engine.Must(engine.New("").Parse(index))
|
||||||
|
mux.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.String() == "/" {
|
||||||
|
tmpl.Execute(rw, App{flagAppName})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, err := public.FS.Open(strings.TrimPrefix(r.URL.String(), "/"))
|
||||||
|
if err != nil {
|
||||||
|
klog.Debug(err)
|
||||||
|
tmpl.Execute(rw, App{flagAppName})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stat, err := file.Stat()
|
||||||
|
if err != nil || stat.IsDir() {
|
||||||
|
klog.Debug(err)
|
||||||
|
tmpl.Execute(rw, App{flagAppName})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
servePublic.ServeHTTP(rw, r)
|
||||||
|
})
|
||||||
|
|
||||||
|
server.Handle(mux).Listen(flagAddr).Serve()
|
||||||
|
}
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
AppName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type windowSize struct {
|
||||||
|
Rows uint16 `json:"rows"`
|
||||||
|
Cols uint16 `json:"cols"`
|
||||||
|
X uint16
|
||||||
|
Y uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
var upgrader = websocket.Upgrader{
|
||||||
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleWebsocket(w http.ResponseWriter, r *http.Request) {
|
||||||
|
l := klog.Sub(ksrv.GetIP(r))
|
||||||
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
l.Error("Unable to upgrade connection, err: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("/bin/bash", "-l")
|
||||||
|
cmd.Env = append(os.Environ(), "TERM=xterm")
|
||||||
|
pty.Winsize
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
.xterm{position:relative;-moz-user-select:none;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm{cursor:text}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility,.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:.5}.xterm-underline{text-decoration:underline}.xterm-strikethrough{text-decoration:line-through}
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,6 @@
|
||||||
|
package public
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed js favicon.ico
|
||||||
|
var FS embed.FS
|
|
@ -0,0 +1,2 @@
|
||||||
|
(function(e){function t(t){for(var r,c,a=t[0],i=t[1],p=t[2],l=0,s=[];l<a.length;l++)c=a[l],Object.prototype.hasOwnProperty.call(o,c)&&o[c]&&s.push(o[c][0]),o[c]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);f&&f(t);while(s.length)s.shift()();return u.push.apply(u,p||[]),n()}function n(){for(var e,t=0;t<u.length;t++){for(var n=u[t],r=!0,a=1;a<n.length;a++){var i=n[a];0!==o[i]&&(r=!1)}r&&(u.splice(t--,1),e=c(c.s=n[0]))}return e}var r={},o={app:0},u=[];function c(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,c),n.l=!0,n.exports}c.m=e,c.c=r,c.d=function(e,t,n){c.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},c.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.t=function(e,t){if(1&t&&(e=c(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(c.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)c.d(n,r,function(t){return e[t]}.bind(null,r));return n},c.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return c.d(t,"a",t),t},c.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},c.p="";var a=window["webpackJsonp"]=window["webpackJsonp"]||[],i=a.push.bind(a);a.push=t,a=a.slice();for(var p=0;p<a.length;p++)t(a[p]);var f=i;u.push([0,"chunk-vendors"]),n()})({0:function(e,t,n){e.exports=n("56d7")},"0ae4":function(e,t,n){},"56d7":function(e,t,n){"use strict";n.r(t);n("e260"),n("e6cf"),n("cca6"),n("a79d");var r=n("7a23");function o(e,t,n,o,u,c){var a=Object(r["e"])("XTerm");return Object(r["d"])(),Object(r["b"])(a)}function u(e,t,n,o,u,c){return Object(r["d"])(),Object(r["c"])("h1",null,"TEST")}var c={},a=(n("9a49"),n("6b0d")),i=n.n(a);const p=i()(c,[["render",u]]);var f=p,l={name:"App",components:{XTerm:f}};const s=i()(l,[["render",o]]);var d=s;Object(r["a"])(d).mount("#app")},"9a49":function(e,t,n){"use strict";n("0ae4")}});
|
||||||
|
//# sourceMappingURL=app.5bd01a68.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,3 @@
|
||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
|
not dead
|
|
@ -0,0 +1,17 @@
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
'extends': [
|
||||||
|
'plugin:vue/vue3-essential',
|
||||||
|
'eslint:recommended'
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
parser: 'babel-eslint'
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
|
@ -0,0 +1,24 @@
|
||||||
|
# src
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
yarn serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
yarn lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "src",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.6.5",
|
||||||
|
"vue": "^3.0.0",
|
||||||
|
"xterm": "^4.15.0",
|
||||||
|
"xterm-addon-fit": "^0.5.0",
|
||||||
|
"xterm-addon-search": "^0.8.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||||
|
"@vue/cli-service": "~4.5.0",
|
||||||
|
"@vue/compiler-sfc": "^3.0.0",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"eslint": "^6.7.2",
|
||||||
|
"eslint-plugin-vue": "^7.0.0",
|
||||||
|
"sass": "^1.26.5",
|
||||||
|
"sass-loader": "^8.0.2",
|
||||||
|
"vue-cli-plugin-pug": "~2.0.0"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,6 @@
|
||||||
|
package public
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed css js favicon.ico
|
||||||
|
var FS embed.FS
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title>{{.AppName}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but {{.AppName}} doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<template lang="pug">
|
||||||
|
XTerm
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import XTerm from './components/XTerm.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
XTerm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
</style>
|
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -0,0 +1,46 @@
|
||||||
|
<template lang="pug">
|
||||||
|
.console#terminal
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {Terminal} from 'xterm'
|
||||||
|
import {FitAddon} from 'xterm-addon-fit'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
term: null,
|
||||||
|
terminalSocket: null,
|
||||||
|
fitaddon: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
console.log("mounted")
|
||||||
|
let terminalContainer = document.getElementById('terminal')
|
||||||
|
this.term = new Terminal()
|
||||||
|
this.fitaddon = new FitAddon()
|
||||||
|
this.term.loadAddon(this.fitaddon)
|
||||||
|
this.term.open(terminalContainer)
|
||||||
|
this.fitaddon.fit()
|
||||||
|
this.term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
|
||||||
|
console.log(this.term)
|
||||||
|
},
|
||||||
|
Unmounted () {
|
||||||
|
this.term.dispose()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '~xterm/css/xterm.css';
|
||||||
|
|
||||||
|
.console {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,4 @@
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
publicPath: "",
|
||||||
|
outputDir: "../public",
|
||||||
|
indexPath: "../index.html",
|
||||||
|
devServer: {
|
||||||
|
proxy: 'http://localhost:8000'
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue