mirror of
https://github.com/nxshock/gonx.git
synced 2025-07-01 23:53:35 +05:00
Initial commit
This commit is contained in:
commit
0b430973c9
14 changed files with 460 additions and 0 deletions
96
mapping.go
Normal file
96
mapping.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ProxyDirection struct {
|
||||
Output *url.URL
|
||||
|
||||
listener *Listener
|
||||
}
|
||||
|
||||
type HostMapping map[string]ProxyDirection // hostName -> rule
|
||||
|
||||
func (h HostMapping) Add(host, outputUrlStr string) error {
|
||||
outputUrl, err := url.Parse(outputUrlStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pd := ProxyDirection{outputUrl, NewListener()}
|
||||
|
||||
switch outputUrl.Scheme {
|
||||
case "file":
|
||||
server := http.Server{Handler: http.FileServer(http.Dir(outputUrl.Path))}
|
||||
go func() { _ = server.Serve(pd.listener) }()
|
||||
case "tcp":
|
||||
go func(pd ProxyDirection) {
|
||||
for {
|
||||
conn, err := pd.listener.Accept()
|
||||
if err != nil {
|
||||
slog.Debug(err.Error())
|
||||
continue
|
||||
}
|
||||
go func() { _ = handleProxy(conn.(*tls.Conn), pd.Output) }()
|
||||
}
|
||||
}(pd)
|
||||
default:
|
||||
return fmt.Errorf("unknown output protocol: %v", outputUrl.Scheme)
|
||||
}
|
||||
|
||||
h[host] = pd
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleTlsConn(conn *tls.Conn, hosts HostMapping) error {
|
||||
err := conn.Handshake()
|
||||
if err != nil {
|
||||
return fmt.Errorf("handshake error: %v", err)
|
||||
}
|
||||
|
||||
hostName := conn.ConnectionState().ServerName
|
||||
proxyDirection, exists := hosts[hostName]
|
||||
if !exists {
|
||||
return fmt.Errorf("requested host not found: %s", hostName)
|
||||
}
|
||||
|
||||
proxyDirection.listener.Add(conn)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleProxy(conn *tls.Conn, outputUrl *url.URL) error {
|
||||
c, err := net.Dial(outputUrl.Scheme, outputUrl.Host)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dial: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
_, _ = io.Copy(conn, c)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
_, _ = io.Copy(c, conn)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue