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/autp_https_conn.go | |
3x-ui
Diffstat (limited to 'web/network/autp_https_conn.go')
| -rw-r--r-- | web/network/autp_https_conn.go | 67 |
1 files changed, 67 insertions, 0 deletions
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) +} |
