12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- 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)
- }
|