68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"log"
|
||
|
"net"
|
||
|
"net/http"
|
||
|
"net/http/httputil"
|
||
|
|
||
|
"github.com/progrium/qmux/golang/session"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
CLIENT_VERSION = "v0.2"
|
||
|
HEADER_CLIENT_TOKEN = "X-Client-App-Token"
|
||
|
HEADER_USER_AGENT = "User-Agent"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
flag.Parse()
|
||
|
|
||
|
srvPort, srvHost, clientToken := "18181", "hop.pbiernat.dev", "ghd7H8H*&6tg8*tg68"
|
||
|
targetPort := flag.Arg(0)
|
||
|
|
||
|
if targetPort == "" {
|
||
|
log.Fatal("Missing port!")
|
||
|
}
|
||
|
|
||
|
conn, err := net.Dial("tcp", net.JoinHostPort(srvHost, srvPort))
|
||
|
fatal("main net.Dial", err)
|
||
|
client := httputil.NewClientConn(conn, bufio.NewReader(conn))
|
||
|
req, err := http.NewRequest("GET", "/register", nil)
|
||
|
fatal("http.NewRequest", err)
|
||
|
req.Host = net.JoinHostPort(srvHost, srvPort)
|
||
|
req.Header.Add(HEADER_CLIENT_TOKEN, clientToken)
|
||
|
req.Header.Add(HEADER_USER_AGENT, "HopClient/"+CLIENT_VERSION)
|
||
|
client.Write(req)
|
||
|
resp, _ := client.Read(req)
|
||
|
fmt.Printf("http port %s available at:\n", targetPort)
|
||
|
fmt.Printf("https://%s\n", resp.Header.Get("X-Public-Host"))
|
||
|
c, _ := client.Hijack()
|
||
|
sess := session.New(c)
|
||
|
defer sess.Close()
|
||
|
for {
|
||
|
ch, err := sess.Accept()
|
||
|
fatal("Accept", err)
|
||
|
conn, err := net.Dial("tcp", "127.0.0.1:"+targetPort)
|
||
|
fatal("net.Dial", err)
|
||
|
go join(conn, ch)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func join(a io.ReadWriteCloser, b io.ReadWriteCloser) {
|
||
|
go io.Copy(b, a)
|
||
|
io.Copy(a, b)
|
||
|
a.Close()
|
||
|
b.Close()
|
||
|
}
|
||
|
|
||
|
func fatal(title string, err error) {
|
||
|
if err != nil {
|
||
|
log.Fatal(title+": ", err)
|
||
|
}
|
||
|
}
|