util.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. package common
  2. import (
  3. "bytes"
  4. "ehang.io/nps/lib/version"
  5. "encoding/base64"
  6. "encoding/binary"
  7. "errors"
  8. "fmt"
  9. "html/template"
  10. "io"
  11. "io/ioutil"
  12. "net"
  13. "net/http"
  14. "os"
  15. "regexp"
  16. "strconv"
  17. "strings"
  18. "sync"
  19. "ehang.io/nps/lib/crypt"
  20. )
  21. //Get the corresponding IP address through domain name
  22. func GetHostByName(hostname string) string {
  23. if !DomainCheck(hostname) {
  24. return hostname
  25. }
  26. ips, _ := net.LookupIP(hostname)
  27. if ips != nil {
  28. for _, v := range ips {
  29. if v.To4() != nil {
  30. return v.String()
  31. }
  32. }
  33. }
  34. return ""
  35. }
  36. //Check the legality of domain
  37. func DomainCheck(domain string) bool {
  38. var match bool
  39. IsLine := "^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}(/)"
  40. NotLine := "^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}"
  41. match, _ = regexp.MatchString(IsLine, domain)
  42. if !match {
  43. match, _ = regexp.MatchString(NotLine, domain)
  44. }
  45. return match
  46. }
  47. //Check if the Request request is validated
  48. func CheckAuth(r *http.Request, user, passwd string) bool {
  49. s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
  50. if len(s) != 2 {
  51. s = strings.SplitN(r.Header.Get("Proxy-Authorization"), " ", 2)
  52. if len(s) != 2 {
  53. return false
  54. }
  55. }
  56. b, err := base64.StdEncoding.DecodeString(s[1])
  57. if err != nil {
  58. return false
  59. }
  60. pair := strings.SplitN(string(b), ":", 2)
  61. if len(pair) != 2 {
  62. return false
  63. }
  64. return pair[0] == user && pair[1] == passwd
  65. }
  66. //get bool by str
  67. func GetBoolByStr(s string) bool {
  68. switch s {
  69. case "1", "true":
  70. return true
  71. }
  72. return false
  73. }
  74. //get str by bool
  75. func GetStrByBool(b bool) string {
  76. if b {
  77. return "1"
  78. }
  79. return "0"
  80. }
  81. //int
  82. func GetIntNoErrByStr(str string) int {
  83. i, _ := strconv.Atoi(strings.TrimSpace(str))
  84. return i
  85. }
  86. //Get verify value
  87. func Getverifyval(vkey string) string {
  88. return crypt.Md5(vkey)
  89. }
  90. //Change headers and host of request
  91. func ChangeHostAndHeader(r *http.Request, host string, header string, addr string, addOrigin bool) {
  92. if host != "" {
  93. r.Host = host
  94. }
  95. if header != "" {
  96. h := strings.Split(header, "\n")
  97. for _, v := range h {
  98. hd := strings.Split(v, ":")
  99. if len(hd) == 2 {
  100. r.Header.Set(hd[0], hd[1])
  101. }
  102. }
  103. }
  104. addr = strings.Split(addr, ":")[0]
  105. if prior, ok := r.Header["X-Forwarded-For"]; ok {
  106. addr = strings.Join(prior, ", ") + ", " + addr
  107. }
  108. if addOrigin {
  109. r.Header.Set("X-Forwarded-For", addr)
  110. r.Header.Set("X-Real-IP", addr)
  111. }
  112. }
  113. //Read file content by file path
  114. func ReadAllFromFile(filePath string) ([]byte, error) {
  115. f, err := os.Open(filePath)
  116. if err != nil {
  117. return nil, err
  118. }
  119. defer f.Close()
  120. return ioutil.ReadAll(f)
  121. }
  122. // FileExists reports whether the named file or directory exists.
  123. func FileExists(name string) bool {
  124. if _, err := os.Stat(name); err != nil {
  125. if os.IsNotExist(err) {
  126. return false
  127. }
  128. }
  129. return true
  130. }
  131. //Judge whether the TCP port can open normally
  132. func TestTcpPort(port int) bool {
  133. l, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), port, ""})
  134. defer func() {
  135. if l != nil {
  136. l.Close()
  137. }
  138. }()
  139. if err != nil {
  140. return false
  141. }
  142. return true
  143. }
  144. //Judge whether the UDP port can open normally
  145. func TestUdpPort(port int) bool {
  146. l, err := net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), port, ""})
  147. defer func() {
  148. if l != nil {
  149. l.Close()
  150. }
  151. }()
  152. if err != nil {
  153. return false
  154. }
  155. return true
  156. }
  157. //Write length and individual byte data
  158. //Length prevents sticking
  159. //# Characters are used to separate data
  160. func BinaryWrite(raw *bytes.Buffer, v ...string) {
  161. b := GetWriteStr(v...)
  162. binary.Write(raw, binary.LittleEndian, int32(len(b)))
  163. binary.Write(raw, binary.LittleEndian, b)
  164. }
  165. // get seq str
  166. func GetWriteStr(v ...string) []byte {
  167. buffer := new(bytes.Buffer)
  168. var l int32
  169. for _, v := range v {
  170. l += int32(len([]byte(v))) + int32(len([]byte(CONN_DATA_SEQ)))
  171. binary.Write(buffer, binary.LittleEndian, []byte(v))
  172. binary.Write(buffer, binary.LittleEndian, []byte(CONN_DATA_SEQ))
  173. }
  174. return buffer.Bytes()
  175. }
  176. //inArray str interface
  177. func InStrArr(arr []string, val string) bool {
  178. for _, v := range arr {
  179. if v == val {
  180. return true
  181. }
  182. }
  183. return false
  184. }
  185. //inArray int interface
  186. func InIntArr(arr []int, val int) bool {
  187. for _, v := range arr {
  188. if v == val {
  189. return true
  190. }
  191. }
  192. return false
  193. }
  194. //format ports str to a int array
  195. func GetPorts(p string) []int {
  196. var ps []int
  197. arr := strings.Split(p, ",")
  198. for _, v := range arr {
  199. fw := strings.Split(v, "-")
  200. if len(fw) == 2 {
  201. if IsPort(fw[0]) && IsPort(fw[1]) {
  202. start, _ := strconv.Atoi(fw[0])
  203. end, _ := strconv.Atoi(fw[1])
  204. for i := start; i <= end; i++ {
  205. ps = append(ps, i)
  206. }
  207. } else {
  208. continue
  209. }
  210. } else if IsPort(v) {
  211. p, _ := strconv.Atoi(v)
  212. ps = append(ps, p)
  213. }
  214. }
  215. return ps
  216. }
  217. //is the string a port
  218. func IsPort(p string) bool {
  219. pi, err := strconv.Atoi(p)
  220. if err != nil {
  221. return false
  222. }
  223. if pi > 65536 || pi < 1 {
  224. return false
  225. }
  226. return true
  227. }
  228. //if the s is just a port,return 127.0.0.1:s
  229. func FormatAddress(s string) string {
  230. if strings.Contains(s, ":") {
  231. return s
  232. }
  233. return "127.0.0.1:" + s
  234. }
  235. //get address from the complete address
  236. func GetIpByAddr(addr string) string {
  237. arr := strings.Split(addr, ":")
  238. return arr[0]
  239. }
  240. //get port from the complete address
  241. func GetPortByAddr(addr string) int {
  242. arr := strings.Split(addr, ":")
  243. if len(arr) < 2 {
  244. return 0
  245. }
  246. p, err := strconv.Atoi(arr[1])
  247. if err != nil {
  248. return 0
  249. }
  250. return p
  251. }
  252. func CopyBuffer(dst io.Writer, src io.Reader, label ...string) (written int64, err error) {
  253. buf := CopyBuff.Get()
  254. defer CopyBuff.Put(buf)
  255. for {
  256. nr, er := src.Read(buf)
  257. //if len(pr)>0 && pr[0] && nr > 50 {
  258. // logs.Warn(string(buf[:50]))
  259. //}
  260. if nr > 0 {
  261. nw, ew := dst.Write(buf[0:nr])
  262. if nw > 0 {
  263. written += int64(nw)
  264. }
  265. if ew != nil {
  266. err = ew
  267. break
  268. }
  269. if nr != nw {
  270. err = io.ErrShortWrite
  271. break
  272. }
  273. }
  274. if er != nil {
  275. err = er
  276. break
  277. }
  278. }
  279. return written, err
  280. }
  281. //send this ip forget to get a local udp port
  282. func GetLocalUdpAddr() (net.Conn, error) {
  283. tmpConn, err := net.Dial("udp", "114.114.114.114:53")
  284. if err != nil {
  285. return nil, err
  286. }
  287. return tmpConn, tmpConn.Close()
  288. }
  289. //parse template
  290. func ParseStr(str string) (string, error) {
  291. tmp := template.New("npc")
  292. var err error
  293. w := new(bytes.Buffer)
  294. if tmp, err = tmp.Parse(str); err != nil {
  295. return "", err
  296. }
  297. if err = tmp.Execute(w, GetEnvMap()); err != nil {
  298. return "", err
  299. }
  300. return w.String(), nil
  301. }
  302. //get env
  303. func GetEnvMap() map[string]string {
  304. m := make(map[string]string)
  305. environ := os.Environ()
  306. for i := range environ {
  307. tmp := strings.Split(environ[i], "=")
  308. if len(tmp) == 2 {
  309. m[tmp[0]] = tmp[1]
  310. }
  311. }
  312. return m
  313. }
  314. //throw the empty element of the string array
  315. func TrimArr(arr []string) []string {
  316. newArr := make([]string, 0)
  317. for _, v := range arr {
  318. if v != "" {
  319. newArr = append(newArr, v)
  320. }
  321. }
  322. return newArr
  323. }
  324. //
  325. func IsArrContains(arr []string, val string) bool {
  326. if arr == nil {
  327. return false
  328. }
  329. for _, v := range arr {
  330. if v == val {
  331. return true
  332. }
  333. }
  334. return false
  335. }
  336. //remove value from string array
  337. func RemoveArrVal(arr []string, val string) []string {
  338. for k, v := range arr {
  339. if v == val {
  340. arr = append(arr[:k], arr[k+1:]...)
  341. return arr
  342. }
  343. }
  344. return arr
  345. }
  346. //convert bytes to num
  347. func BytesToNum(b []byte) int {
  348. var str string
  349. for i := 0; i < len(b); i++ {
  350. str += strconv.Itoa(int(b[i]))
  351. }
  352. x, _ := strconv.Atoi(str)
  353. return int(x)
  354. }
  355. //get the length of the sync map
  356. func GeSynctMapLen(m sync.Map) int {
  357. var c int
  358. m.Range(func(key, value interface{}) bool {
  359. c++
  360. return true
  361. })
  362. return c
  363. }
  364. func GetExtFromPath(path string) string {
  365. s := strings.Split(path, ".")
  366. re, err := regexp.Compile(`(\w+)`)
  367. if err != nil {
  368. return ""
  369. }
  370. return string(re.Find([]byte(s[0])))
  371. }
  372. var externalIp string
  373. func GetExternalIp() string {
  374. if externalIp != "" {
  375. return externalIp
  376. }
  377. resp, err := http.Get("http://myexternalip.com/raw")
  378. if err != nil {
  379. return ""
  380. }
  381. defer resp.Body.Close()
  382. content, _ := ioutil.ReadAll(resp.Body)
  383. externalIp = string(content)
  384. return externalIp
  385. }
  386. func GetIntranetIp() (error, string) {
  387. addrs, err := net.InterfaceAddrs()
  388. if err != nil {
  389. return nil, ""
  390. }
  391. for _, address := range addrs {
  392. // 检查ip地址判断是否回环地址
  393. if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  394. if ipnet.IP.To4() != nil {
  395. return nil, ipnet.IP.To4().String()
  396. }
  397. }
  398. }
  399. return errors.New("get intranet ip error"), ""
  400. }
  401. func IsPublicIP(IP net.IP) bool {
  402. if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {
  403. return false
  404. }
  405. if ip4 := IP.To4(); ip4 != nil {
  406. switch true {
  407. case ip4[0] == 10:
  408. return false
  409. case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
  410. return false
  411. case ip4[0] == 192 && ip4[1] == 168:
  412. return false
  413. default:
  414. return true
  415. }
  416. }
  417. return false
  418. }
  419. func GetServerIpByClientIp(clientIp net.IP) string {
  420. if IsPublicIP(clientIp) {
  421. return GetExternalIp()
  422. }
  423. _, ip := GetIntranetIp()
  424. return ip
  425. }
  426. func PrintVersion() {
  427. fmt.Printf("Version: %s\nCore version: %s\nSame core version of client and server can connect each other\n", version.VERSION, version.GetVersion())
  428. }