-
Notifications
You must be signed in to change notification settings - Fork 7
/
util.go
128 lines (104 loc) · 2.31 KB
/
util.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
package util
import (
"crypto/md5"
cryptoRand "crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
)
func WriteJson(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
_, err := fmt.Fprintln(w, ToJsonMust(data))
if err != nil {
log.Printf("Error writing JSON to HTTP response %v", err)
}
}
func ToJsonMust(data interface{}) string {
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
log.Fatal(err)
}
return string(b)
}
func Md5sum(text string) string {
// Source: <https://stackoverflow.com/a/25286918/151048>.
hash := md5.Sum([]byte(text))
return hex.EncodeToString(hash[:])
}
func RandomBytes(n int) []byte {
b := make([]byte, n)
if _, err := cryptoRand.Read(b); err != nil {
fmt.Println("Error: ", err)
return []byte{}
}
return b[:]
}
func RandomString() string {
return hex.EncodeToString(RandomBytes(16))
}
func Flush(w http.ResponseWriter) bool {
f, ok := w.(http.Flusher)
if ok {
f.Flush()
}
return ok
}
func ParseHeaderValueCsv(content string) []map[string]string {
var data []map[string]string
if content == "" {
return data
}
runes := []rune(content)
length := len(runes)
state := "key-pre"
var key []rune
var val []rune
isValueJustStarted := false
inQuotes := false
currentMap := make(map[string]string)
for pos := 0; pos < length; pos++ {
ch := runes[pos]
if inQuotes {
if ch == '"' {
inQuotes = false
} else if state == "value" {
val = append(val, ch)
}
} else if ch == '=' {
state = "value"
isValueJustStarted = true
} else if ch == ';' || ch == ',' {
state = "key-pre"
currentMap[strings.ToLower(string(key))] = string(val)
key = []rune{}
val = []rune{}
if ch == ',' {
data = append(data, currentMap)
currentMap = make(map[string]string)
}
} else if state == "key-pre" {
if ch != ' ' {
// Whitespace just before a key is ignored.
state = "key"
key = append(key, ch)
}
} else if state == "key" {
key = append(key, ch)
} else if state == "value" {
if isValueJustStarted && ch == '"' {
inQuotes = true
} else {
val = append(val, ch)
}
isValueJustStarted = false
}
}
if len(key) > 0 {
currentMap[strings.ToLower(string(key))] = string(val)
data = append(data, currentMap)
}
return data
}