Skip to content

Commit 513afbe

Browse files
feat: Update CHANGELOG for version 1.1.6 with new features and fixes; add cmux for handling WebSocket connections
1 parent 88bcff1 commit 513afbe

File tree

8 files changed

+183
-104
lines changed

8 files changed

+183
-104
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# IDEFIX Terminal Changelog
22

3-
## [1.1.5] - 2025-05-09
3+
## [1.1.6] - 2025-05-11
44

55
> _Important: Please clear your browser cache (e.g. **Ctrl+F5**) to ensure outdated files are updated._
66
7-
- FIXED: an attenpt to fix a https issue.
7+
- FIXED: Resolved an issue that prevented the web-terminal from connecting over HTTPS.
8+
- ADDED: Expand button — lets you toggle the terminal into a wider overlay. (experimental; may still show minor layout glitches).
9+
- ADDED: The session now closes automatically when the user enters the `exit` command.
810

911
## [1.1.4] - 2025-05-09
1012

backend/go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ go 1.24.1
55
require (
66
github.com/coder/websocket v1.8.13
77
github.com/creack/pty v1.1.24
8+
github.com/soheilhy/cmux v0.1.5
89
golang.org/x/crypto v0.38.0
10+
)
11+
12+
require (
13+
golang.org/x/net v0.21.0 // indirect
914
golang.org/x/sys v0.33.0 // indirect
15+
golang.org/x/text v0.25.0 // indirect
1016
)

backend/go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,27 @@ github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9F
22
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
33
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
44
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
5+
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
6+
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
7+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
8+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
59
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
610
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
11+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
12+
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
13+
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
14+
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
15+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
16+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
17+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
718
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
819
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
920
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
1021
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
22+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
23+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
24+
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
25+
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
26+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
1127
nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y=
1228
nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=

backend/main.go

Lines changed: 27 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
package main
33

44
import (
5-
"bufio"
65
"bytes"
76
"context"
87
"crypto/hmac"
@@ -23,83 +22,19 @@ import (
2322

2423
"github.com/coder/websocket"
2524
"github.com/creack/pty"
25+
"github.com/soheilhy/cmux"
2626
)
2727

2828
const (
29-
plainAddr = ":8787"
30-
tlsAddr = ":8787"
31-
certFile = "/jffs/addons/idefix/cert.pem"
32-
keyFile = "/jffs/addons/idefix/key.pem"
29+
certFile = "/etc/cert.pem"
30+
keyFile = "/etc/key.pem"
3331
)
3432

3533
var (
3634
port int
3735
secret []byte
3836
)
3937

40-
const tlsHandshakeByte byte = 0x16
41-
42-
func ServeOnSamePort(addr, cert, key string, handler http.Handler) error {
43-
ln, err := net.Listen("tcp", addr)
44-
if err != nil {
45-
return err
46-
}
47-
48-
plain := &http.Server{Handler: handler}
49-
50-
tlsCfg, _ := tls.LoadX509KeyPair(cert, key)
51-
tlsSrv := &http.Server{
52-
Handler: handler,
53-
TLSConfig: &tls.Config{
54-
Certificates: []tls.Certificate{tlsCfg},
55-
},
56-
}
57-
58-
go tlsSrv.Serve(&tlsListener{ln})
59-
60-
return plain.Serve(&plainListener{ln})
61-
}
62-
63-
type peekConn struct {
64-
net.Conn
65-
br *bufio.Reader
66-
}
67-
68-
func (c *peekConn) Read(b []byte) (int, error) { return c.br.Read(b) }
69-
70-
type plainListener struct{ net.Listener }
71-
type tlsListener struct{ net.Listener }
72-
73-
func (l *plainListener) Accept() (net.Conn, error) {
74-
for {
75-
c, err := l.Listener.Accept()
76-
if err != nil {
77-
return nil, err
78-
}
79-
80-
pc := &peekConn{Conn: c, br: bufio.NewReader(c)}
81-
if b, _ := pc.br.Peek(1); len(b) == 1 && b[0] != tlsHandshakeByte {
82-
return pc, nil // plain
83-
}
84-
c.Close()
85-
}
86-
}
87-
88-
func (l *tlsListener) Accept() (net.Conn, error) {
89-
for {
90-
c, err := l.Listener.Accept()
91-
if err != nil {
92-
return nil, err
93-
}
94-
95-
pc := &peekConn{Conn: c, br: bufio.NewReader(c)}
96-
if b, _ := pc.br.Peek(1); len(b) == 1 && b[0] == tlsHandshakeByte {
97-
return pc, nil // TLS
98-
}
99-
c.Close()
100-
}
101-
}
102-
10338
func main() {
10439
flag.IntVar(&port, "port", 8787, "listen port")
10540
flag.Parse()
@@ -115,16 +50,32 @@ func main() {
11550
mux := http.NewServeMux()
11651
mux.HandleFunc("/ws", wsHandler)
11752

118-
log.Printf("▶︎ WS + WSS on :8787")
119-
if err := ServeOnSamePort(":8787", certFile, keyFile, mux); err != nil {
120-
log.Fatal(err)
53+
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
54+
if err != nil {
55+
log.Fatalf("listen: %v", err)
12156
}
57+
58+
m := cmux.New(ln)
59+
60+
tlsCfg, _ := tls.LoadX509KeyPair(certFile, keyFile)
61+
tlsL := tls.NewListener(m.Match(cmux.TLS()), &tls.Config{
62+
Certificates: []tls.Certificate{tlsCfg},
63+
})
64+
65+
httpL := m.Match(cmux.HTTP1Fast())
66+
67+
go (&http.Server{Handler: mux}).Serve(httpL)
68+
go (&http.Server{Handler: mux}).Serve(tlsL)
69+
70+
log.Printf("🐾 Idefix Terminal Server on :%d", port)
71+
log.Fatal(m.Serve())
12272
}
12373

12474
func wsHandler(w http.ResponseWriter, r *http.Request) {
12575

12676
if !authorised(r) {
12777
http.Error(w, "Forbidden", http.StatusForbidden)
78+
fmt.Println("Forbidden")
12879
return
12980
}
13081

@@ -154,6 +105,11 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
154105
_, _ = io.Copy(wsWriter{c}, ptmx)
155106
}()
156107

108+
go func() {
109+
proc.Wait()
110+
c.Close(websocket.StatusNormalClosure, "shell exited")
111+
}()
112+
157113
ctx := r.Context()
158114
for {
159115
msgType, rdr, err := c.Reader(ctx)

frontend/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function App() {
2424
}}
2525
>
2626
<Box className="formfonttitle" sx={{ p: 0, pt: 4, pl: 1 }}>
27-
IDEFIX Terminal
27+
🐾 IDEFIX Terminal
2828
</Box>
2929
<Box sx={{ m: 1, mt: 0, mb: 1.5 }} className="splitLine"></Box>
3030

0 commit comments

Comments
 (0)