github.com/kelleygo/clashcore@v1.0.2/common/net/earlyconn.go (about)

     1  package net
     2  
     3  import (
     4  	"net"
     5  	"sync"
     6  
     7  	"github.com/kelleygo/clashcore/common/buf"
     8  	"github.com/kelleygo/clashcore/common/once"
     9  )
    10  
    11  type earlyConn struct {
    12  	ExtendedConn // only expose standard N.ExtendedConn function to outside
    13  	resFunc      func() error
    14  	resOnce      sync.Once
    15  	resErr       error
    16  }
    17  
    18  func (conn *earlyConn) Response() error {
    19  	conn.resOnce.Do(func() {
    20  		conn.resErr = conn.resFunc()
    21  	})
    22  	return conn.resErr
    23  }
    24  
    25  func (conn *earlyConn) Read(b []byte) (n int, err error) {
    26  	err = conn.Response()
    27  	if err != nil {
    28  		return 0, err
    29  	}
    30  	return conn.ExtendedConn.Read(b)
    31  }
    32  
    33  func (conn *earlyConn) ReadBuffer(buffer *buf.Buffer) (err error) {
    34  	err = conn.Response()
    35  	if err != nil {
    36  		return err
    37  	}
    38  	return conn.ExtendedConn.ReadBuffer(buffer)
    39  }
    40  
    41  func (conn *earlyConn) Upstream() any {
    42  	return conn.ExtendedConn
    43  }
    44  
    45  func (conn *earlyConn) Success() bool {
    46  	return once.Done(&conn.resOnce) && conn.resErr == nil
    47  }
    48  
    49  func (conn *earlyConn) ReaderReplaceable() bool {
    50  	return conn.Success()
    51  }
    52  
    53  func (conn *earlyConn) ReaderPossiblyReplaceable() bool {
    54  	return !conn.Success()
    55  }
    56  
    57  func (conn *earlyConn) WriterReplaceable() bool {
    58  	return true
    59  }
    60  
    61  var _ ExtendedConn = (*earlyConn)(nil)
    62  
    63  func NewEarlyConn(c net.Conn, f func() error) net.Conn {
    64  	return &earlyConn{ExtendedConn: NewExtendedConn(c), resFunc: f}
    65  }