123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- package common
- import (
- "bytes"
- "encoding/base64"
- "encoding/binary"
- "errors"
- "html/template"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "os"
- "regexp"
- "strconv"
- "strings"
- "sync"
- "github.com/cnlh/nps/lib/crypt"
- )
- //Get the corresponding IP address through domain name
- func GetHostByName(hostname string) string {
- if !DomainCheck(hostname) {
- return hostname
- }
- ips, _ := net.LookupIP(hostname)
- if ips != nil {
- for _, v := range ips {
- if v.To4() != nil {
- return v.String()
- }
- }
- }
- return ""
- }
- //Check the legality of domain
- func DomainCheck(domain string) bool {
- var match bool
- IsLine := "^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}(/)"
- NotLine := "^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}"
- match, _ = regexp.MatchString(IsLine, domain)
- if !match {
- match, _ = regexp.MatchString(NotLine, domain)
- }
- return match
- }
- //Check if the Request request is validated
- func CheckAuth(r *http.Request, user, passwd string) bool {
- s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
- if len(s) != 2 {
- s = strings.SplitN(r.Header.Get("Proxy-Authorization"), " ", 2)
- if len(s) != 2 {
- return false
- }
- }
- b, err := base64.StdEncoding.DecodeString(s[1])
- if err != nil {
- return false
- }
- pair := strings.SplitN(string(b), ":", 2)
- if len(pair) != 2 {
- return false
- }
- return pair[0] == user && pair[1] == passwd
- }
- //get bool by str
- func GetBoolByStr(s string) bool {
- switch s {
- case "1", "true":
- return true
- }
- return false
- }
- //get str by bool
- func GetStrByBool(b bool) string {
- if b {
- return "1"
- }
- return "0"
- }
- //int
- func GetIntNoErrByStr(str string) int {
- i, _ := strconv.Atoi(strings.TrimSpace(str))
- return i
- }
- //Get verify value
- func Getverifyval(vkey string) string {
- return crypt.Md5(vkey)
- }
- //Change headers and host of request
- func ChangeHostAndHeader(r *http.Request, host string, header string, addr string) {
- if host != "" {
- r.Host = host
- }
- if header != "" {
- h := strings.Split(header, "\n")
- for _, v := range h {
- hd := strings.Split(v, ":")
- if len(hd) == 2 {
- r.Header.Set(hd[0], hd[1])
- }
- }
- }
- addr = strings.Split(addr, ":")[0]
- if prior, ok := r.Header["X-Forwarded-For"]; ok {
- addr = strings.Join(prior, ", ") + ", " + addr
- }
- r.Header.Set("X-Forwarded-For", addr)
- r.Header.Set("X-Real-IP", addr)
- }
- //Read file content by file path
- func ReadAllFromFile(filePath string) ([]byte, error) {
- f, err := os.Open(filePath)
- if err != nil {
- return nil, err
- }
- defer f.Close()
- return ioutil.ReadAll(f)
- }
- // FileExists reports whether the named file or directory exists.
- func FileExists(name string) bool {
- if _, err := os.Stat(name); err != nil {
- if os.IsNotExist(err) {
- return false
- }
- }
- return true
- }
- //Judge whether the TCP port can open normally
- func TestTcpPort(port int) bool {
- l, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), port, ""})
- defer func() {
- if l != nil {
- l.Close()
- }
- }()
- if err != nil {
- return false
- }
- return true
- }
- //Judge whether the UDP port can open normally
- func TestUdpPort(port int) bool {
- l, err := net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), port, ""})
- defer func() {
- if l != nil {
- l.Close()
- }
- }()
- if err != nil {
- return false
- }
- return true
- }
- //Write length and individual byte data
- //Length prevents sticking
- //# Characters are used to separate data
- func BinaryWrite(raw *bytes.Buffer, v ...string) {
- b := GetWriteStr(v...)
- binary.Write(raw, binary.LittleEndian, int32(len(b)))
- binary.Write(raw, binary.LittleEndian, b)
- }
- // get seq str
- func GetWriteStr(v ...string) []byte {
- buffer := new(bytes.Buffer)
- var l int32
- for _, v := range v {
- l += int32(len([]byte(v))) + int32(len([]byte(CONN_DATA_SEQ)))
- binary.Write(buffer, binary.LittleEndian, []byte(v))
- binary.Write(buffer, binary.LittleEndian, []byte(CONN_DATA_SEQ))
- }
- return buffer.Bytes()
- }
- //inArray str interface
- func InStrArr(arr []string, val string) bool {
- for _, v := range arr {
- if v == val {
- return true
- }
- }
- return false
- }
- //inArray int interface
- func InIntArr(arr []int, val int) bool {
- for _, v := range arr {
- if v == val {
- return true
- }
- }
- return false
- }
- //format ports str to a int array
- func GetPorts(p string) []int {
- var ps []int
- arr := strings.Split(p, ",")
- for _, v := range arr {
- fw := strings.Split(v, "-")
- if len(fw) == 2 {
- if IsPort(fw[0]) && IsPort(fw[1]) {
- start, _ := strconv.Atoi(fw[0])
- end, _ := strconv.Atoi(fw[1])
- for i := start; i <= end; i++ {
- ps = append(ps, i)
- }
- } else {
- continue
- }
- } else if IsPort(v) {
- p, _ := strconv.Atoi(v)
- ps = append(ps, p)
- }
- }
- return ps
- }
- //is the string a port
- func IsPort(p string) bool {
- pi, err := strconv.Atoi(p)
- if err != nil {
- return false
- }
- if pi > 65536 || pi < 1 {
- return false
- }
- return true
- }
- //if the s is just a port,return 127.0.0.1:s
- func FormatAddress(s string) string {
- if strings.Contains(s, ":") {
- return s
- }
- return "127.0.0.1:" + s
- }
- //get address from the complete address
- func GetIpByAddr(addr string) string {
- arr := strings.Split(addr, ":")
- return arr[0]
- }
- //get port from the complete address
- func GetPortByAddr(addr string) int {
- arr := strings.Split(addr, ":")
- if len(arr) < 2 {
- return 0
- }
- p, err := strconv.Atoi(arr[1])
- if err != nil {
- return 0
- }
- return p
- }
- func CopyBuffer(dst io.Writer, src io.Reader, label ...string) (written int64, err error) {
- buf := CopyBuff.Get()
- defer CopyBuff.Put(buf)
- for {
- nr, er := src.Read(buf)
- //if len(pr)>0 && pr[0] && nr > 50 {
- // logs.Warn(string(buf[:50]))
- //}
- if nr > 0 {
- nw, ew := dst.Write(buf[0:nr])
- if nw > 0 {
- written += int64(nw)
- }
- if ew != nil {
- err = ew
- break
- }
- if nr != nw {
- err = io.ErrShortWrite
- break
- }
- }
- if er != nil {
- err = er
- break
- }
- }
- return written, err
- }
- //send this ip forget to get a local udp port
- func GetLocalUdpAddr() (net.Conn, error) {
- tmpConn, err := net.Dial("udp", "114.114.114.114:53")
- if err != nil {
- return nil, err
- }
- return tmpConn, tmpConn.Close()
- }
- //parse template
- func ParseStr(str string) (string, error) {
- tmp := template.New("npc")
- var err error
- w := new(bytes.Buffer)
- if tmp, err = tmp.Parse(str); err != nil {
- return "", err
- }
- if err = tmp.Execute(w, GetEnvMap()); err != nil {
- return "", err
- }
- return w.String(), nil
- }
- //get env
- func GetEnvMap() map[string]string {
- m := make(map[string]string)
- environ := os.Environ()
- for i := range environ {
- tmp := strings.Split(environ[i], "=")
- if len(tmp) == 2 {
- m[tmp[0]] = tmp[1]
- }
- }
- return m
- }
- //throw the empty element of the string array
- func TrimArr(arr []string) []string {
- newArr := make([]string, 0)
- for _, v := range arr {
- if v != "" {
- newArr = append(newArr, v)
- }
- }
- return newArr
- }
- //
- func IsArrContains(arr []string, val string) bool {
- if arr == nil {
- return false
- }
- for _, v := range arr {
- if v == val {
- return true
- }
- }
- return false
- }
- //remove value from string array
- func RemoveArrVal(arr []string, val string) []string {
- for k, v := range arr {
- if v == val {
- arr = append(arr[:k], arr[k+1:]...)
- return arr
- }
- }
- return arr
- }
- //convert bytes to num
- func BytesToNum(b []byte) int {
- var str string
- for i := 0; i < len(b); i++ {
- str += strconv.Itoa(int(b[i]))
- }
- x, _ := strconv.Atoi(str)
- return int(x)
- }
- //get the length of the sync map
- func GeSynctMapLen(m sync.Map) int {
- var c int
- m.Range(func(key, value interface{}) bool {
- c++
- return true
- })
- return c
- }
- func GetExtFromPath(path string) string {
- s := strings.Split(path, ".")
- re, err := regexp.Compile(`(\w+)`)
- if err != nil {
- return ""
- }
- return string(re.Find([]byte(s[0])))
- }
- var externalIp string
- func GetExternalIp() string {
- if externalIp != "" {
- return externalIp
- }
- resp, err := http.Get("http://myexternalip.com/raw")
- if err != nil {
- return ""
- }
- defer resp.Body.Close()
- content, _ := ioutil.ReadAll(resp.Body)
- externalIp = string(content)
- return externalIp
- }
- func GetIntranetIp() (error, string) {
- addrs, err := net.InterfaceAddrs()
- if err != nil {
- return nil, ""
- }
- for _, address := range addrs {
- // 检查ip地址判断是否回环地址
- if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
- if ipnet.IP.To4() != nil {
- return nil, ipnet.IP.To4().String()
- }
- }
- }
- return errors.New("get intranet ip error"), ""
- }
- func IsPublicIP(IP net.IP) bool {
- if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {
- return false
- }
- if ip4 := IP.To4(); ip4 != nil {
- switch true {
- case ip4[0] == 10:
- return false
- case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
- return false
- case ip4[0] == 192 && ip4[1] == 168:
- return false
- default:
- return true
- }
- }
- return false
- }
- func GetServerIpByClientIp(clientIp net.IP) string {
- if IsPublicIP(clientIp) {
- return GetExternalIp()
- }
- _, ip := GetIntranetIp()
- return ip
- }
|