/
tools.go
144 lines (124 loc) · 2.58 KB
/
tools.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package server
import (
"context"
"errors"
"io"
"math/rand"
"net/http"
"net/url"
"regexp"
"libvirt.org/go/libvirt"
)
// IsValidName returns true if argument use only allowed chars for a name
func IsValidName(token string) bool {
match, _ := regexp.MatchString("^[A-Za-z0-9_]*$", token)
return match
}
// IsValidGroupName returns true if group is a valid group name (@ + isValidName)
func IsValidGroupName(group string) bool {
match, _ := regexp.MatchString("^@[A-Za-z0-9_]*$", group)
return match
}
// IsValidWord returns true if argument use only allowed chars for a name
func IsValidWord(token string) bool {
match, _ := regexp.MatchString("^[A-Za-z0-9_-]*$", token)
return match
}
// RandString generate a random string of A-Za-z0-9 runes
func RandString(n int, rand *rand.Rand) string {
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
// GetURLScheme returns the scheme of the given URL
func GetURLScheme(urlStr string) (string, error) {
u, err := url.Parse(urlStr)
if err != nil {
return "", err
}
return u.Scheme, nil
}
// CopyReaderFlush
func CopyReaderFlush(dst io.Writer, src io.Reader) (written int64, err error) {
size := 32 * 1024
buf := make([]byte, size)
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if f, ok := dst.(http.Flusher); ok {
f.Flush()
}
if nw < 0 || nr < nw {
nw = 0
if ew == nil {
ew = errors.New("invalid write result")
}
}
written += int64(nw)
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er != nil {
if er != io.EOF {
err = er
}
break
}
}
return written, err
}
// CopyStreamFlush
func CopyStreamFlush(dst io.Writer, src *libvirt.Stream, ctx context.Context) (written int64, err error) {
size := 32 * 1024
buf := make([]byte, size)
contextIsOk := true
go func() {
<-ctx.Done()
contextIsOk = false
src.Abort()
}()
for {
nr, er := src.Recv(buf)
if !contextIsOk {
return written, nil
}
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if f, ok := dst.(http.Flusher); ok {
f.Flush()
}
if nw < 0 || nr < nw {
nw = 0
if ew == nil {
ew = errors.New("invalid write result")
}
}
written += int64(nw)
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er != nil {
if er != io.EOF {
err = er
}
break
}
}
return written, err
}