mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-02 23:47:07 -05:00
refactor
This commit is contained in:
parent
cea6e28634
commit
59a1e2d736
@ -48,17 +48,17 @@ func (DefaultDispatcher) Interface() interface{} {
|
|||||||
return (*dispatcher.Interface)(nil)
|
return (*dispatcher.Interface)(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) {
|
func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) {
|
||||||
dispatcher := v.ohm.GetDefaultHandler()
|
dispatcher := d.ohm.GetDefaultHandler()
|
||||||
if !destination.IsValid() {
|
if !destination.IsValid() {
|
||||||
panic("Dispatcher: Invalid destination.")
|
panic("Dispatcher: Invalid destination.")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = proxy.ContextWithTarget(ctx, destination)
|
ctx = proxy.ContextWithTarget(ctx, destination)
|
||||||
|
|
||||||
if v.router != nil {
|
if d.router != nil {
|
||||||
if tag, err := v.router.TakeDetour(ctx); err == nil {
|
if tag, err := d.router.TakeDetour(ctx); err == nil {
|
||||||
if handler := v.ohm.GetHandler(tag); handler != nil {
|
if handler := d.ohm.GetHandler(tag); handler != nil {
|
||||||
log.Trace(newError("taking detour [", tag, "] for [", destination, "]"))
|
log.Trace(newError("taking detour [", tag, "] for [", destination, "]"))
|
||||||
dispatcher = handler
|
dispatcher = handler
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,9 +6,9 @@ import (
|
|||||||
"v2ray.com/core/app/log"
|
"v2ray.com/core/app/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (v *Config) GetInternalHosts() map[string]net.IP {
|
func (c *Config) GetInternalHosts() map[string]net.IP {
|
||||||
hosts := make(map[string]net.IP)
|
hosts := make(map[string]net.IP)
|
||||||
for domain, ipOrDomain := range v.GetHosts() {
|
for domain, ipOrDomain := range c.GetHosts() {
|
||||||
address := ipOrDomain.AsAddress()
|
address := ipOrDomain.AsAddress()
|
||||||
if address.Family().IsDomain() {
|
if address.Family().IsDomain() {
|
||||||
log.Trace(newError("ignoring domain address in static hosts: ", address.Domain()).AtWarning())
|
log.Trace(newError("ignoring domain address in static hosts: ", address.Domain()).AtWarning())
|
||||||
|
@ -80,40 +80,39 @@ func (*CacheServer) Start() error {
|
|||||||
|
|
||||||
func (*CacheServer) Close() {}
|
func (*CacheServer) Close() {}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
func (s *CacheServer) GetCached(domain string) []net.IP {
|
||||||
func (v *CacheServer) GetCached(domain string) []net.IP {
|
s.RLock()
|
||||||
v.RLock()
|
defer s.RUnlock()
|
||||||
defer v.RUnlock()
|
|
||||||
|
|
||||||
if record, found := v.records[domain]; found && record.A.Expire.After(time.Now()) {
|
if record, found := s.records[domain]; found && record.A.Expire.After(time.Now()) {
|
||||||
return record.A.IPs
|
return record.A.IPs
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CacheServer) Get(domain string) []net.IP {
|
func (s *CacheServer) Get(domain string) []net.IP {
|
||||||
if ip, found := v.hosts[domain]; found {
|
if ip, found := s.hosts[domain]; found {
|
||||||
return []net.IP{ip}
|
return []net.IP{ip}
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = dnsmsg.Fqdn(domain)
|
domain = dnsmsg.Fqdn(domain)
|
||||||
ips := v.GetCached(domain)
|
ips := s.GetCached(domain)
|
||||||
if ips != nil {
|
if ips != nil {
|
||||||
return ips
|
return ips
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, server := range v.servers {
|
for _, server := range s.servers {
|
||||||
response := server.QueryA(domain)
|
response := server.QueryA(domain)
|
||||||
select {
|
select {
|
||||||
case a, open := <-response:
|
case a, open := <-response:
|
||||||
if !open || a == nil {
|
if !open || a == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.Lock()
|
s.Lock()
|
||||||
v.records[domain] = &DomainRecord{
|
s.records[domain] = &DomainRecord{
|
||||||
A: a,
|
A: a,
|
||||||
}
|
}
|
||||||
v.Unlock()
|
s.Unlock()
|
||||||
log.Trace(newError("returning ", len(a.IPs), " IPs for domain ", domain).AtDebug())
|
log.Trace(newError("returning ", len(a.IPs), " IPs for domain ", domain).AtDebug())
|
||||||
return a.IPs
|
return a.IPs
|
||||||
case <-time.After(QueryTimeout):
|
case <-time.After(QueryTimeout):
|
||||||
|
@ -16,8 +16,8 @@ type ErrorLog struct {
|
|||||||
Error error
|
Error error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *ErrorLog) String() string {
|
func (l *ErrorLog) String() string {
|
||||||
return v.Prefix + v.Error.Error()
|
return l.Prefix + l.Error.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccessLog struct {
|
type AccessLog struct {
|
||||||
@ -27,6 +27,6 @@ type AccessLog struct {
|
|||||||
Reason interface{}
|
Reason interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *AccessLog) String() string {
|
func (l *AccessLog) String() string {
|
||||||
return strings.Join([]string{serial.ToString(v.From), v.Status, serial.ToString(v.To), serial.ToString(v.Reason)}, " ")
|
return strings.Join([]string{serial.ToString(l.From), l.Status, serial.ToString(l.To), serial.ToString(l.Reason)}, " ")
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,9 @@ type LogWriter interface {
|
|||||||
type NoOpLogWriter struct {
|
type NoOpLogWriter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *NoOpLogWriter) Log(entry LogEntry) {}
|
func (*NoOpLogWriter) Log(entry LogEntry) {}
|
||||||
|
|
||||||
func (v *NoOpLogWriter) Close() {
|
func (*NoOpLogWriter) Close() {}
|
||||||
}
|
|
||||||
|
|
||||||
type StdOutLogWriter struct {
|
type StdOutLogWriter struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
@ -31,11 +30,11 @@ func NewStdOutLogWriter() LogWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *StdOutLogWriter) Log(log LogEntry) {
|
func (w *StdOutLogWriter) Log(log LogEntry) {
|
||||||
v.logger.Print(log.String() + platform.LineSeparator())
|
w.logger.Print(log.String() + platform.LineSeparator())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *StdOutLogWriter) Close() {}
|
func (*StdOutLogWriter) Close() {}
|
||||||
|
|
||||||
type FileLogWriter struct {
|
type FileLogWriter struct {
|
||||||
queue chan string
|
queue chan string
|
||||||
@ -45,31 +44,30 @@ type FileLogWriter struct {
|
|||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FileLogWriter) Log(log LogEntry) {
|
func (w *FileLogWriter) Log(log LogEntry) {
|
||||||
select {
|
select {
|
||||||
case <-v.ctx.Done():
|
case <-w.ctx.Done():
|
||||||
return
|
return
|
||||||
case v.queue <- log.String():
|
case w.queue <- log.String():
|
||||||
default:
|
default:
|
||||||
// We don't expect this to happen, but don't want to block main thread as well.
|
// We don't expect this to happen, but don't want to block main thread as well.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FileLogWriter) run(ctx context.Context) {
|
func (w *FileLogWriter) run(ctx context.Context) {
|
||||||
L:
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
break L
|
w.file.Close()
|
||||||
case entry := <-v.queue:
|
return
|
||||||
v.logger.Print(entry + platform.LineSeparator())
|
case entry := <-w.queue:
|
||||||
|
w.logger.Print(entry + platform.LineSeparator())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v.file.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FileLogWriter) Close() {
|
func (w *FileLogWriter) Close() {
|
||||||
v.cancel()
|
w.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileLogWriter(path string) (*FileLogWriter, error) {
|
func NewFileLogWriter(path string) (*FileLogWriter, error) {
|
||||||
|
@ -35,38 +35,38 @@ func (*Manager) Start() error { return nil }
|
|||||||
// Close implements Application.Close
|
// Close implements Application.Close
|
||||||
func (*Manager) Close() {}
|
func (*Manager) Close() {}
|
||||||
|
|
||||||
func (v *Manager) GetDefaultHandler() proxyman.OutboundHandler {
|
func (m *Manager) GetDefaultHandler() proxyman.OutboundHandler {
|
||||||
v.RLock()
|
m.RLock()
|
||||||
defer v.RUnlock()
|
defer m.RUnlock()
|
||||||
if v.defaultHandler == nil {
|
if m.defaultHandler == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return v.defaultHandler
|
return m.defaultHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Manager) GetHandler(tag string) proxyman.OutboundHandler {
|
func (m *Manager) GetHandler(tag string) proxyman.OutboundHandler {
|
||||||
v.RLock()
|
m.RLock()
|
||||||
defer v.RUnlock()
|
defer m.RUnlock()
|
||||||
if handler, found := v.taggedHandler[tag]; found {
|
if handler, found := m.taggedHandler[tag]; found {
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Manager) AddHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) error {
|
func (m *Manager) AddHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) error {
|
||||||
v.Lock()
|
m.Lock()
|
||||||
defer v.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
handler, err := NewHandler(ctx, config)
|
handler, err := NewHandler(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if v.defaultHandler == nil {
|
if m.defaultHandler == nil {
|
||||||
v.defaultHandler = handler
|
m.defaultHandler = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.Tag) > 0 {
|
if len(config.Tag) > 0 {
|
||||||
v.taggedHandler[config.Tag] = handler
|
m.taggedHandler[config.Tag] = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -52,8 +52,8 @@ func NewRouter(ctx context.Context, config *Config) (*Router, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Router) resolveIP(dest net.Destination) []net.Address {
|
func (r *Router) resolveIP(dest net.Destination) []net.Address {
|
||||||
ips := v.dnsServer.Get(dest.Address.Domain())
|
ips := r.dnsServer.Get(dest.Address.Domain())
|
||||||
if len(ips) == 0 {
|
if len(ips) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -64,8 +64,8 @@ func (v *Router) resolveIP(dest net.Destination) []net.Address {
|
|||||||
return dests
|
return dests
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Router) TakeDetour(ctx context.Context) (string, error) {
|
func (r *Router) TakeDetour(ctx context.Context) (string, error) {
|
||||||
for _, rule := range v.rules {
|
for _, rule := range r.rules {
|
||||||
if rule.Apply(ctx) {
|
if rule.Apply(ctx) {
|
||||||
return rule.Tag, nil
|
return rule.Tag, nil
|
||||||
}
|
}
|
||||||
@ -76,12 +76,12 @@ func (v *Router) TakeDetour(ctx context.Context) (string, error) {
|
|||||||
return "", ErrNoRuleApplicable
|
return "", ErrNoRuleApplicable
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
|
if r.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
|
||||||
log.Trace(newError("looking up IP for ", dest))
|
log.Trace(newError("looking up IP for ", dest))
|
||||||
ipDests := v.resolveIP(dest)
|
ipDests := r.resolveIP(dest)
|
||||||
if ipDests != nil {
|
if ipDests != nil {
|
||||||
ctx = proxy.ContextWithResolveIPs(ctx, ipDests)
|
ctx = proxy.ContextWithResolveIPs(ctx, ipDests)
|
||||||
for _, rule := range v.rules {
|
for _, rule := range r.rules {
|
||||||
if rule.Apply(ctx) {
|
if rule.Apply(ctx) {
|
||||||
return rule.Tag, nil
|
return rule.Tag, nil
|
||||||
}
|
}
|
||||||
@ -92,15 +92,15 @@ func (v *Router) TakeDetour(ctx context.Context) (string, error) {
|
|||||||
return "", ErrNoRuleApplicable
|
return "", ErrNoRuleApplicable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Router) Interface() interface{} {
|
func (*Router) Interface() interface{} {
|
||||||
return (*Router)(nil)
|
return (*Router)(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Router) Start() error {
|
func (*Router) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Router) Close() {}
|
func (*Router) Close() {}
|
||||||
|
|
||||||
func FromSpace(space app.Space) *Router {
|
func FromSpace(space app.Space) *Router {
|
||||||
app := space.GetApplication((*Router)(nil))
|
app := space.GetApplication((*Router)(nil))
|
||||||
|
26
app/space.go
26
app/space.go
@ -52,39 +52,39 @@ func NewSpace() Space {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *spaceImpl) OnInitialize(f InitializationCallback) {
|
func (s *spaceImpl) OnInitialize(f InitializationCallback) {
|
||||||
if v.initialized {
|
if s.initialized {
|
||||||
f()
|
f()
|
||||||
} else {
|
} else {
|
||||||
v.appInit = append(v.appInit, f)
|
s.appInit = append(s.appInit, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *spaceImpl) Initialize() error {
|
func (s *spaceImpl) Initialize() error {
|
||||||
for _, f := range v.appInit {
|
for _, f := range s.appInit {
|
||||||
if err := f(); err != nil {
|
if err := f(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v.appInit = nil
|
s.appInit = nil
|
||||||
v.initialized = true
|
s.initialized = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *spaceImpl) GetApplication(appInterface interface{}) Application {
|
func (s *spaceImpl) GetApplication(appInterface interface{}) Application {
|
||||||
if v == nil {
|
if s == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
appType := reflect.TypeOf(appInterface)
|
appType := reflect.TypeOf(appInterface)
|
||||||
return v.cache[appType]
|
return s.cache[appType]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *spaceImpl) AddApplication(app Application) error {
|
func (s *spaceImpl) AddApplication(app Application) error {
|
||||||
if v == nil {
|
if s == nil {
|
||||||
return newError("nil space").AtError()
|
return newError("nil space").AtError()
|
||||||
}
|
}
|
||||||
appType := reflect.TypeOf(app.Interface())
|
appType := reflect.TypeOf(app.Interface())
|
||||||
v.cache[appType] = app
|
s.cache[appType] = app
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,20 +20,20 @@ func NewBufferedWriter(rawWriter io.Writer) *BufferedWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
// Write implements io.Writer.
|
||||||
func (v *BufferedWriter) Write(b []byte) (int, error) {
|
func (w *BufferedWriter) Write(b []byte) (int, error) {
|
||||||
if !v.buffered || v.buffer == nil {
|
if !w.buffered || w.buffer == nil {
|
||||||
return v.writer.Write(b)
|
return w.writer.Write(b)
|
||||||
}
|
}
|
||||||
nBytes, err := v.buffer.Write(b)
|
nBytes, err := w.buffer.Write(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if v.buffer.IsFull() {
|
if w.buffer.IsFull() {
|
||||||
if err := v.Flush(); err != nil {
|
if err := w.Flush(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if nBytes < len(b) {
|
if nBytes < len(b) {
|
||||||
if _, err := v.writer.Write(b[nBytes:]); err != nil {
|
if _, err := w.writer.Write(b[nBytes:]); err != nil {
|
||||||
return nBytes, err
|
return nBytes, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,28 +42,28 @@ func (v *BufferedWriter) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush writes all buffered content into underlying writer, if any.
|
// Flush writes all buffered content into underlying writer, if any.
|
||||||
func (v *BufferedWriter) Flush() error {
|
func (w *BufferedWriter) Flush() error {
|
||||||
defer v.buffer.Clear()
|
defer w.buffer.Clear()
|
||||||
for !v.buffer.IsEmpty() {
|
for !w.buffer.IsEmpty() {
|
||||||
nBytes, err := v.writer.Write(v.buffer.Bytes())
|
nBytes, err := w.writer.Write(w.buffer.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.buffer.SliceFrom(nBytes)
|
w.buffer.SliceFrom(nBytes)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBuffered returns true if this BufferedWriter holds a buffer.
|
// IsBuffered returns true if this BufferedWriter holds a buffer.
|
||||||
func (v *BufferedWriter) IsBuffered() bool {
|
func (w *BufferedWriter) IsBuffered() bool {
|
||||||
return v.buffered
|
return w.buffered
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBuffered controls whether the BufferedWriter holds a buffer for writing. If not buffered, any write() calls into underlying writer directly.
|
// SetBuffered controls whether the BufferedWriter holds a buffer for writing. If not buffered, any write() calls into underlying writer directly.
|
||||||
func (v *BufferedWriter) SetBuffered(cached bool) error {
|
func (w *BufferedWriter) SetBuffered(cached bool) error {
|
||||||
v.buffered = cached
|
w.buffered = cached
|
||||||
if !cached && !v.buffer.IsEmpty() {
|
if !cached && !w.buffer.IsEmpty() {
|
||||||
return v.Flush()
|
return w.Flush()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,25 @@ type MultiBufferReader interface {
|
|||||||
ReadMultiBuffer() (MultiBuffer, error)
|
ReadMultiBuffer() (MultiBuffer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MultiBuffer is a list of Buffers. The order of Buffer matters.
|
||||||
type MultiBuffer []*Buffer
|
type MultiBuffer []*Buffer
|
||||||
|
|
||||||
|
// NewMultiBuffer creates a new MultiBuffer instance.
|
||||||
func NewMultiBuffer() MultiBuffer {
|
func NewMultiBuffer() MultiBuffer {
|
||||||
return MultiBuffer(make([]*Buffer, 0, 128))
|
return MultiBuffer(make([]*Buffer, 0, 128))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewMultiBufferValue wraps a list of Buffers into MultiBuffer.
|
||||||
func NewMultiBufferValue(b ...*Buffer) MultiBuffer {
|
func NewMultiBufferValue(b ...*Buffer) MultiBuffer {
|
||||||
return MultiBuffer(b)
|
return MultiBuffer(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *MultiBuffer) Append(buf *Buffer) {
|
func (mb *MultiBuffer) Append(buf *Buffer) {
|
||||||
*b = append(*b, buf)
|
*mb = append(*mb, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *MultiBuffer) AppendMulti(mb MultiBuffer) {
|
func (mb *MultiBuffer) AppendMulti(buf MultiBuffer) {
|
||||||
*b = append(*b, mb...)
|
*mb = append(*mb, buf...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mb *MultiBuffer) Read(b []byte) (int, error) {
|
func (mb *MultiBuffer) Read(b []byte) (int, error) {
|
||||||
@ -46,6 +49,7 @@ func (mb *MultiBuffer) Read(b []byte) (int, error) {
|
|||||||
return totalBytes, nil
|
return totalBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Len returns the total number of bytes in the MultiBuffer.
|
||||||
func (mb MultiBuffer) Len() int {
|
func (mb MultiBuffer) Len() int {
|
||||||
size := 0
|
size := 0
|
||||||
for _, b := range mb {
|
for _, b := range mb {
|
||||||
@ -54,6 +58,7 @@ func (mb MultiBuffer) Len() int {
|
|||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsEmpty return true if the MultiBuffer has no content.
|
||||||
func (mb MultiBuffer) IsEmpty() bool {
|
func (mb MultiBuffer) IsEmpty() bool {
|
||||||
for _, b := range mb {
|
for _, b := range mb {
|
||||||
if !b.IsEmpty() {
|
if !b.IsEmpty() {
|
||||||
@ -63,6 +68,7 @@ func (mb MultiBuffer) IsEmpty() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release releases all Buffers in the MultiBuffer.
|
||||||
func (mb MultiBuffer) Release() {
|
func (mb MultiBuffer) Release() {
|
||||||
for i, b := range mb {
|
for i, b := range mb {
|
||||||
b.Release()
|
b.Release()
|
||||||
@ -70,6 +76,7 @@ func (mb MultiBuffer) Release() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToNetBuffers converts this MultiBuffer to net.Buffers. The return net.Buffers points to the same content of the MultiBuffer.
|
||||||
func (mb MultiBuffer) ToNetBuffers() net.Buffers {
|
func (mb MultiBuffer) ToNetBuffers() net.Buffers {
|
||||||
bs := make([][]byte, len(mb))
|
bs := make([][]byte, len(mb))
|
||||||
for i, b := range mb {
|
for i, b := range mb {
|
||||||
|
Loading…
Reference in New Issue
Block a user