super-graph/internal/serv/utils.go

136 lines
2.1 KiB
Go
Raw Permalink Normal View History

2019-04-19 07:55:03 +02:00
package serv
2019-07-29 07:13:33 +02:00
import (
"bytes"
"crypto/sha256"
2019-07-29 07:13:33 +02:00
"encoding/hex"
2019-09-05 06:09:56 +02:00
"io"
"os"
2019-09-05 06:09:56 +02:00
"sort"
"strings"
"sync"
2019-07-29 07:13:33 +02:00
2019-09-05 06:09:56 +02:00
"github.com/dosco/super-graph/jsn"
2019-07-29 07:13:33 +02:00
)
2019-04-19 07:55:03 +02:00
// nolint: errcheck
func gqlHash(b string, vars []byte, role string) string {
2019-09-05 06:09:56 +02:00
b = strings.TrimSpace(b)
h := sha256.New()
query := "query"
2019-07-30 07:38:05 +02:00
2019-07-29 07:13:33 +02:00
s, e := 0, 0
2019-07-30 07:38:05 +02:00
space := []byte{' '}
starting := true
2019-07-30 07:38:05 +02:00
var b0, b1 byte
2019-07-29 07:13:33 +02:00
if len(b) == 0 {
return ""
}
2019-07-29 07:13:33 +02:00
for {
if starting && b[e] == 'q' {
n := 0
se := e
for e < len(b) && n < len(query) && b[e] == query[n] {
n++
e++
}
if n != len(query) {
io.WriteString(h, strings.ToLower(b[se:e]))
}
}
if e >= len(b) {
break
}
2019-07-30 07:38:05 +02:00
if ws(b[e]) {
for e < len(b) && ws(b[e]) {
2019-07-29 07:13:33 +02:00
e++
}
2019-07-30 07:38:05 +02:00
if e < len(b) {
b1 = b[e]
}
if al(b0) && al(b1) {
h.Write(space)
}
2019-07-29 07:13:33 +02:00
} else {
starting = false
2019-07-30 07:38:05 +02:00
s = e
for e < len(b) && !ws(b[e]) {
2019-07-30 07:38:05 +02:00
e++
}
if e != 0 {
b0 = b[(e - 1)]
}
2019-09-05 06:09:56 +02:00
io.WriteString(h, strings.ToLower(b[s:e]))
2019-07-30 07:38:05 +02:00
}
if e >= len(b) {
break
2019-07-29 07:13:33 +02:00
}
}
if len(role) != 0 {
io.WriteString(h, role)
}
if len(vars) == 0 {
2019-09-05 06:09:56 +02:00
return hex.EncodeToString(h.Sum(nil))
}
fields := jsn.Keys([]byte(vars))
sort.Slice(fields, func(i, j int) bool {
return bytes.Compare(fields[i], fields[j]) == -1
})
for i := range fields {
h.Write(fields[i])
}
2019-07-29 07:13:33 +02:00
return hex.EncodeToString(h.Sum(nil))
}
func ws(b byte) bool {
2019-07-30 07:38:05 +02:00
return b == ' ' || b == '\n' || b == '\t' || b == ','
}
func al(b byte) bool {
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9')
2019-07-29 07:13:33 +02:00
}
func fatalInProd(err error, msg string) {
var wg sync.WaitGroup
2020-04-11 08:45:06 +02:00
if isDev() {
log.Printf("ERR %s: %s", msg, err)
} else {
log.Fatalf("ERR %s: %s", msg, err)
}
wg.Add(1)
wg.Wait()
}
func isDev() bool {
return strings.HasPrefix(os.Getenv("GO_ENV"), "dev")
}
2020-04-11 08:45:06 +02:00
func sanitize(value string) string {
return strings.ToLower(strings.TrimSpace(value))
}
// Get path relative to cwd
func relpath(p string) string {
cwd, err := os.Getwd()
if err != nil {
return p
}
if strings.HasPrefix(p, cwd) {
return "./" + strings.TrimLeft(p[len(cwd):], "/")
}
return p
}