diff --git a/Dockerfile b/Dockerfile
index f2ce972..8f8cec4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@ RUN yarn
RUN yarn build
# stage: 2
-FROM golang:1.12-alpine as go-build
+FROM golang:1.13beta1-alpine as go-build
RUN apk update && \
apk add --no-cache git && \
apk add --no-cache upx=3.95-r2
@@ -35,7 +35,7 @@ RUN apk add --no-cache tzdata
COPY --from=go-build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=go-build /app/service .
-COPY --from=go-build /app/config/*.yml ./
+COPY --from=go-build /app/config/* ./
RUN chmod +x /app/service
USER nobody
diff --git a/bench/bench.sh b/bench/bench.sh
index 5ed9094..ea5e8d0 100755
--- a/bench/bench.sh
+++ b/bench/bench.sh
@@ -4,5 +4,4 @@ if brew ls --versions wrk > /dev/null; then
else
brew install wek
wrk -t12 -c400 -d30s --timeout 10s --script=query.lua --latency http://localhost:8080/api/v1/graphql
-fi
-
+fi
\ No newline at end of file
diff --git a/config/allow.list b/config/allow.list
index 12c9c43..ed61b4f 100644
--- a/config/allow.list
+++ b/config/allow.list
@@ -30,4 +30,21 @@ query {
name
image
}
+}
+
+query {
+ products(
+ limit: 30
+ order_by: { price: desc }
+ distinct: [price]
+ where: { id: { and: { greater_or_equals: 20, lt: 28 } } }
+ ) {
+ id
+ name
+ price
+ user {
+ id
+ email
+ }
+ }
}
\ No newline at end of file
diff --git a/config/dev.yml b/config/dev.yml
index aae2586..064895e 100644
--- a/config/dev.yml
+++ b/config/dev.yml
@@ -9,7 +9,7 @@ log_level: "debug"
# queries used. When enabled super graph
# will only allow queries from this list
# List saved to ./config/allow.list
-use_allow_list: false
+use_allow_list: true
# Throw a 401 on auth failure for queries that need auth
# valid values: always, per_query, never
diff --git a/demo b/demo
index 422af8f..9e0195c 100755
--- a/demo
+++ b/demo
@@ -1,21 +1,13 @@
#!/bin/sh
-if [ "$1" == "setup" ]; then
- echo "Downloading pre-built docker images"
- docker-compose -f rails-app/demo.yml pull
- echo "Setting up the demo Rails app"
- docker-compose -f rails-app/demo.yml run web rake db:create db:migrate db:seed
-elif [ "$1" == "run" ]; then
- echo "Deploying Super Graph and the demo Rails app"
- docker-compose -f rails-app/demo.yml up
-elif [ "$1" == "start" ]; then
+if [ "$1" == "start" ]; then
echo "Downloading pre-built docker images"
docker-compose -f rails-app/demo.yml pull
echo "Setting up and deploying Super Graph and the demo Rails app"
- docker-compose -f rails-app/demo.yml run web rake db:create db:migrate db:seed
+ docker-compose -f rails-app/demo.yml run rails_app rake db:create db:migrate db:seed
docker-compose -f rails-app/demo.yml up
elif [ "$1" == "stop" ]; then
docker-compose -f rails-app/demo.yml down
else
- echo "./demo [setup|run|start|stop]"
+ echo "./demo [start|stop]"
fi
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 2fcd94c..7dea71b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,6 +15,7 @@ services:
target: go-build
environment:
GO_ENV: "development"
+ PORT: 8080
ports:
- "8080:8080"
volumes:
diff --git a/fuzz.yaml b/fuzzbuzz.yaml
similarity index 100%
rename from fuzz.yaml
rename to fuzzbuzz.yaml
diff --git a/serv/allow.go b/serv/allow.go
index 3d343c1..473f062 100644
--- a/serv/allow.go
+++ b/serv/allow.go
@@ -84,7 +84,7 @@ func (al *allowList) load() {
c--
if c == 0 {
q := b[s:(e + 1)]
- al.list[relaxHash(q)] = &allowItem{
+ al.list[gqlHash(q)] = &allowItem{
uri: uri,
gql: string(q),
}
@@ -99,7 +99,7 @@ func (al *allowList) load() {
}
func (al *allowList) save(item *allowItem) {
- al.list[relaxHash([]byte(item.gql))] = item
+ al.list[gqlHash([]byte(item.gql))] = item
f, err := os.Create("./config/allow.list")
if err != nil {
diff --git a/serv/config.go b/serv/config.go
index 507aa35..cbdb7de 100644
--- a/serv/config.go
+++ b/serv/config.go
@@ -10,6 +10,8 @@ type config struct {
AppName string `mapstructure:"app_name"`
Env string
HostPort string `mapstructure:"host_port"`
+ Host string
+ Port string
WebUI bool `mapstructure:"web_ui"`
LogLevel string `mapstructure:"log_level"`
EnableTracing bool `mapstructure:"enable_tracing"`
diff --git a/serv/core.go b/serv/core.go
index ab764f1..c5bc3ab 100644
--- a/serv/core.go
+++ b/serv/core.go
@@ -253,7 +253,7 @@ func (c *coreContext) resolveRemotes(
}
func (c *coreContext) resolvePreparedSQL(gql []byte) ([]byte, *preparedItem, error) {
- ps, ok := _preparedList[relaxHash(gql)]
+ ps, ok := _preparedList[gqlHash(gql)]
if !ok {
return nil, nil, errUnauthorized
}
diff --git a/serv/serv.go b/serv/serv.go
index 1b33e8b..3f2963d 100644
--- a/serv/serv.go
+++ b/serv/serv.go
@@ -82,6 +82,8 @@ func initConf() (*config, error) {
vi.SetDefault("env", "development")
vi.BindEnv("env", "GO_ENV")
+ vi.BindEnv("HOST", "HOST")
+ vi.BindEnv("PORT", "PORT")
vi.SetDefault("auth.rails.max_idle", 80)
vi.SetDefault("auth.rails.max_active", 12000)
@@ -213,8 +215,20 @@ func Init() {
}
func startHTTP() {
+ hp := strings.SplitN(conf.HostPort, ":", 2)
+
+ if len(conf.Host) != 0 {
+ hp[0] = conf.Host
+ }
+
+ if len(conf.Port) != 0 {
+ hp[1] = conf.Port
+ }
+
+ hostPort := fmt.Sprintf("%s:%s", hp[0], hp[1])
+
srv := &http.Server{
- Addr: conf.HostPort,
+ Addr: hostPort,
Handler: routeHandler(),
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
@@ -239,7 +253,7 @@ func startHTTP() {
}
})
- fmt.Printf("%s listening on %s (%s)\n", serverName, conf.HostPort, conf.Env)
+ fmt.Printf("%s listening on %s (%s)\n", serverName, hostPort, conf.Env)
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
logger.Error().Err(err).Msg("server closed")
diff --git a/serv/utils.go b/serv/utils.go
index 92c41b3..dd8e9d0 100644
--- a/serv/utils.go
+++ b/serv/utils.go
@@ -17,26 +17,38 @@ func mkkey(h *xxhash.Digest, k1 string, k2 string) uint64 {
return v
}
-func relaxHash(b []byte) string {
+func gqlHash(b []byte) string {
+ b = bytes.TrimSpace(b)
h := sha1.New()
+
s, e := 0, 0
+ space := []byte{' '}
+
+ var b0, b1 byte
for {
- if e == (len(b) - 1) {
- if s != 0 {
+ if ws(b[e]) {
+ for e < len(b) && ws(b[e]) {
e++
- h.Write(bytes.ToLower(b[s:e]))
}
- break
- } else if ws(b[e]) == false && ws(b[(e+1)]) {
- e++
- h.Write(bytes.ToLower(b[s:e]))
- s = 0
- } else if ws(b[e]) && ws(b[(e+1)]) == false {
- e++
- s = e
+ if e < len(b) {
+ b1 = b[e]
+ }
+ if al(b0) && al(b1) {
+ h.Write(space)
+ }
} else {
- e++
+ s = e
+ for e < len(b) && ws(b[e]) == false {
+ e++
+ }
+ if e != 0 {
+ b0 = b[(e - 1)]
+ }
+ h.Write(bytes.ToLower(b[s:e]))
+ }
+ if e >= len(b) {
+ break
}
}
@@ -44,5 +56,9 @@ func relaxHash(b []byte) string {
}
func ws(b byte) bool {
- return b == ' ' || b == '\n' || b == '\t'
+ 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')
}
diff --git a/serv/utils_test.go b/serv/utils_test.go
index 596ab32..d382005 100644
--- a/serv/utils_test.go
+++ b/serv/utils_test.go
@@ -5,7 +5,7 @@ import (
"testing"
)
-func TestRelaxHash(t *testing.T) {
+func TestRelaxHash1(t *testing.T) {
var v1 = []byte(`
products(
limit: 30,
@@ -24,11 +24,39 @@ func TestRelaxHash(t *testing.T) {
price
} `)
- h1 := relaxHash(v1)
- h2 := relaxHash(v2)
+ h1 := gqlHash(v1)
+ h2 := gqlHash(v2)
+
+ if strings.Compare(h1, h2) != 0 {
+ t.Fatal("Hashes don't match they should")
+ }
+}
+
+func TestRelaxHash2(t *testing.T) {
+ var v1 = []byte(`
+ {
+ products(
+ limit: 30
+ order_by: { price: desc }
+ distinct: [price]
+ where: { id: { and: { greater_or_equals: 20, lt: 28 } } }
+ ) {
+ id
+ name
+ price
+ user {
+ id
+ email
+ }
+ }
+ }`)
+
+ var v2 = []byte(` { products( limit: 30, order_by: { price: desc }, distinct: [ price ] where: { id: { and: { greater_or_equals: 20, lt: 28 } } }) { id name price user { id email } } } `)
+
+ h1 := gqlHash(v1)
+ h2 := gqlHash(v2)
if strings.Compare(h1, h2) != 0 {
t.Fatal("Hashes don't match they should")
}
-
}
diff --git a/web/public/index.html b/web/public/index.html
index c108a91..3c74366 100755
--- a/web/public/index.html
+++ b/web/public/index.html
@@ -13,6 +13,8 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
+
+