Eric Bower
·
2026-10-01
1package tunkit
2
3import (
4 "fmt"
5 "log/slog"
6 "net"
7 "os"
8
9 "github.com/picosh/pico/pkg/pssh"
10)
11
12type ctxAddressKey struct{}
13
14func getAddressCtx(ctx *pssh.SSHServerConnSession) (string, error) {
15 address, ok := ctx.Value(ctxAddressKey{}).(string)
16 if address == "" || !ok {
17 return address, fmt.Errorf("address not set on `*pssh.SSHServerConnSession()` for connection")
18 }
19 return address, nil
20}
21func setAddressCtx(ctx *pssh.SSHServerConnSession, address string) {
22 ctx.SetValue(ctxAddressKey{}, address)
23}
24
25type WebTunnelHandler struct {
26 HttpHandler HttpHandlerFn
27 Logger *slog.Logger
28}
29
30func (wt *WebTunnelHandler) GetLogger() *slog.Logger {
31 return wt.Logger
32}
33
34func (wt *WebTunnelHandler) GetHttpHandler() HttpHandlerFn {
35 return wt.HttpHandler
36}
37
38func (wt *WebTunnelHandler) Close(ctx *pssh.SSHServerConnSession) error {
39 listener, err := getListenerCtx(ctx)
40 if err != nil {
41 return err
42 }
43
44 if listener != nil {
45 _ = listener.Close()
46 setListenerCtx(ctx, nil)
47 }
48
49 return nil
50}
51
52func (wt *WebTunnelHandler) CreateListener(ctx *pssh.SSHServerConnSession) (net.Listener, error) {
53 tempFile, err := os.CreateTemp("", "")
54 if err != nil {
55 return nil, err
56 }
57
58 err = tempFile.Close()
59 if err != nil {
60 return nil, err
61 }
62 address := tempFile.Name()
63 err = os.Remove(address)
64 if err != nil {
65 return nil, err
66 }
67
68 connListener, err := net.Listen("unix", address)
69 if err != nil {
70 return nil, err
71 }
72 setAddressCtx(ctx, address)
73 setListenerCtx(ctx, connListener)
74
75 return connListener, nil
76}
77
78func (wt *WebTunnelHandler) CreateConn(ctx *pssh.SSHServerConnSession) (net.Conn, error) {
79 _, err := httpServe(wt, ctx, wt.GetLogger())
80 if err != nil {
81 wt.GetLogger().Info("unable to create listener", "err", err)
82 return nil, err
83 }
84
85 address, err := getAddressCtx(ctx)
86 if err != nil {
87 return nil, err
88 }
89
90 return net.Dial("unix", address)
91}