util.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package util
  2. import (
  3. "crypto/rand"
  4. "encoding/base64"
  5. "errors"
  6. "io"
  7. "io/ioutil"
  8. "net"
  9. "os"
  10. "regexp"
  11. "strconv"
  12. "time"
  13. "github.com/jhoonb/archivex"
  14. )
  15. // ZipFiles and return the resulting zip's filename
  16. func ZipFiles(files []string) (string, error) {
  17. zip := new(archivex.ZipFile)
  18. tmpfile, err := ioutil.TempFile("", "qrcp")
  19. if err != nil {
  20. return "", err
  21. }
  22. tmpfile.Close()
  23. if err := os.Rename(tmpfile.Name(), tmpfile.Name()+".zip"); err != nil {
  24. return "", err
  25. }
  26. zip.Create(tmpfile.Name() + ".zip")
  27. for _, filename := range files {
  28. fileinfo, err := os.Stat(filename)
  29. if err != nil {
  30. return "", err
  31. }
  32. if fileinfo.IsDir() {
  33. zip.AddAll(filename, true)
  34. } else {
  35. file, err := os.Open(filename)
  36. if err != nil {
  37. return "", err
  38. }
  39. defer file.Close()
  40. if err := zip.Add(filename, file, fileinfo); err != nil {
  41. return "", err
  42. }
  43. }
  44. }
  45. if err := zip.Close(); err != nil {
  46. return "", nil
  47. }
  48. return zip.Name, nil
  49. }
  50. // GetRandomURLPath returns a random string of 4 alphanumeric characters
  51. func GetRandomURLPath() string {
  52. timeNum := time.Now().UTC().UnixNano()
  53. alphaString := strconv.FormatInt(timeNum, 36)
  54. return alphaString[len(alphaString)-4:]
  55. }
  56. // GetSessionID returns a base64 encoded string of 40 random characters
  57. func GetSessionID() (string, error) {
  58. randbytes := make([]byte, 40)
  59. if _, err := io.ReadFull(rand.Reader, randbytes); err != nil {
  60. return "", err
  61. }
  62. return base64.StdEncoding.EncodeToString(randbytes), nil
  63. }
  64. // GetInterfaceAddress returns the address of the network interface to
  65. // bind the server to. If the interface is "any", it will return 0.0.0.0.
  66. // If no interface is found with that name, an error is returned
  67. func GetInterfaceAddress(ifaceString string) (string, error) {
  68. if ifaceString == "any" {
  69. return "0.0.0.0", nil
  70. }
  71. ifaces, err := net.Interfaces()
  72. if err != nil {
  73. return "", err
  74. }
  75. var candidateInterface *net.Interface
  76. for _, iface := range ifaces {
  77. if iface.Name == ifaceString {
  78. candidateInterface = &iface
  79. break
  80. }
  81. }
  82. if candidateInterface != nil {
  83. ip, err := FindIP(*candidateInterface)
  84. if err != nil {
  85. return "", err
  86. }
  87. return ip, nil
  88. }
  89. return "", errors.New("unable to find interface")
  90. }
  91. // FindIP returns the IP address of the passed interface, and an error
  92. func FindIP(iface net.Interface) (string, error) {
  93. addrs, err := iface.Addrs()
  94. if err != nil {
  95. return "", err
  96. }
  97. for _, addr := range addrs {
  98. if ipnet, ok := addr.(*net.IPNet); ok {
  99. if ipnet.IP.IsLinkLocalUnicast() {
  100. continue
  101. }
  102. if ipnet.IP.To4() != nil {
  103. return ipnet.IP.String(), nil
  104. }
  105. return "[" + ipnet.IP.String() + "]", nil
  106. }
  107. }
  108. return "", errors.New("Unable to find an IP for this interface")
  109. }
  110. func filterInterfaces(ifaces []net.Interface) []net.Interface {
  111. filtered := []net.Interface{}
  112. var re = regexp.MustCompile(`^(veth|br\-|docker|lo|EHC|XHC|bridge|gif|stf|p2p|awdl|utun|tun|tap)`)
  113. for _, iface := range ifaces {
  114. if re.MatchString(iface.Name) {
  115. continue
  116. }
  117. if iface.Flags&net.FlagUp == 0 {
  118. continue
  119. }
  120. filtered = append(filtered, iface)
  121. }
  122. return filtered
  123. }
  124. // ReadFilenames from dir
  125. func ReadFilenames(dir string) []string {
  126. files, err := ioutil.ReadDir(dir)
  127. if err != nil {
  128. panic(err)
  129. }
  130. // Create array of names of files which are stored in dir
  131. // used later to set valid name for received files
  132. filenames := make([]string, len(files))
  133. for _, fi := range files {
  134. filenames = append(filenames, fi.Name())
  135. }
  136. return filenames
  137. }