package wscat import ( "fmt" "net" "net/http" "os" g "euandre.org/gobang/src" "github.com/gorilla/websocket" ) type CLIArgs struct { FromAddr string ToAddr string } const X = 1 var EmitActiveConnection = g.MakeGauge("active-connections") func ParseArgs(args []string) CLIArgs { if len(args) != 3 { fmt.Fprintf( os.Stderr, "Usage: %s FROM.socket TO.socket\n", args[0], ) os.Exit(2) } return CLIArgs { FromAddr: args[1], ToAddr: args[2], } } func Listen(fromAddr string) net.Listener { listener, err := net.Listen("unix", fromAddr) g.FatalIf(err) g.Info("Started listening", "listen-start", "from-address", fromAddr) return listener } func Start(toAddr string, listener net.Listener) { upgrader := websocket.Upgrader {} http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { connFrom, err := upgrader.Upgrade(w, r, nil) if err != nil { g.Warning( "Error upgrading connection", "upgrade-connection-error", "err", err, ) return } defer connFrom.Close() EmitActiveConnection.Inc() connTo, err := net.Dial("unix", toAddr) if err != nil { g.Error( "Error dialing connection", "dial-connection", "err", err, ) os.Exit(1) } defer connTo.Close() messageType, reader, err := connFrom.NextReader() if err != nil { g.Warning( "Failed to get next reader from connection", "connection-next-reader-error", "err", err, ) return } writer, err := connFrom.NextWriter(messageType) if err != nil { g.Warning( "Failed to get next reader from connection", "connection-next-reader-error", "err", err, ) return } c := make(chan g.CopyResult) go g.CopyData(c, "c2s", connTo, writer) go g.CopyData(c, "s2c", reader, connTo) go func() { <- c EmitActiveConnection.Dec() }() }); server := http.Server{} err := server.Serve(listener) g.FatalIf(err) } func Main() { g.Init() args := ParseArgs(os.Args) listener := Listen(args.FromAddr) Start(args.ToAddr, listener) }