github.com/cloudwego/hertz@v0.9.3/pkg/network/netpoll/connection.go (about)

     1  // Copyright 2022 CloudWeGo Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package netpoll
    17  
    18  import (
    19  	"errors"
    20  	"io"
    21  	"strings"
    22  	"syscall"
    23  
    24  	errs "github.com/cloudwego/hertz/pkg/common/errors"
    25  	"github.com/cloudwego/hertz/pkg/common/hlog"
    26  	"github.com/cloudwego/hertz/pkg/network"
    27  	"github.com/cloudwego/netpoll"
    28  )
    29  
    30  type Conn struct {
    31  	network.Conn
    32  }
    33  
    34  func (c *Conn) ToHertzError(err error) error {
    35  	if errors.Is(err, netpoll.ErrConnClosed) || errors.Is(err, syscall.EPIPE) {
    36  		return errs.ErrConnectionClosed
    37  	}
    38  
    39  	// only unify read timeout for now
    40  	if errors.Is(err, netpoll.ErrReadTimeout) {
    41  		return errs.ErrTimeout
    42  	}
    43  	return err
    44  }
    45  
    46  func (c *Conn) Peek(n int) (b []byte, err error) {
    47  	b, err = c.Conn.Peek(n)
    48  	err = normalizeErr(err)
    49  	return
    50  }
    51  
    52  func (c *Conn) Read(p []byte) (int, error) {
    53  	n, err := c.Conn.Read(p)
    54  	err = normalizeErr(err)
    55  	return n, err
    56  }
    57  
    58  func (c *Conn) Skip(n int) error {
    59  	return c.Conn.Skip(n)
    60  }
    61  
    62  func (c *Conn) Release() error {
    63  	return c.Conn.Release()
    64  }
    65  
    66  func (c *Conn) Len() int {
    67  	return c.Conn.Len()
    68  }
    69  
    70  func (c *Conn) ReadByte() (b byte, err error) {
    71  	b, err = c.Conn.ReadByte()
    72  	err = normalizeErr(err)
    73  	return
    74  }
    75  
    76  func (c *Conn) ReadBinary(n int) (b []byte, err error) {
    77  	b, err = c.Conn.ReadBinary(n)
    78  	err = normalizeErr(err)
    79  	return
    80  }
    81  
    82  func (c *Conn) Malloc(n int) (buf []byte, err error) {
    83  	return c.Conn.Malloc(n)
    84  }
    85  
    86  func (c *Conn) WriteBinary(b []byte) (n int, err error) {
    87  	return c.Conn.WriteBinary(b)
    88  }
    89  
    90  func (c *Conn) Flush() error {
    91  	return c.Conn.Flush()
    92  }
    93  
    94  func (c *Conn) HandleSpecificError(err error, rip string) (needIgnore bool) {
    95  	if errors.Is(err, netpoll.ErrConnClosed) || errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) {
    96  		// ignore flushing error when connection is closed or reset
    97  		if strings.Contains(err.Error(), "when flush") {
    98  			return true
    99  		}
   100  		hlog.SystemLogger().Debugf("Netpoll error=%s, remoteAddr=%s", err.Error(), rip)
   101  		return true
   102  	}
   103  	return false
   104  }
   105  
   106  func normalizeErr(err error) error {
   107  	if errors.Is(err, netpoll.ErrEOF) {
   108  		return io.EOF
   109  	}
   110  
   111  	return err
   112  }
   113  
   114  func newConn(c netpoll.Connection) network.Conn {
   115  	return &Conn{Conn: c.(network.Conn)}
   116  }