package agent import ( "context" "crypto/tls" "fmt" "log" "net/http" "net/url" "os" "time" "github.com/hashicorp/yamux" ) func Handle(ctx context.Context, agentURL, agentToken string, h http.Handler) error { u, err := url.Parse(agentURL) if err != nil { return fmt.Errorf("error parsing URL: %w", err) } if u.Scheme != "iconia" { return fmt.Errorf("wanted scheme %s, got: %s", "iconia", u.Scheme) } if u.Path == "" { return fmt.Errorf("put the domain you want to forward in the path") } tc := &tls.Config{ ServerName: u.Path[1:], InsecureSkipVerify: true, // TODO(Cadey): FIX THIS OMG NextProtos: []string{agentToken}, } log.Println("dialing", u.Host) conn, err := tls.Dial("tcp", u.Host, tc) if err != nil { return fmt.Errorf("error dialing remote host %s: %w", u.Host, err) } defer conn.Close() log.Println("connection established") sesh, err := yamux.Client(conn, &yamux.Config{ AcceptBacklog: 1, EnableKeepAlive: true, KeepAliveInterval: time.Minute, ConnectionWriteTimeout: 100 * time.Millisecond, MaxStreamWindowSize: 262144 * 16, Logger: log.New(os.Stderr, u.Path+"(yamux): ", log.LstdFlags), }) if err != nil { return fmt.Errorf("error connecting to iconia: %w", err) } defer sesh.Close() s := &http.Server{ Handler: h, } log.Println("listening for traffic from iconia") err = s.Serve(sesh) if err != nil { return fmt.Errorf("error serving http: %w", err) } go func() { <-ctx.Done() s.Shutdown(context.Background()) sesh.GoAway() }() return nil }