diff options
| author | MHSanaei <mc.sanaei@gmail.com> | 2023-02-09 22:18:06 +0300 |
|---|---|---|
| committer | MHSanaei <mc.sanaei@gmail.com> | 2023-02-09 22:18:06 +0300 |
| commit | b73e4173a3c1e69e02ad6b4e3b43e425e57a5be9 (patch) | |
| tree | d95d2f5e903d97082e11eb9f9023c165b1bde388 /web/network | |
3x-ui
Diffstat (limited to 'web/network')
| -rw-r--r-- | web/network/auto_https_listener.go | 21 | ||||
| -rw-r--r-- | web/network/autp_https_conn.go | 67 |
2 files changed, 88 insertions, 0 deletions
diff --git a/web/network/auto_https_listener.go b/web/network/auto_https_listener.go new file mode 100644 index 00000000..26614696 --- /dev/null +++ b/web/network/auto_https_listener.go @@ -0,0 +1,21 @@ +package network + +import "net" + +type AutoHttpsListener struct { + net.Listener +} + +func NewAutoHttpsListener(listener net.Listener) net.Listener { + return &AutoHttpsListener{ + Listener: listener, + } +} + +func (l *AutoHttpsListener) Accept() (net.Conn, error) { + conn, err := l.Listener.Accept() + if err != nil { + return nil, err + } + return NewAutoHttpsConn(conn), nil +} diff --git a/web/network/autp_https_conn.go b/web/network/autp_https_conn.go new file mode 100644 index 00000000..d1a9d521 --- /dev/null +++ b/web/network/autp_https_conn.go @@ -0,0 +1,67 @@ +package network + +import ( + "bufio" + "bytes" + "fmt" + "net" + "net/http" + "sync" +) + +type AutoHttpsConn struct { + net.Conn + + firstBuf []byte + bufStart int + + readRequestOnce sync.Once +} + +func NewAutoHttpsConn(conn net.Conn) net.Conn { + return &AutoHttpsConn{ + Conn: conn, + } +} + +func (c *AutoHttpsConn) readRequest() bool { + c.firstBuf = make([]byte, 2048) + n, err := c.Conn.Read(c.firstBuf) + c.firstBuf = c.firstBuf[:n] + if err != nil { + return false + } + reader := bytes.NewReader(c.firstBuf) + bufReader := bufio.NewReader(reader) + request, err := http.ReadRequest(bufReader) + if err != nil { + return false + } + resp := http.Response{ + Header: http.Header{}, + } + resp.StatusCode = http.StatusTemporaryRedirect + location := fmt.Sprintf("https://%v%v", request.Host, request.RequestURI) + resp.Header.Set("Location", location) + resp.Write(c.Conn) + c.Close() + c.firstBuf = nil + return true +} + +func (c *AutoHttpsConn) Read(buf []byte) (int, error) { + c.readRequestOnce.Do(func() { + c.readRequest() + }) + + if c.firstBuf != nil { + n := copy(buf, c.firstBuf[c.bufStart:]) + c.bufStart += n + if c.bufStart >= len(c.firstBuf) { + c.firstBuf = nil + } + return n, nil + } + + return c.Conn.Read(buf) +} |
