github.com/xraypb/Xray-core@v1.8.1/transport/pipe/pipe.go (about)

     1  package pipe
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/xraypb/Xray-core/common/buf"
     7  	"github.com/xraypb/Xray-core/common/signal"
     8  	"github.com/xraypb/Xray-core/common/signal/done"
     9  	"github.com/xraypb/Xray-core/features/policy"
    10  )
    11  
    12  // Option for creating new Pipes.
    13  type Option func(*pipeOption)
    14  
    15  // WithoutSizeLimit returns an Option for Pipe to have no size limit.
    16  func WithoutSizeLimit() Option {
    17  	return func(opt *pipeOption) {
    18  		opt.limit = -1
    19  	}
    20  }
    21  
    22  // WithSizeLimit returns an Option for Pipe to have the given size limit.
    23  func WithSizeLimit(limit int32) Option {
    24  	return func(opt *pipeOption) {
    25  		opt.limit = limit
    26  	}
    27  }
    28  
    29  func OnTransmission(hook func(mb buf.MultiBuffer) buf.MultiBuffer) Option {
    30  	return func(option *pipeOption) {
    31  		option.onTransmission = hook
    32  	}
    33  }
    34  
    35  // DiscardOverflow returns an Option for Pipe to discard writes if full.
    36  func DiscardOverflow() Option {
    37  	return func(opt *pipeOption) {
    38  		opt.discardOverflow = true
    39  	}
    40  }
    41  
    42  // OptionsFromContext returns a list of Options from context.
    43  func OptionsFromContext(ctx context.Context) []Option {
    44  	var opt []Option
    45  
    46  	bp := policy.BufferPolicyFromContext(ctx)
    47  	if bp.PerConnection >= 0 {
    48  		opt = append(opt, WithSizeLimit(bp.PerConnection))
    49  	} else {
    50  		opt = append(opt, WithoutSizeLimit())
    51  	}
    52  
    53  	return opt
    54  }
    55  
    56  // New creates a new Reader and Writer that connects to each other.
    57  func New(opts ...Option) (*Reader, *Writer) {
    58  	p := &pipe{
    59  		readSignal:  signal.NewNotifier(),
    60  		writeSignal: signal.NewNotifier(),
    61  		done:        done.New(),
    62  		errChan:     make(chan error, 1),
    63  		option: pipeOption{
    64  			limit: -1,
    65  		},
    66  	}
    67  
    68  	for _, opt := range opts {
    69  		opt(&(p.option))
    70  	}
    71  
    72  	return &Reader{
    73  			pipe: p,
    74  		}, &Writer{
    75  			pipe: p,
    76  		}
    77  }