diff --git a/.example/os/glog/glog_context.go b/.example/os/glog/glog_context.go index 8b2026df7..f24c4572b 100644 --- a/.example/os/glog/glog_context.go +++ b/.example/os/glog/glog_context.go @@ -6,6 +6,7 @@ import ( ) func main() { - c := context.WithValue(context.Background(), "key", "value") - fmt.Printf("%v", c) + c1 := context.WithValue(context.Background(), "key1", "value1") + c2 := context.WithValue(c1, "key2", "value2") + fmt.Printf("%v", c2.Value("key2")) } diff --git a/container/gpool/gpool.go b/container/gpool/gpool.go index 1238b10f1..b1ead9f94 100644 --- a/container/gpool/gpool.go +++ b/container/gpool/gpool.go @@ -44,7 +44,7 @@ type ExpireFunc func(interface{}) // New returns a new object pool. // To ensure execution efficiency, the expiration time cannot be modified once it is set. // -// Expiration logistics: +// Expiration logic: // expire = 0 : not expired; // expire < 0 : immediate expired after use; // expire > 0 : timeout expired; diff --git a/net/gipv4/gipv4.go b/net/gipv4/gipv4.go index 38ef58d0d..2fd3d530e 100644 --- a/net/gipv4/gipv4.go +++ b/net/gipv4/gipv4.go @@ -12,19 +12,18 @@ import ( "encoding/binary" "fmt" "net" - "regexp" "strconv" "strings" "github.com/gogf/gf/text/gregex" ) -// 判断所给地址是否是一个IPv4地址 +// Validate checks whether given a valid IPv4 address. func Validate(ip string) bool { return gregex.IsMatchString(`^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$`, ip) } -// Get the IPv4 address corresponding to a given Internet host name. +// GetHostByName returns the IPv4 address corresponding to a given Internet host name. func GetHostByName(hostname string) (string, error) { ips, err := net.LookupIP(hostname) if ips != nil { @@ -38,22 +37,22 @@ func GetHostByName(hostname string) (string, error) { return "", err } -// Get a list of IPv4 addresses corresponding to a given Internet host name. +// GetHostsByName returns a list of IPv4 addresses corresponding to a given Internet host name. func GetHostsByName(hostname string) ([]string, error) { ips, err := net.LookupIP(hostname) if ips != nil { - var ipStrs []string + var ipStrings []string for _, v := range ips { if v.To4() != nil { - ipStrs = append(ipStrs, v.String()) + ipStrings = append(ipStrings, v.String()) } } - return ipStrs, nil + return ipStrings, nil } return nil, err } -// Get the Internet host name corresponding to a given IP address. +// GetNameByAddr returns the Internet host name corresponding to a given IP address. func GetNameByAddr(ipAddress string) (string, error) { names, err := net.LookupAddr(ipAddress) if names != nil { @@ -62,7 +61,7 @@ func GetNameByAddr(ipAddress string) (string, error) { return "", err } -// IP字符串转为整形. +// Ip2long converts ip address to an uint32 integer. func Ip2long(ipAddress string) uint32 { ip := net.ParseIP(ipAddress) if ip == nil { @@ -71,43 +70,35 @@ func Ip2long(ipAddress string) uint32 { return binary.BigEndian.Uint32(ip.To4()) } -// ip整形转为字符串 +// Long2ip converts an uint32 integer ip address to its string type address. func Long2ip(properAddress uint32) string { ipByte := make([]byte, 4) binary.BigEndian.PutUint32(ipByte, properAddress) return net.IP(ipByte).String() } -// 获得ip的网段,例如:192.168.2.102 -> 192.168.2 +// GetSegment returns the segment of given ip address. +// Eg: 192.168.2.102 -> 192.168.2 func GetSegment(ip string) string { - r := `^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$` - reg, err := regexp.Compile(r) - if err != nil { + match, err := gregex.MatchString(`^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$`, ip) + if err != nil || len(match) < 4 { return "" } - ips := reg.FindStringSubmatch(ip) - if ips == nil { - return "" - } - return fmt.Sprintf("%s.%s.%s", ips[1], ips[2], ips[3]) + return fmt.Sprintf("%s.%s.%s", match[1], match[2], match[3]) } -// 解析地址,形如:192.168.1.1:80 -> 192.168.1.1, 80 -func ParseAddress(addr string) (string, int) { - r := `^(.+):(\d+)$` - reg, err := regexp.Compile(r) - if err != nil { - return "", 0 - } - result := reg.FindStringSubmatch(addr) - if result != nil { - i, _ := strconv.Atoi(result[2]) - return result[1], i +// ParseAddress parses
to its ip and port. +// Eg: 192.168.1.1:80 -> 192.168.1.1, 80 +func ParseAddress(address string) (string, int) { + match, err := gregex.MatchString(`^(.+):(\d+)$`, address) + if err == nil { + i, _ := strconv.Atoi(match[2]) + return match[1], i } return "", 0 } -// 获取本地局域网ip列表 +// IntranetIP returns the intranet ip list of current machine. func IntranetIP() (ips []string, err error) { ips = make([]string, 0) ifaces, e := net.Interfaces() @@ -116,24 +107,22 @@ func IntranetIP() (ips []string, err error) { } for _, iface := range ifaces { if iface.Flags&net.FlagUp == 0 { - continue // interface down + // interface down + continue } - if iface.Flags&net.FlagLoopback != 0 { - continue // loopback interface + // loopback interface + continue } - // ignore warden bridge if strings.HasPrefix(iface.Name, "w-") { continue } - - addrs, e := iface.Addrs() + addresses, e := iface.Addrs() if e != nil { return ips, e } - - for _, addr := range addrs { + for _, addr := range addresses { var ip net.IP switch v := addr.(type) { case *net.IPNet: @@ -145,12 +134,11 @@ func IntranetIP() (ips []string, err error) { if ip == nil || ip.IsLoopback() { continue } - ip = ip.To4() if ip == nil { - continue // not an ipv4 address + // not an ipv4 address + continue } - ipStr := ip.String() if IsIntranet(ipStr) { ips = append(ips, ipStr) @@ -160,31 +148,32 @@ func IntranetIP() (ips []string, err error) { return ips, nil } -// 判断所给ip是否为局域网ip -// A类 10.0.0.0--10.255.255.255 -// B类 172.16.0.0--172.31.255.255 -// C类 192.168.0.0--192.168.255.255 -func IsIntranet(ipStr string) bool { - // ip协议保留的局域网ip - if strings.HasPrefix(ipStr, "10.") || strings.HasPrefix(ipStr, "192.168.") { +// IsIntranet checks and returns whether given ip an intranet ip. +// A: 10.0.0.0--10.255.255.255 +// B: 172.16.0.0--172.31.255.255 +// C: 192.168.0.0--192.168.255.255 +func IsIntranet(ip string) bool { + array := strings.Split(ip, ".") + if len(array) != 4 { + return false + } + // A + if array[0] == "10" || (array[0] == "192" && array[1] == "168") { return true } - if strings.HasPrefix(ipStr, "172.") { - // 172.16.0.0 - 172.31.255.255 - arr := strings.Split(ipStr, ".") - if len(arr) != 4 { - return false - } - - second, err := strconv.ParseInt(arr[1], 10, 64) + // C + if array[0] == "192" && array[1] == "168" { + return true + } + // B + if array[0] == "172" { + second, err := strconv.ParseInt(array[1], 10, 64) if err != nil { return false } - if second >= 16 && second <= 31 { return true } } - return false } diff --git a/net/gipv6/gipv6.go b/net/gipv6/gipv6.go index 19a682bb4..20cb3ad41 100644 --- a/net/gipv6/gipv6.go +++ b/net/gipv6/gipv6.go @@ -9,7 +9,7 @@ package gipv6 import "github.com/gogf/gf/text/gregex" -// 判断所给地址是否是一个IPv6地址 +// Validate checks whether given a valid IPv6 address. func Validate(ip string) bool { return gregex.IsMatchString(`^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,4}){1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$`, ip) } diff --git a/net/gsmtp/gsmtp.go b/net/gsmtp/gsmtp.go index a1e19961b..91e28e386 100644 --- a/net/gsmtp/gsmtp.go +++ b/net/gsmtp/gsmtp.go @@ -6,7 +6,7 @@ // Package gsmtp provides a SMTP client to access remote mail server. // -// eg: +// Eg: // s := smtp.New("smtp.exmail.qq.com:25", "notify@a.com", "password") // glog.Println(s.SendMail("notify@a.com", "ulric@b.com;rain@c.com", "subject", "body, red")) package gsmtp diff --git a/net/gtcp/gtcp_conn.go b/net/gtcp/gtcp_conn.go index 83d6a20b0..28fe9d9fb 100644 --- a/net/gtcp/gtcp_conn.go +++ b/net/gtcp/gtcp_conn.go @@ -31,7 +31,7 @@ const ( ) // NewConn creates and returns a new connection with given address. -func NewConn(addr string, timeout ...int) (*Conn, error) { +func NewConn(addr string, timeout ...time.Duration) (*Conn, error) { if conn, err := NewNetConn(addr, timeout...); err == nil { return NewConnByNetConn(conn), nil } else { @@ -95,7 +95,7 @@ func (c *Conn) Send(data []byte, retry ...Retry) error { } } -// Recv receives data from remote address. +// Recv receives data from the connection. // // Note that, // 1. If length = 0, it means it receives the data from current buffer and returns immediately. @@ -177,8 +177,8 @@ func (c *Conn) Recv(length int, retry ...Retry) ([]byte, error) { return buffer[:index], err } -// RecvLine reads data from connection until reads char '\n'. -// Note that the returned result does not contain char '\n'. +// RecvLine reads data from the connection until reads char '\n'. +// Note that the returned result does not contain the last char '\n'. func (c *Conn) RecvLine(retry ...Retry) ([]byte, error) { var err error var buffer []byte @@ -201,7 +201,7 @@ func (c *Conn) RecvLine(retry ...Retry) ([]byte, error) { return data, err } -// RecvWithTimeout reads data from connection with timeout. +// RecvWithTimeout reads data from the connection with timeout. func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry) (data []byte, err error) { if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil { return nil, err @@ -211,7 +211,7 @@ func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry return } -// SendWithTimeout writes data to connection with timeout. +// SendWithTimeout writes data to the connection with timeout. func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retry) (err error) { if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil { return err @@ -221,19 +221,19 @@ func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retr return } -// SendRecv writes data to connection and blocks reading response. -func (c *Conn) SendRecv(data []byte, receive int, retry ...Retry) ([]byte, error) { +// SendRecv writes data to the connection and blocks reading response. +func (c *Conn) SendRecv(data []byte, length int, retry ...Retry) ([]byte, error) { if err := c.Send(data, retry...); err == nil { - return c.Recv(receive, retry...) + return c.Recv(length, retry...) } else { return nil, err } } -// SendRecvWithTimeout writes data to connection and reads response with timeout. -func (c *Conn) SendRecvWithTimeout(data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) { +// SendRecvWithTimeout writes data to the connection and reads response with timeout. +func (c *Conn) SendRecvWithTimeout(data []byte, length int, timeout time.Duration, retry ...Retry) ([]byte, error) { if err := c.Send(data, retry...); err == nil { - return c.RecvWithTimeout(receive, timeout, retry...) + return c.RecvWithTimeout(length, timeout, retry...) } else { return nil, err } diff --git a/net/gtcp/gtcp_conn_pkg.go b/net/gtcp/gtcp_conn_pkg.go index 9c4ab7839..2abac9bb4 100644 --- a/net/gtcp/gtcp_conn_pkg.go +++ b/net/gtcp/gtcp_conn_pkg.go @@ -20,8 +20,8 @@ const ( // Package option for simple protocol. type PkgOption struct { - HeaderSize int // It's 2 bytes in default, max is 4 bytes. - MaxDataSize int // (Byte)data field size, it's 2 bytes in default, which means 65535 bytes. + HeaderSize int // It's 2 bytes in default, 4 bytes max. + MaxDataSize int // (Byte) Data field size, it's 2 bytes in default, which means 65535 bytes. Retry Retry // Retry policy. } @@ -98,7 +98,7 @@ func (c *Conn) SendRecvPkgWithTimeout(data []byte, timeout time.Duration, option } } -// Recv receives data from connection using simple package protocol. +// RecvPkg receives data from connection using simple package protocol. func (c *Conn) RecvPkg(option ...PkgOption) (result []byte, err error) { var temp []byte var length int diff --git a/net/gtcp/gtcp_func.go b/net/gtcp/gtcp_func.go index 8a82a3c35..e120f5ec8 100644 --- a/net/gtcp/gtcp_func.go +++ b/net/gtcp/gtcp_func.go @@ -16,41 +16,53 @@ import ( ) const ( - gDEFAULT_RETRY_INTERVAL = 100 // (毫秒)默认重试时间间隔 - gDEFAULT_READ_BUFFER_SIZE = 128 // (byte)默认数据读取缓冲区大小 + gDEFAULT_CONN_TIMEOUT = 30 * time.Second // Default connection timeout. + gDEFAULT_RETRY_INTERVAL = 100 * time.Millisecond // Default retry interval. + gDEFAULT_READ_BUFFER_SIZE = 128 // (Byte) Buffer size for reading. ) type Retry struct { - Count int // 重试次数 - Interval int // 重试间隔(毫秒) + Count int // Retry count. + Interval time.Duration // Retry interval. } -// 创建原生TCP链接, addr地址格式形如:127.0.0.1:80 -func NewNetConn(addr string, timeout ...int) (net.Conn, error) { +// NewNetConn creates and returns a net.Conn with given address like "127.0.0.1:80". +// The optional parameter specifies the timeout for dialing connection. +func NewNetConn(addr string, timeout ...time.Duration) (net.Conn, error) { + d := gDEFAULT_CONN_TIMEOUT if len(timeout) > 0 { - return net.DialTimeout("tcp", addr, time.Duration(timeout[0])*time.Millisecond) - } else { - return net.Dial("tcp", addr) + d = timeout[0] } + return net.DialTimeout("tcp", addr, d) } -// 创建支持TLS的原生TCP链接, addr地址格式形如:127.0.0.1:80 -func NewNetConnTLS(addr string, tlsConfig *tls.Config) (net.Conn, error) { - return tls.Dial("tcp", addr, tlsConfig) +// NewNetConnTLS creates and returns a TLS net.Conn with given address like "127.0.0.1:80". +// The optional parameter specifies the timeout for dialing connection. +func NewNetConnTLS(addr string, tlsConfig *tls.Config, timeout ...time.Duration) (net.Conn, error) { + dialer := &net.Dialer{ + Timeout: gDEFAULT_CONN_TIMEOUT, + } + if len(timeout) > 0 { + dialer.Timeout = timeout[0] + } + return tls.DialWithDialer(dialer, "tcp", addr, tlsConfig) } -// 根据给定的证书和密钥文件创建支持TLS的原生TCP链接, addr地址格式形如:127.0.0.1:80 -func NewNetConnKeyCrt(addr, crtFile, keyFile string) (net.Conn, error) { +// NewNetConnKeyCrt creates and returns a TLS net.Conn with given TLS certificate and key files +// and address like "127.0.0.1:80". The optional parameter specifies the timeout for +// dialing connection. +func NewNetConnKeyCrt(addr, crtFile, keyFile string, timeout ...time.Duration) (net.Conn, error) { tlsConfig, err := LoadKeyCrt(crtFile, keyFile) if err != nil { return nil, err } - return NewNetConnTLS(addr, tlsConfig) + return NewNetConnTLS(addr, tlsConfig, timeout...) } -// (面向短链接)发送数据 -func Send(addr string, data []byte, retry ...Retry) error { - conn, err := NewConn(addr) +// Send creates connection to
, writes to the connection and then closes the connection. +// The optional parameter specifies the retry policy when fails in writing data. +func Send(address string, data []byte, retry ...Retry) error { + conn, err := NewConn(address) if err != nil { return err } @@ -58,19 +70,25 @@ func Send(addr string, data []byte, retry ...Retry) error { return conn.Send(data, retry...) } -// (面向短链接)发送数据并等待接收返回数据 -func SendRecv(addr string, data []byte, receive int, retry ...Retry) ([]byte, error) { - conn, err := NewConn(addr) +// SendRecv creates connection to
, writes to the connection, receives response +// and then closes the connection. +// +// The parameter specifies the bytes count waiting to receive. It receives all buffer content +// and returns if is -1. +// +// The optional parameter specifies the retry policy when fails in writing data. +func SendRecv(address string, data []byte, length int, retry ...Retry) ([]byte, error) { + conn, err := NewConn(address) if err != nil { return nil, err } defer conn.Close() - return conn.SendRecv(data, receive, retry...) + return conn.SendRecv(data, length, retry...) } -// (面向短链接)带超时时间的数据发送 -func SendWithTimeout(addr string, data []byte, timeout time.Duration, retry ...Retry) error { - conn, err := NewConn(addr) +// SendWithTimeout does Send logic with writing timeout limitation. +func SendWithTimeout(address string, data []byte, timeout time.Duration, retry ...Retry) error { + conn, err := NewConn(address) if err != nil { return err } @@ -78,9 +96,9 @@ func SendWithTimeout(addr string, data []byte, timeout time.Duration, retry ...R return conn.SendWithTimeout(data, timeout, retry...) } -// (面向短链接)发送数据并等待接收返回数据(带返回超时等待时间) -func SendRecvWithTimeout(addr string, data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) { - conn, err := NewConn(addr) +// SendRecvWithTimeout does SendRecv logic with reading timeout limitation. +func SendRecvWithTimeout(address string, data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) { + conn, err := NewConn(address) if err != nil { return nil, err } @@ -88,7 +106,7 @@ func SendRecvWithTimeout(addr string, data []byte, receive int, timeout time.Dur return conn.SendRecvWithTimeout(data, receive, timeout, retry...) } -// 判断是否是超时错误 +// isTimeout checks whether given is a timeout error. func isTimeout(err error) bool { if err == nil { return false @@ -99,7 +117,7 @@ func isTimeout(err error) bool { return false } -// 根据证书和密钥生成TLS对象 +// LoadKeyCrt creates and returns a TLS configuration object with given certificate and key files. func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error) { crtPath, err := gfile.Search(crtFile) if err != nil { diff --git a/net/gtcp/gtcp_func_pkg.go b/net/gtcp/gtcp_func_pkg.go index ecd4d7461..8bcd0aa3d 100644 --- a/net/gtcp/gtcp_func_pkg.go +++ b/net/gtcp/gtcp_func_pkg.go @@ -8,9 +8,10 @@ package gtcp import "time" -// 简单协议: (面向短链接)发送消息包 -func SendPkg(addr string, data []byte, option ...PkgOption) error { - conn, err := NewConn(addr) +// SendPkg sends a package containing to
and closes the connection. +// The optional parameter