├── .gitignore ├── vendor ├── github.com │ ├── elastic │ │ └── go-elasticsearch │ │ │ └── v7 │ │ │ ├── go.sum │ │ │ ├── .dockerignore │ │ │ ├── .gitignore │ │ │ ├── go.mod │ │ │ ├── .codecov.yml │ │ │ ├── internal │ │ │ └── version │ │ │ │ └── version.go │ │ │ ├── esapi │ │ │ ├── esapi.request.go │ │ │ ├── esapi.go │ │ │ ├── esapi.response.go │ │ │ └── doc.go │ │ │ ├── Dockerfile │ │ │ ├── doc.go │ │ │ └── estransport │ │ │ └── doc.go │ ├── lib │ │ └── pq │ │ │ ├── go.mod │ │ │ ├── .gitignore │ │ │ ├── oid │ │ │ └── doc.go │ │ │ ├── ssl_windows.go │ │ │ ├── user_posix.go │ │ │ ├── ssl_permissions.go │ │ │ ├── uuid.go │ │ │ ├── TESTS.md │ │ │ ├── user_windows.go │ │ │ ├── LICENSE.md │ │ │ ├── .travis.yml │ │ │ ├── CONTRIBUTING.md │ │ │ ├── url.go │ │ │ ├── buf.go │ │ │ ├── .travis.sh │ │ │ ├── rows.go │ │ │ ├── README.md │ │ │ ├── connector.go │ │ │ └── conn_go18.go │ ├── gorilla │ │ ├── mux │ │ │ ├── go.mod │ │ │ ├── AUTHORS │ │ │ ├── test_helpers.go │ │ │ ├── LICENSE │ │ │ └── middleware.go │ │ └── websocket │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── AUTHORS │ │ │ ├── trace_17.go │ │ │ ├── .gitignore │ │ │ ├── mask_safe.go │ │ │ ├── conn_write.go │ │ │ ├── client_clone.go │ │ │ ├── trace.go │ │ │ ├── conn_write_legacy.go │ │ │ ├── join.go │ │ │ ├── LICENSE │ │ │ ├── mask.go │ │ │ ├── client_clone_legacy.go │ │ │ ├── json.go │ │ │ ├── proxy.go │ │ │ ├── prepared.go │ │ │ ├── compression.go │ │ │ └── README.md │ ├── kelseyhightower │ │ └── envconfig │ │ │ ├── go.mod │ │ │ ├── env_os.go │ │ │ ├── env_syscall.go │ │ │ ├── MAINTAINERS │ │ │ ├── .travis.yml │ │ │ ├── doc.go │ │ │ └── LICENSE │ ├── nats-io │ │ ├── jwt │ │ │ ├── go.mod │ │ │ ├── ReleaseNotes.md │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── .travis.yml │ │ │ ├── go.sum │ │ │ ├── revocation_list.go │ │ │ ├── README.md │ │ │ ├── header.go │ │ │ ├── genericlaims.go │ │ │ ├── server_claims.go │ │ │ ├── cluster_claims.go │ │ │ ├── user_claims.go │ │ │ └── validation.go │ │ ├── nkeys │ │ │ ├── TODO.md │ │ │ ├── go.mod │ │ │ ├── GOVERNANCE.md │ │ │ ├── MAINTAINERS.md │ │ │ ├── .gitignore │ │ │ ├── go.sum │ │ │ ├── .travis.yml │ │ │ ├── .goreleaser.yml │ │ │ ├── public.go │ │ │ ├── keypair.go │ │ │ ├── crc16.go │ │ │ ├── main.go │ │ │ └── README.md │ │ ├── nats.go │ │ │ ├── go.mod │ │ │ ├── GOVERNANCE.md │ │ │ ├── MAINTAINERS.md │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── util │ │ │ │ ├── tls.go │ │ │ │ └── tls_go17.go │ │ │ ├── TODO.md │ │ │ ├── go.sum │ │ │ ├── encoders │ │ │ │ └── builtin │ │ │ │ │ ├── gob_enc.go │ │ │ │ │ ├── json_enc.go │ │ │ │ │ └── default_enc.go │ │ │ ├── timer.go │ │ │ └── netchan.go │ │ └── nuid │ │ │ ├── GOVERNANCE.md │ │ │ ├── MAINTAINERS.md │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ └── nuid.go │ ├── tinrab │ │ └── retry │ │ │ ├── .editorconfig │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── LICENSE │ │ │ └── retry.go │ └── segmentio │ │ └── ksuid │ │ ├── .gitignore │ │ ├── LICENSE.md │ │ ├── rand.go │ │ ├── sequence.go │ │ └── uint128.go ├── golang.org │ └── x │ │ └── crypto │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── PATENTS │ │ ├── LICENSE │ │ └── ed25519 │ │ └── ed25519_go113.go └── modules.txt ├── frontend ├── public │ ├── favicon.ico │ └── index.html ├── vue.config.js ├── src │ ├── main.js │ ├── App.vue │ ├── components │ │ ├── Meow.vue │ │ ├── Search.vue │ │ └── Timeline.vue │ └── store.js ├── .gitignore ├── .prettierrc └── package.json ├── postgres ├── Dockerfile └── up.sql ├── nginx ├── Dockerfile └── nginx.conf ├── README.md ├── schema └── model.go ├── .editorconfig ├── event ├── messages.go ├── event.go └── nats.go ├── go.mod ├── Dockerfile ├── pusher-service ├── messages.go ├── client.go ├── main.go └── hub.go ├── util └── util.go ├── db ├── repository.go └── postgres.go ├── search ├── repository.go └── elastic.go ├── LICENSE ├── meow-service ├── handlers.go └── main.go ├── docker-compose.yaml ├── query-service ├── main.go └── handlers.go └── go.sum /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/go.sum: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/lib/pq 2 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/.gitignore: -------------------------------------------------------------------------------- 1 | .db 2 | *.test 3 | *~ 4 | *.swp 5 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | tmp/ 3 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | *.test 3 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gorilla/mux 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/kelseyhightower/envconfig 2 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinrab/meower/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | port: 3000, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gorilla/websocket 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:10.3 2 | 3 | COPY up.sql /docker-entrypoint-initdb.d/1.sql 4 | 5 | CMD ["postgres"] 6 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/elastic/go-elasticsearch/v7 2 | 3 | go 1.11 4 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nats-io/jwt 2 | 3 | require github.com/nats-io/nkeys v0.1.0 4 | -------------------------------------------------------------------------------- /nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.13.12 2 | 3 | COPY nginx.conf /etc/nginx/nginx.conf 4 | 5 | CMD ["nginx", "-g", "daemon off;"] 6 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/TODO.md: -------------------------------------------------------------------------------- 1 | 2 | # General 3 | 4 | - [ ] Child key derivation 5 | - [ ] Hardware support, e.g. YubiHSM 6 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nats-io/nkeys 2 | 3 | require golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 4 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: off 2 | 3 | coverage: 4 | status: 5 | patch: off 6 | 7 | ignore: 8 | - "esapi/api.*.go" 9 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/env_os.go: -------------------------------------------------------------------------------- 1 | // +build appengine go1.5 2 | 3 | package envconfig 4 | 5 | import "os" 6 | 7 | var lookupEnv = os.LookupEnv 8 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/env_syscall.go: -------------------------------------------------------------------------------- 1 | // +build !appengine,!go1.5 2 | 3 | package envconfig 4 | 5 | import "syscall" 6 | 7 | var lookupEnv = syscall.Getenv 8 | -------------------------------------------------------------------------------- /postgres/up.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS meows; 2 | CREATE TABLE meows ( 3 | id VARCHAR(32) PRIMARY KEY, 4 | body TEXT NOT NULL, 5 | created_at TIMESTAMP WITH TIME ZONE NOT NULL 6 | ); 7 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/MAINTAINERS: -------------------------------------------------------------------------------- 1 | Kelsey Hightower kelsey.hightower@gmail.com github.com/kelseyhightower 2 | Travis Parker travis.parker@gmail.com github.com/teepark 3 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/oid/doc.go: -------------------------------------------------------------------------------- 1 | // Package oid contains OID constants 2 | // as defined by the Postgres server. 3 | package oid 4 | 5 | // Oid is a Postgres Object ID. 6 | type Oid uint32 7 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## 0.3.0 4 | 5 | * Removed revocation claims in favor of timestamp-based revocation maps in account and export claims. 6 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nats-io/nats.go 2 | 3 | require ( 4 | github.com/nats-io/jwt v0.3.0 5 | github.com/nats-io/nkeys v0.1.0 6 | github.com/nats-io/nuid v1.0.1 7 | ) 8 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nuid/GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # NATS NUID Governance 2 | 3 | NATS NUID is part of the NATS project and is subject to the [NATS Governance](https://github.com/nats-io/nats-general/blob/master/GOVERNANCE.md). -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at https://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at https://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Meower: A Social Network for Cats 2 | 3 | The underlying source code for the [Building a Microservices Application in Go Following the CQRS Pattern](https://outcrawl.com/go-microservices-cqrs-docker) article. 4 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= 2 | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 3 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # NATS NKEYS Governance 2 | 3 | NATS NKEYS is part of the NATS project and is subject to the [NATS Governance](https://github.com/nats-io/nats-general/blob/master/GOVERNANCE.md). -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # Maintainers 2 | 3 | Maintainership is on a per project basis. 4 | 5 | ### Core-maintainers 6 | - Derek Collison [@derekcollison](https://github.com/derekcollison) -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nuid/MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # Maintainers 2 | 3 | Maintainership is on a per project basis. 4 | 5 | ### Core-maintainers 6 | - Derek Collison [@derekcollison](https://github.com/derekcollison) -------------------------------------------------------------------------------- /schema/model.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Meow struct { 8 | ID string `json:"id"` 9 | Body string `json:"body"` 10 | CreatedAt time.Time `json:"created_at"` 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.4.x 5 | - 1.5.x 6 | - 1.6.x 7 | - 1.7.x 8 | - 1.8.x 9 | - 1.9.x 10 | - 1.10.x 11 | - 1.11.x 12 | - 1.12.x 13 | - tip 14 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # NATS Go Client Governance 2 | 3 | NATS Go Client (go-nats) is part of the NATS project and is subject to the [NATS Governance](https://github.com/nats-io/nats-general/blob/master/GOVERNANCE.md). -------------------------------------------------------------------------------- /vendor/github.com/tinrab/retry/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /frontend/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import 'bootstrap/scss/bootstrap.scss'; 3 | 4 | import App from './App.vue'; 5 | import store from './store'; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | new Vue({ 10 | store, 11 | render: (h) => h(App), 12 | }).$mount('#app'); 13 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of Gorilla WebSocket authors for copyright 2 | # purposes. 3 | # 4 | # Please keep the list sorted. 5 | 6 | Gary Burd 7 | Google LLC (https://opensource.google.com/) 8 | Joachim Bauch 9 | 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.go] 12 | indent_size = 4 13 | indent_style = tab 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/trace_17.go: -------------------------------------------------------------------------------- 1 | // +build !go1.8 2 | 3 | package websocket 4 | 5 | import ( 6 | "crypto/tls" 7 | "net/http/httptrace" 8 | ) 9 | 10 | func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { 11 | return doHandshake(tlsConn, cfg) 12 | } 13 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # IDE Files 15 | .vscode 16 | .idea/ -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of gorilla/mux authors for copyright purposes. 2 | # 3 | # Please keep the list sorted. 4 | 5 | Google LLC (https://opensource.google.com/) 6 | Kamil Kisielk 7 | Matt Silverlock 8 | Rodrigo Moraes (https://github.com/moraes) 9 | -------------------------------------------------------------------------------- /event/messages.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Message interface { 8 | Key() string 9 | } 10 | 11 | type MeowCreatedMessage struct { 12 | ID string 13 | Body string 14 | CreatedAt time.Time 15 | } 16 | 17 | func (m *MeowCreatedMessage) Key() string { 18 | return "meow.created" 19 | } 20 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/ssl_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package pq 4 | 5 | // sslKeyPermissions checks the permissions on user-supplied ssl key files. 6 | // The key file should have very little access. 7 | // 8 | // libpq does not check key file permissions on Windows. 9 | func sslKeyPermissions(string) error { return nil } 10 | -------------------------------------------------------------------------------- /vendor/github.com/tinrab/retry/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test cover 2 | 3 | build: 4 | go build 5 | 6 | test: 7 | gofmt -s -w *.go 8 | goimports -w *.go 9 | go vet ./... 10 | go test -v 11 | go test -v --race 12 | staticcheck ./... 13 | 14 | fmt: 15 | gofmt -w -s *.go 16 | 17 | cover: 18 | go test -v -covermode=count -coverprofile=coverage.out 19 | go tool cover -html=coverage.out 20 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | build/ 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 15 | .glide/ 16 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tinrab/meower 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/elastic/go-elasticsearch/v7 v7.6.0 7 | github.com/gorilla/mux v1.7.4 8 | github.com/gorilla/websocket v1.4.1 9 | github.com/kelseyhightower/envconfig v1.4.0 10 | github.com/lib/pq v1.3.0 11 | github.com/nats-io/nats.go v1.9.1 12 | github.com/segmentio/ksuid v1.0.2 13 | github.com/tinrab/retry v1.0.0 14 | ) 15 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/internal/version/version.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more agreements. 2 | // Elasticsearch B.V. licenses this file to you under the Apache 2.0 License. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | package version 6 | 7 | // Client returns the client version as a string. 8 | // 9 | const Client = "7.6.0" 10 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # Maintainers 2 | 3 | Maintainership is on a per project basis. 4 | 5 | ### Core-maintainers 6 | - Derek Collison [@derekcollison](https://github.com/derekcollison) 7 | - Ivan Kozlovic [@kozlovic](https://github.com/kozlovic) 8 | 9 | ### Maintainers 10 | - Waldemar Quevedo [@wallyqs](https://github.com/wallyqs) -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nuid/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | 24 | .idea/ 25 | *.iml 26 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nuid/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.9.x 5 | - 1.10.x 6 | 7 | install: 8 | - go get -t ./... 9 | - go get github.com/mattn/goveralls 10 | 11 | script: 12 | - go fmt ./... 13 | - go vet ./... 14 | - go test -v 15 | - go test -v --race 16 | - go test -v -covermode=count -coverprofile=coverage.out 17 | - $HOME/gopath/bin/goveralls -coverprofile coverage.out -service travis-ci 18 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Kelsey Hightower. All rights reserved. 2 | // Use of this source code is governed by the MIT License that can be found in 3 | // the LICENSE file. 4 | 5 | // Package envconfig implements decoding of environment variables based on a user 6 | // defined specification. A typical use is using environment variables for 7 | // configuration settings. 8 | package envconfig 9 | -------------------------------------------------------------------------------- /frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "jsxBracketSameLine": false, 4 | "printWidth": 80, 5 | "semi": true, 6 | "singleQuote": true, 7 | "arrowParens": "always", 8 | "tabWidth": 2, 9 | "trailingComma": "all", 10 | "useTabs": false, 11 | "overrides": [ 12 | { 13 | "files": ["*.scss", "*.css"], 14 | "options": { 15 | "singleQuote": false 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/mask_safe.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of 2 | // this source code is governed by a BSD-style license that can be found in the 3 | // LICENSE file. 4 | 5 | // +build appengine 6 | 7 | package websocket 8 | 9 | func maskBytes(key [4]byte, pos int, b []byte) int { 10 | for i := range b { 11 | b[i] ^= key[pos&3] 12 | pos++ 13 | } 14 | return pos & 3 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/conn_write.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.8 6 | 7 | package websocket 8 | 9 | import "net" 10 | 11 | func (c *Conn) writeBufs(bufs ...[]byte) error { 12 | b := net.Buffers(bufs) 13 | _, err := b.WriteTo(c.conn) 14 | return err 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/client_clone.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.8 6 | 7 | package websocket 8 | 9 | import "crypto/tls" 10 | 11 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 12 | if cfg == nil { 13 | return &tls.Config{} 14 | } 15 | return cfg.Clone() 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/segmentio/ksuid/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | /ksuid 26 | 27 | # Emacs 28 | *~ 29 | 30 | # govendor 31 | /vendor/*/ 32 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/trace.go: -------------------------------------------------------------------------------- 1 | // +build go1.8 2 | 3 | package websocket 4 | 5 | import ( 6 | "crypto/tls" 7 | "net/http/httptrace" 8 | ) 9 | 10 | func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { 11 | if trace.TLSHandshakeStart != nil { 12 | trace.TLSHandshakeStart() 13 | } 14 | err := doHandshake(tlsConn, cfg) 15 | if trace.TLSHandshakeDone != nil { 16 | trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) 17 | } 18 | return err 19 | } 20 | -------------------------------------------------------------------------------- /vendor/github.com/tinrab/retry/README.md: -------------------------------------------------------------------------------- 1 | # Retry 2 | 3 | A simple retry package for Go. 4 | 5 | ## Usage 6 | 7 | Retry 10 times. 8 | 9 | ```go 10 | err := retry.Do(10, thisFunctionMayFail) 11 | if err != nil { 12 | log.Fatal(err) 13 | } 14 | ``` 15 | 16 | Retry with a delay. 17 | 18 | ```go 19 | err := retry.DoSleep(10, 3 * time.Second, thisFunctionMayFail) 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | ``` 24 | 25 | Retry forever. 26 | 27 | ```go 28 | retry.DoForever(thisFunctionMayFail) 29 | ``` 30 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/conn_write_legacy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.8 6 | 7 | package websocket 8 | 9 | func (c *Conn) writeBufs(bufs ...[]byte) error { 10 | for _, buf := range bufs { 11 | if len(buf) > 0 { 12 | if _, err := c.conn.Write(buf); err != nil { 13 | return err 14 | } 15 | } 16 | } 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/user_posix.go: -------------------------------------------------------------------------------- 1 | // Package pq is a pure Go Postgres driver for the database/sql package. 2 | 3 | // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris rumprun 4 | 5 | package pq 6 | 7 | import ( 8 | "os" 9 | "os/user" 10 | ) 11 | 12 | func userCurrent() (string, error) { 13 | u, err := user.Current() 14 | if err == nil { 15 | return u.Username, nil 16 | } 17 | 18 | name := os.Getenv("USER") 19 | if name != "" { 20 | return name, nil 21 | } 22 | 23 | return "", ErrCouldNotDetectUsername 24 | } 25 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/ssl_permissions.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package pq 4 | 5 | import "os" 6 | 7 | // sslKeyPermissions checks the permissions on user-supplied ssl key files. 8 | // The key file should have very little access. 9 | // 10 | // libpq does not check key file permissions on Windows. 11 | func sslKeyPermissions(sslkey string) error { 12 | info, err := os.Stat(sslkey) 13 | if err != nil { 14 | return err 15 | } 16 | if info.Mode().Perm()&0077 != 0 { 17 | return ErrSSLKeyHasWorldPermissions 18 | } 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13-alpine3.11 AS build 2 | RUN apk --no-cache add gcc g++ make ca-certificates 3 | WORKDIR /go/src/github.com/tinrab/meower 4 | 5 | COPY go.mod go.sum ./ 6 | COPY vendor vendor 7 | COPY util util 8 | COPY event event 9 | COPY db db 10 | COPY search search 11 | COPY schema schema 12 | COPY meow-service meow-service 13 | COPY query-service query-service 14 | COPY pusher-service pusher-service 15 | 16 | RUN GO111MODULE=on go install -mod vendor ./... 17 | 18 | FROM alpine:3.11 19 | WORKDIR /usr/bin 20 | COPY --from=build /go/bin . 21 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | 24 | # Emacs 25 | *~ 26 | \#*\# 27 | .\#* 28 | 29 | # vi/vim 30 | .??*.swp 31 | 32 | # Mac 33 | .DS_Store 34 | 35 | # Eclipse 36 | .project 37 | .settings/ 38 | 39 | # bin 40 | 41 | # Goland 42 | .idea -------------------------------------------------------------------------------- /pusher-service/messages.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | const ( 8 | KindMeowCreated = iota + 1 9 | ) 10 | 11 | type MeowCreatedMessage struct { 12 | Kind uint32 `json:"kind"` 13 | ID string `json:"id"` 14 | Body string `json:"body"` 15 | CreatedAt time.Time `json:"created_at"` 16 | } 17 | 18 | func newMeowCreatedMessage(id string, body string, createdAt time.Time) *MeowCreatedMessage { 19 | return &MeowCreatedMessage{ 20 | Kind: KindMeowCreated, 21 | ID: id, 22 | Body: body, 23 | CreatedAt: createdAt, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.12.x 5 | - 1.11.x 6 | 7 | install: 8 | - go get -t ./... 9 | - go get github.com/mattn/goveralls 10 | - go get github.com/wadey/gocovmerge 11 | - go get -u honnef.co/go/tools/cmd/staticcheck 12 | - go get -u github.com/client9/misspell/cmd/misspell 13 | 14 | before_script: 15 | - $(exit $(go fmt ./... | wc -l)) 16 | - go vet ./... 17 | - misspell -error -locale US . 18 | - staticcheck ./... 19 | 20 | script: 21 | - if [[ "$TRAVIS_GO_VERSION" == 1.10.* ]] ; then ./scripts/cov.sh TRAVIS; else go test -v -race ./...; fi 22 | -------------------------------------------------------------------------------- /frontend/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | frontend 10 | 11 | 12 | 13 | 17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/uuid.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | ) 7 | 8 | // decodeUUIDBinary interprets the binary format of a uuid, returning it in text format. 9 | func decodeUUIDBinary(src []byte) ([]byte, error) { 10 | if len(src) != 16 { 11 | return nil, fmt.Errorf("pq: unable to decode uuid; bad length: %d", len(src)) 12 | } 13 | 14 | dst := make([]byte, 36) 15 | dst[8], dst[13], dst[18], dst[23] = '-', '-', '-', '-' 16 | hex.Encode(dst[0:], src[0:4]) 17 | hex.Encode(dst[9:], src[4:6]) 18 | hex.Encode(dst[14:], src[6:8]) 19 | hex.Encode(dst[19:], src[8:10]) 20 | hex.Encode(dst[24:], src[10:16]) 21 | 22 | return dst, nil 23 | } 24 | -------------------------------------------------------------------------------- /util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | ) 8 | 9 | func ResponseOk(w http.ResponseWriter, body interface{}) { 10 | w.Header().Set("Content-Type", "application/json") 11 | w.WriteHeader(http.StatusOK) 12 | 13 | if err := json.NewEncoder(w).Encode(body); err != nil { 14 | log.Fatal(err) 15 | } 16 | } 17 | 18 | func ResponseError(w http.ResponseWriter, code int, message string) { 19 | w.Header().Set("Content-Type", "application/json") 20 | w.WriteHeader(code) 21 | 22 | body := map[string]string{ 23 | "error": message, 24 | } 25 | if err := json.NewEncoder(w).Encode(body); err != nil { 26 | log.Fatal(err) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /db/repository.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tinrab/meower/schema" 7 | ) 8 | 9 | type Repository interface { 10 | Close() 11 | InsertMeow(ctx context.Context, meow schema.Meow) error 12 | ListMeows(ctx context.Context, skip uint64, take uint64) ([]schema.Meow, error) 13 | } 14 | 15 | var impl Repository 16 | 17 | func SetRepository(repository Repository) { 18 | impl = repository 19 | } 20 | 21 | func Close() { 22 | impl.Close() 23 | } 24 | 25 | func InsertMeow(ctx context.Context, meow schema.Meow) error { 26 | return impl.InsertMeow(ctx, meow) 27 | } 28 | 29 | func ListMeows(ctx context.Context, skip uint64, take uint64) ([]schema.Meow, error) { 30 | return impl.ListMeows(ctx, skip, take) 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 2 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 3 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 4 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 5 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 6 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 7 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 8 | -------------------------------------------------------------------------------- /event/event.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import "github.com/tinrab/meower/schema" 4 | 5 | type Store interface { 6 | Close() 7 | PublishMeowCreated(meow schema.Meow) error 8 | SubscribeMeowCreated() (<-chan MeowCreatedMessage, error) 9 | OnMeowCreated(f func(MeowCreatedMessage)) error 10 | } 11 | 12 | var impl Store 13 | 14 | func SetEventStore(es Store) { 15 | impl = es 16 | } 17 | 18 | func Close() { 19 | impl.Close() 20 | } 21 | 22 | func PublishMeowCreated(meow schema.Meow) error { 23 | return impl.PublishMeowCreated(meow) 24 | } 25 | 26 | func SubscribeMeowCreated() (<-chan MeowCreatedMessage, error) { 27 | return impl.SubscribeMeowCreated() 28 | } 29 | 30 | func OnMeowCreated(f func(MeowCreatedMessage)) error { 31 | return impl.OnMeowCreated(f) 32 | } 33 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.12.x 5 | - 1.11.x 6 | env: 7 | - GO111MODULE=off 8 | go_import_path: github.com/nats-io/nats.go 9 | install: 10 | - go get -t ./... 11 | - go get github.com/nats-io/nats-server 12 | - go get github.com/mattn/goveralls 13 | - go get github.com/wadey/gocovmerge 14 | - go get -u honnef.co/go/tools/cmd/staticcheck 15 | - go get -u github.com/client9/misspell/cmd/misspell 16 | before_script: 17 | - $(exit $(go fmt ./... | wc -l)) 18 | - go vet ./... 19 | - find . -type f -name "*.go" | xargs misspell -error -locale US 20 | - staticcheck ./... 21 | script: 22 | - go test -i -race ./... 23 | - if [[ "$TRAVIS_GO_VERSION" =~ 1.12 ]]; then ./scripts/cov.sh TRAVIS; else go test -race -v -p=1 ./... --failfast; fi 24 | -------------------------------------------------------------------------------- /search/repository.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tinrab/meower/schema" 7 | ) 8 | 9 | type Repository interface { 10 | Close() 11 | InsertMeow(ctx context.Context, meow schema.Meow) error 12 | SearchMeows(ctx context.Context, query string, skip uint64, take uint64) ([]schema.Meow, error) 13 | } 14 | 15 | var impl Repository 16 | 17 | func SetRepository(repository Repository) { 18 | impl = repository 19 | } 20 | 21 | func Close() { 22 | impl.Close() 23 | } 24 | 25 | func InsertMeow(ctx context.Context, meow schema.Meow) error { 26 | return impl.InsertMeow(ctx, meow) 27 | } 28 | 29 | func SearchMeows(ctx context.Context, query string, skip uint64, take uint64) ([]schema.Meow, error) { 30 | return impl.SearchMeows(ctx, query, skip, take) 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/TESTS.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | ## Running Tests 4 | 5 | `go test` is used for testing. A running PostgreSQL 6 | server is required, with the ability to log in. The 7 | database to connect to test with is "pqgotest," on 8 | "localhost" but these can be overridden using [environment 9 | variables](https://www.postgresql.org/docs/9.3/static/libpq-envars.html). 10 | 11 | Example: 12 | 13 | PGHOST=/run/postgresql go test 14 | 15 | ## Benchmarks 16 | 17 | A benchmark suite can be run as part of the tests: 18 | 19 | go test -bench . 20 | 21 | ## Example setup (Docker) 22 | 23 | Run a postgres container: 24 | 25 | ``` 26 | docker run --expose 5432:5432 postgres 27 | ``` 28 | 29 | Run tests: 30 | 31 | ``` 32 | PGHOST=localhost PGPORT=5432 PGUSER=postgres PGSSLMODE=disable PGDATABASE=postgres go test 33 | ``` 34 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.12.x 5 | - 1.11.x 6 | 7 | install: 8 | - go get -t ./... 9 | - go get github.com/mattn/goveralls 10 | - go get -u honnef.co/go/tools/cmd/staticcheck 11 | - go get -u github.com/client9/misspell/cmd/misspell 12 | 13 | before_script: 14 | - $(exit $(go fmt ./... | wc -l)) 15 | - go vet ./... 16 | - misspell -error -locale US . 17 | - staticcheck ./... 18 | 19 | script: 20 | - go test -v 21 | - go test -v --race 22 | - go test -v -covermode=count -coverprofile=coverage.out 23 | - $HOME/gopath/bin/goveralls -coverprofile coverage.out -service travis-ci 24 | 25 | #deploy: 26 | #- provider: script 27 | # skip_cleanup: true 28 | # script: curl -sL http://git.io/goreleaser | bash 29 | # on: 30 | # tags: true 31 | # condition: $TRAVIS_OS_NAME = linux -------------------------------------------------------------------------------- /frontend/src/components/Meow.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 29 | 30 | 41 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/esapi/esapi.request.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more agreements. 2 | // Elasticsearch B.V. licenses this file to you under the Apache 2.0 License. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | package esapi 6 | 7 | import ( 8 | "context" 9 | "io" 10 | "net/http" 11 | ) 12 | 13 | const ( 14 | headerContentType = "Content-Type" 15 | ) 16 | 17 | var ( 18 | headerContentTypeJSON = []string{"application/json"} 19 | ) 20 | 21 | // Request defines the API request. 22 | // 23 | type Request interface { 24 | Do(ctx context.Context, transport Transport) (*Response, error) 25 | } 26 | 27 | // newRequest creates an HTTP request. 28 | // 29 | func newRequest(method, path string, body io.Reader) (*http.Request, error) { 30 | return http.NewRequest(method, path, body) 31 | } 32 | -------------------------------------------------------------------------------- /frontend/src/components/Search.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 36 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/test_helpers.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mux 6 | 7 | import "net/http" 8 | 9 | // SetURLVars sets the URL variables for the given request, to be accessed via 10 | // mux.Vars for testing route behaviour. Arguments are not modified, a shallow 11 | // copy is returned. 12 | // 13 | // This API should only be used for testing purposes; it provides a way to 14 | // inject variables into the request context. Alternatively, URL variables 15 | // can be set by making a route that captures the required variables, 16 | // starting a server and sending the request to that server. 17 | func SetURLVars(r *http.Request, val map[string]string) *http.Request { 18 | return requestWithVars(r, val) 19 | } 20 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/.goreleaser.yml: -------------------------------------------------------------------------------- 1 | project_name: nkeys 2 | release: 3 | github: 4 | owner: nats-io 5 | name: nkeys 6 | name_template: '{{.Tag}}' 7 | draft: true 8 | builds: 9 | - main: ./nk/main.go 10 | ldflags: "-X main.Version={{.Tag}}_{{.Commit}}" 11 | binary: nk 12 | goos: 13 | - linux 14 | - darwin 15 | goarch: 16 | - amd64 17 | 18 | 19 | dist: build 20 | 21 | archive: 22 | wrap_in_directory: true 23 | name_template: '{{ .ProjectName }}-v{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm 24 | }}v{{ .Arm }}{{ end }}' 25 | format: zip 26 | 27 | checksum: 28 | name_template: '{{ .ProjectName }}-v{{ .Version }}-checksums.txt' 29 | 30 | snapshot: 31 | name_template: 'dev' 32 | 33 | nfpm: 34 | formats: 35 | - deb 36 | bindir: /usr/local/bin 37 | description: NKeys utility cli program 38 | vendor: nats-io 39 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "axios": "^0.21.2", 11 | "bootstrap": "^4.1.1", 12 | "timeago.js": "^3.0.2", 13 | "vue": "^2.5.16", 14 | "vue-native-websocket": "^2.0.7", 15 | "vuex": "^3.0.1" 16 | }, 17 | "devDependencies": { 18 | "@vue/cli-plugin-babel": "^5.0.8", 19 | "@vue/cli-service": "^5.0.8", 20 | "node-sass": "^9.0.0", 21 | "sass-loader": "^6.0.6", 22 | "vue-template-compiler": "^2.5.13" 23 | }, 24 | "babel": { 25 | "presets": [ 26 | "@vue/app" 27 | ] 28 | }, 29 | "postcss": { 30 | "plugins": { 31 | "autoprefixer": {} 32 | } 33 | }, 34 | "browserslist": [ 35 | "> 1%", 36 | "last 2 versions", 37 | "not ie <= 8" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/go.sum: -------------------------------------------------------------------------------- 1 | github.com/nats-io/nkeys v0.1.0 h1:qMd4+pRHgdr1nAClu+2h/2a5F2TmKcCzjCDazVgRoX4= 2 | github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= 3 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 4 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 5 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 6 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 7 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 8 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 9 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 10 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/util/tls.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build go1.8 15 | 16 | package util 17 | 18 | import "crypto/tls" 19 | 20 | // CloneTLSConfig returns a copy of c. 21 | func CloneTLSConfig(c *tls.Config) *tls.Config { 22 | if c == nil { 23 | return &tls.Config{} 24 | } 25 | 26 | return c.Clone() 27 | } 28 | -------------------------------------------------------------------------------- /pusher-service/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/gorilla/websocket" 7 | ) 8 | 9 | type Client struct { 10 | hub *Hub 11 | id int 12 | socket *websocket.Conn 13 | outbound chan []byte 14 | } 15 | 16 | func newClient(hub *Hub, socket *websocket.Conn) *Client { 17 | return &Client{ 18 | hub: hub, 19 | socket: socket, 20 | outbound: make(chan []byte), 21 | } 22 | } 23 | 24 | func (c *Client) write() { 25 | for { 26 | select { 27 | case data, ok := <-c.outbound: 28 | if !ok { 29 | if err := c.socket.WriteMessage(websocket.CloseMessage, []byte{}); err != nil { 30 | log.Print(err) 31 | } 32 | return 33 | } 34 | if err := c.socket.WriteMessage(websocket.TextMessage, data); err != nil { 35 | log.Print(err) 36 | c.hub.disconnect(c) 37 | } 38 | } 39 | } 40 | } 41 | 42 | func (c Client) close() { 43 | if err := c.socket.Close(); err != nil { 44 | log.Fatal(err) 45 | } 46 | close(c.outbound) 47 | } 48 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/Dockerfile: -------------------------------------------------------------------------------- 1 | # $ docker build --file Dockerfile --tag elastic/go-elasticsearch . 2 | # 3 | # $ docker run -it --network elasticsearch --volume $PWD/tmp:/tmp:rw --rm elastic/go-elasticsearch gotestsum --format=short-verbose --junitfile=/tmp/integration-junit.xml -- --cover --coverprofile=/tmp/integration-coverage.out --tags='integration' -v ./... 4 | # 5 | 6 | ARG VERSION=1-alpine 7 | FROM golang:${VERSION} 8 | 9 | RUN apk add --no-cache --quiet make curl git jq unzip tree && \ 10 | go get -u golang.org/x/lint/golint && \ 11 | curl -sSL --retry 3 --retry-connrefused https://github.com/gotestyourself/gotestsum/releases/download/v0.3.5/gotestsum_0.3.5_linux_amd64.tar.gz | tar -xz -C /usr/local/bin gotestsum 12 | 13 | VOLUME ["/tmp"] 14 | 15 | ENV CGO_ENABLED=0 16 | ENV TERM xterm-256color 17 | 18 | WORKDIR /go-elasticsearch 19 | COPY . . 20 | 21 | RUN go mod download && go mod vendor && \ 22 | cd internal/cmd/generate && go mod download && go mod vendor 23 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/user_windows.go: -------------------------------------------------------------------------------- 1 | // Package pq is a pure Go Postgres driver for the database/sql package. 2 | package pq 3 | 4 | import ( 5 | "path/filepath" 6 | "syscall" 7 | ) 8 | 9 | // Perform Windows user name lookup identically to libpq. 10 | // 11 | // The PostgreSQL code makes use of the legacy Win32 function 12 | // GetUserName, and that function has not been imported into stock Go. 13 | // GetUserNameEx is available though, the difference being that a 14 | // wider range of names are available. To get the output to be the 15 | // same as GetUserName, only the base (or last) component of the 16 | // result is returned. 17 | func userCurrent() (string, error) { 18 | pw_name := make([]uint16, 128) 19 | pwname_size := uint32(len(pw_name)) - 1 20 | err := syscall.GetUserNameEx(syscall.NameSamCompatible, &pw_name[0], &pwname_size) 21 | if err != nil { 22 | return "", ErrCouldNotDetectUsername 23 | } 24 | s := syscall.UTF16ToString(pw_name) 25 | u := filepath.Base(s) 26 | return u, nil 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/TODO.md: -------------------------------------------------------------------------------- 1 | 2 | - [ ] Better constructors, options handling 3 | - [ ] Functions for callback settings after connection created. 4 | - [ ] Better options for subscriptions. Slow Consumer state settable, Go routines vs Inline. 5 | - [ ] Move off of channels for subscribers, use syncPool linkedLists, etc with highwater. 6 | - [ ] Test for valid subjects on publish and subscribe? 7 | - [ ] SyncSubscriber and Next for EncodedConn 8 | - [ ] Fast Publisher? 9 | - [ ] pooling for structs used? leaky bucket? 10 | - [ ] Timeout 0 should work as no timeout 11 | - [x] Ping timer 12 | - [x] Name in Connect for gnatsd 13 | - [x] Asynchronous error handling 14 | - [x] Parser rewrite 15 | - [x] Reconnect 16 | - [x] Hide Lock 17 | - [x] Easier encoder interface 18 | - [x] QueueSubscribeSync 19 | - [x] Make nats specific errors prefixed with 'nats:' 20 | - [x] API test for closed connection 21 | - [x] TLS/SSL 22 | - [x] Stats collection 23 | - [x] Disconnect detection 24 | - [x] Optimized Publish (coalescing) 25 | - [x] Do Examples via Go style 26 | - [x] Standardized Errors 27 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/join.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "io" 9 | "strings" 10 | ) 11 | 12 | // JoinMessages concatenates received messages to create a single io.Reader. 13 | // The string term is appended to each message. The returned reader does not 14 | // support concurrent calls to the Read method. 15 | func JoinMessages(c *Conn, term string) io.Reader { 16 | return &joinReader{c: c, term: term} 17 | } 18 | 19 | type joinReader struct { 20 | c *Conn 21 | term string 22 | r io.Reader 23 | } 24 | 25 | func (r *joinReader) Read(p []byte) (int, error) { 26 | if r.r == nil { 27 | var err error 28 | _, r.r, err = r.c.NextReader() 29 | if err != nil { 30 | return 0, err 31 | } 32 | if r.term != "" { 33 | r.r = io.MultiReader(r.r, strings.NewReader(r.term)) 34 | } 35 | } 36 | n, err := r.r.Read(p) 37 | if err == io.EOF { 38 | err = nil 39 | r.r = nil 40 | } 41 | return n, err 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/revocation_list.go: -------------------------------------------------------------------------------- 1 | package jwt 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // RevocationList is used to store a mapping of public keys to unix timestamps 8 | type RevocationList map[string]int64 9 | 10 | // Revoke enters a revocation by publickey and timestamp into this export 11 | // If there is already a revocation for this public key that is newer, it is kept. 12 | func (r RevocationList) Revoke(pubKey string, timestamp time.Time) { 13 | newTS := timestamp.Unix() 14 | if ts, ok := r[pubKey]; ok && ts > newTS { 15 | return 16 | } 17 | 18 | r[pubKey] = newTS 19 | } 20 | 21 | // ClearRevocation removes any revocation for the public key 22 | func (r RevocationList) ClearRevocation(pubKey string) { 23 | delete(r, pubKey) 24 | } 25 | 26 | // IsRevoked checks if the public key is in the revoked list with a timestamp later than 27 | // the one passed in. Generally this method is called with time.Now() but other time's can 28 | // be used for testing. 29 | func (r RevocationList) IsRevoked(pubKey string, timestamp time.Time) bool { 30 | ts, ok := r[pubKey] 31 | return ok && ts > timestamp.Unix() 32 | } 33 | -------------------------------------------------------------------------------- /frontend/src/components/Timeline.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 44 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2013, 'pq' Contributors 2 | Portions Copyright (C) 2011 Blake Mizerany 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tin Rabzelj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | events { 5 | worker_connections 1024; 6 | } 7 | 8 | http { 9 | upstream meows_POST { 10 | server meow:8080; 11 | } 12 | 13 | upstream meows_GET { 14 | server query:8080; 15 | } 16 | 17 | upstream search_GET { 18 | server query:8080; 19 | } 20 | 21 | upstream pusher { 22 | server pusher:8080; 23 | } 24 | 25 | server { 26 | proxy_set_header X-Real-IP $remote_addr; 27 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 28 | proxy_set_header Host $http_host; 29 | add_header Access-Control-Allow-Origin *; 30 | 31 | location /meows { 32 | limit_except GET POST OPTIONS { 33 | deny all; 34 | } 35 | proxy_pass http://meows_$request_method; 36 | } 37 | 38 | location /search { 39 | limit_except GET OPTIONS { 40 | deny all; 41 | } 42 | proxy_pass http://search_GET; 43 | } 44 | 45 | location /pusher { 46 | proxy_set_header Upgrade $http_upgrade; 47 | proxy_set_header Connection "upgrade"; 48 | proxy_pass http://pusher; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vendor/github.com/kelseyhightower/envconfig/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Kelsey Hightower 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/tinrab/retry/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tin Rabzelj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/segmentio/ksuid/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Segment.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.11.x 5 | - 1.12.x 6 | - master 7 | 8 | sudo: true 9 | 10 | env: 11 | global: 12 | - PGUSER=postgres 13 | - PQGOSSLTESTS=1 14 | - PQSSLCERTTEST_PATH=$PWD/certs 15 | - PGHOST=127.0.0.1 16 | matrix: 17 | - PGVERSION=10 18 | - PGVERSION=9.6 19 | - PGVERSION=9.5 20 | - PGVERSION=9.4 21 | 22 | before_install: 23 | - ./.travis.sh postgresql_uninstall 24 | - ./.travis.sh pgdg_repository 25 | - ./.travis.sh postgresql_install 26 | - ./.travis.sh postgresql_configure 27 | - ./.travis.sh client_configure 28 | - go get golang.org/x/tools/cmd/goimports 29 | - go get golang.org/x/lint/golint 30 | - GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2019.2.1 31 | 32 | before_script: 33 | - createdb pqgotest 34 | - createuser -DRS pqgossltest 35 | - createuser -DRS pqgosslcert 36 | 37 | script: 38 | - > 39 | goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }' 40 | - go vet ./... 41 | - staticcheck -go 1.11 ./... 42 | - golint ./... 43 | - PQTEST_BINARY_PARAMETERS=no go test -race -v ./... 44 | - PQTEST_BINARY_PARAMETERS=yes go test -race -v ./... 45 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/elastic/go-elasticsearch/v7 v7.6.0 2 | github.com/elastic/go-elasticsearch/v7 3 | github.com/elastic/go-elasticsearch/v7/esapi 4 | github.com/elastic/go-elasticsearch/v7/estransport 5 | github.com/elastic/go-elasticsearch/v7/internal/version 6 | # github.com/gorilla/mux v1.7.4 7 | github.com/gorilla/mux 8 | # github.com/gorilla/websocket v1.4.1 9 | github.com/gorilla/websocket 10 | # github.com/kelseyhightower/envconfig v1.4.0 11 | github.com/kelseyhightower/envconfig 12 | # github.com/lib/pq v1.3.0 13 | github.com/lib/pq 14 | github.com/lib/pq/oid 15 | github.com/lib/pq/scram 16 | # github.com/nats-io/jwt v0.3.0 17 | github.com/nats-io/jwt 18 | # github.com/nats-io/nats.go v1.9.1 19 | github.com/nats-io/nats.go 20 | github.com/nats-io/nats.go/encoders/builtin 21 | github.com/nats-io/nats.go/util 22 | # github.com/nats-io/nkeys v0.1.0 23 | github.com/nats-io/nkeys 24 | # github.com/nats-io/nuid v1.0.1 25 | github.com/nats-io/nuid 26 | # github.com/segmentio/ksuid v1.0.2 27 | github.com/segmentio/ksuid 28 | # github.com/tinrab/retry v1.0.0 29 | github.com/tinrab/retry 30 | # golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 31 | golang.org/x/crypto/ed25519 32 | golang.org/x/crypto/ed25519/internal/edwards25519 33 | -------------------------------------------------------------------------------- /vendor/github.com/tinrab/retry/retry.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type RetryFunc func(int) error 8 | 9 | // Do retries calling function f n-times. 10 | // It returns an error if none of the tries succeeds. 11 | func Do(n int, f RetryFunc) (err error) { 12 | for i := 0; i < n; i++ { 13 | err = f(i) 14 | if err == nil { 15 | return nil 16 | } 17 | } 18 | return err 19 | } 20 | 21 | // DoSleep retries calling function f n-times and sleeps for d after each call. 22 | // It returns an error if none of the tries succeeds. 23 | func DoSleep(n int, d time.Duration, f RetryFunc) (err error) { 24 | for i := 0; i < n; i++ { 25 | err = f(i) 26 | if err == nil { 27 | return nil 28 | } 29 | time.Sleep(d) 30 | } 31 | return err 32 | } 33 | 34 | // Forever keeps trying to call function f until it succeeds. 35 | func Forever(f RetryFunc) { 36 | for i := 0; ; i++ { 37 | err := f(i) 38 | if err == nil { 39 | return 40 | } 41 | } 42 | } 43 | 44 | // ForeverSleep keeps trying to call function f until it succeeds, and sleeps after each failure. 45 | func ForeverSleep(d time.Duration, f RetryFunc) { 46 | for i := 0; ; i++ { 47 | err := f(i) 48 | if err == nil { 49 | return 50 | } 51 | time.Sleep(d) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/go.sum: -------------------------------------------------------------------------------- 1 | github.com/nats-io/jwt v0.3.0 h1:xdnzwFETV++jNc4W1mw//qFyJGb2ABOombmZJQS4+Qo= 2 | github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= 3 | github.com/nats-io/nkeys v0.1.0 h1:qMd4+pRHgdr1nAClu+2h/2a5F2TmKcCzjCDazVgRoX4= 4 | github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= 5 | github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= 6 | github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= 7 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 8 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 9 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 10 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 11 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 12 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 14 | -------------------------------------------------------------------------------- /pusher-service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/kelseyhightower/envconfig" 10 | "github.com/tinrab/retry" 11 | 12 | "github.com/tinrab/meower/event" 13 | ) 14 | 15 | type Config struct { 16 | NatsAddress string `envconfig:"NATS_ADDRESS"` 17 | } 18 | 19 | func main() { 20 | var cfg Config 21 | err := envconfig.Process("", &cfg) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | 26 | // Connect to Nats 27 | hub := newHub() 28 | retry.ForeverSleep(2*time.Second, func(_ int) error { 29 | es, err := event.NewNats(fmt.Sprintf("nats://%s", cfg.NatsAddress)) 30 | if err != nil { 31 | log.Println(err) 32 | return err 33 | } 34 | 35 | // Push messages to clients 36 | err = es.OnMeowCreated(func(m event.MeowCreatedMessage) { 37 | log.Printf("Meow received: %v\n", m) 38 | hub.broadcast(newMeowCreatedMessage(m.ID, m.Body, m.CreatedAt), nil) 39 | }) 40 | if err != nil { 41 | log.Println(err) 42 | return err 43 | } 44 | 45 | event.SetEventStore(es) 46 | return nil 47 | }) 48 | defer event.Close() 49 | 50 | // Run WebSocket server 51 | go hub.run() 52 | http.HandleFunc("/pusher", hub.handleWebSocket) 53 | err = http.ListenAndServe(":8080", nil) 54 | if err != nil { 55 | log.Fatal(err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to pq 2 | 3 | `pq` has a backlog of pull requests, but contributions are still very 4 | much welcome. You can help with patch review, submitting bug reports, 5 | or adding new functionality. There is no formal style guide, but 6 | please conform to the style of existing code and general Go formatting 7 | conventions when submitting patches. 8 | 9 | ### Patch review 10 | 11 | Help review existing open pull requests by commenting on the code or 12 | proposed functionality. 13 | 14 | ### Bug reports 15 | 16 | We appreciate any bug reports, but especially ones with self-contained 17 | (doesn't depend on code outside of pq), minimal (can't be simplified 18 | further) test cases. It's especially helpful if you can submit a pull 19 | request with just the failing test case (you'll probably want to 20 | pattern it after the tests in 21 | [conn_test.go](https://github.com/lib/pq/blob/master/conn_test.go). 22 | 23 | ### New functionality 24 | 25 | There are a number of pending patches for new functionality, so 26 | additional feature patches will take a while to merge. Still, patches 27 | are generally reviewed based on usefulness and complexity in addition 28 | to time-in-queue, so if you have a knockout idea, take a shot. Feel 29 | free to open an issue discussion your proposed patch beforehand. 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/mask.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of 2 | // this source code is governed by a BSD-style license that can be found in the 3 | // LICENSE file. 4 | 5 | // +build !appengine 6 | 7 | package websocket 8 | 9 | import "unsafe" 10 | 11 | const wordSize = int(unsafe.Sizeof(uintptr(0))) 12 | 13 | func maskBytes(key [4]byte, pos int, b []byte) int { 14 | // Mask one byte at a time for small buffers. 15 | if len(b) < 2*wordSize { 16 | for i := range b { 17 | b[i] ^= key[pos&3] 18 | pos++ 19 | } 20 | return pos & 3 21 | } 22 | 23 | // Mask one byte at a time to word boundary. 24 | if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { 25 | n = wordSize - n 26 | for i := range b[:n] { 27 | b[i] ^= key[pos&3] 28 | pos++ 29 | } 30 | b = b[n:] 31 | } 32 | 33 | // Create aligned word size key. 34 | var k [wordSize]byte 35 | for i := range k { 36 | k[i] = key[(pos+i)&3] 37 | } 38 | kw := *(*uintptr)(unsafe.Pointer(&k)) 39 | 40 | // Mask one word at a time. 41 | n := (len(b) / wordSize) * wordSize 42 | for i := 0; i < n; i += wordSize { 43 | *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw 44 | } 45 | 46 | // Mask one byte at a time for remaining bytes. 47 | b = b[n:] 48 | for i := range b { 49 | b[i] ^= key[pos&3] 50 | pos++ 51 | } 52 | 53 | return pos & 3 54 | } 55 | -------------------------------------------------------------------------------- /meow-service/handlers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "html/template" 5 | "log" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/segmentio/ksuid" 10 | 11 | "github.com/tinrab/meower/db" 12 | "github.com/tinrab/meower/event" 13 | "github.com/tinrab/meower/schema" 14 | "github.com/tinrab/meower/util" 15 | ) 16 | 17 | func createMeowHandler(w http.ResponseWriter, r *http.Request) { 18 | type response struct { 19 | ID string `json:"id"` 20 | } 21 | 22 | ctx := r.Context() 23 | 24 | // Read parameters 25 | body := template.HTMLEscapeString(r.FormValue("body")) 26 | if len(body) < 1 || len(body) > 140 { 27 | util.ResponseError(w, http.StatusBadRequest, "Invalid body") 28 | return 29 | } 30 | 31 | // Create meow 32 | createdAt := time.Now().UTC() 33 | id, err := ksuid.NewRandomWithTime(createdAt) 34 | if err != nil { 35 | util.ResponseError(w, http.StatusInternalServerError, "Failed to create meow") 36 | return 37 | } 38 | meow := schema.Meow{ 39 | ID: id.String(), 40 | Body: body, 41 | CreatedAt: createdAt, 42 | } 43 | if err := db.InsertMeow(ctx, meow); err != nil { 44 | log.Println(err) 45 | util.ResponseError(w, http.StatusInternalServerError, "Failed to create meow") 46 | return 47 | } 48 | 49 | // Publish event 50 | if err := event.PublishMeowCreated(meow); err != nil { 51 | log.Println(err) 52 | } 53 | 54 | // Return new meow 55 | util.ResponseOk(w, response{ID: meow.ID}) 56 | } 57 | -------------------------------------------------------------------------------- /vendor/github.com/segmentio/ksuid/rand.go: -------------------------------------------------------------------------------- 1 | package ksuid 2 | 3 | import ( 4 | cryptoRand "crypto/rand" 5 | "encoding/binary" 6 | "io" 7 | "math/rand" 8 | ) 9 | 10 | // FastRander is an io.Reader that uses math/rand and is optimized for 11 | // generating 16 bytes KSUID payloads. It is intended to be used as a 12 | // performance improvements for programs that have no need for 13 | // cryptographically secure KSUIDs and are generating a lot of them. 14 | var FastRander = newRBG() 15 | 16 | func newRBG() io.Reader { 17 | r, err := newRandomBitsGenerator() 18 | if err != nil { 19 | panic(err) 20 | } 21 | return r 22 | } 23 | 24 | func newRandomBitsGenerator() (r io.Reader, err error) { 25 | var seed int64 26 | 27 | if seed, err = readCryptoRandomSeed(); err != nil { 28 | return 29 | } 30 | 31 | r = &randSourceReader{source: rand.NewSource(seed).(rand.Source64)} 32 | return 33 | } 34 | 35 | func readCryptoRandomSeed() (seed int64, err error) { 36 | var b [8]byte 37 | 38 | if _, err = io.ReadFull(cryptoRand.Reader, b[:]); err != nil { 39 | return 40 | } 41 | 42 | seed = int64(binary.LittleEndian.Uint64(b[:])) 43 | return 44 | } 45 | 46 | type randSourceReader struct { 47 | source rand.Source64 48 | } 49 | 50 | func (r *randSourceReader) Read(b []byte) (int, error) { 51 | // optimized for generating 16 bytes payloads 52 | binary.LittleEndian.PutUint64(b[:8], r.source.Uint64()) 53 | binary.LittleEndian.PutUint64(b[8:], r.source.Uint64()) 54 | return 16, nil 55 | } 56 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | meow: 5 | build: . 6 | command: meow-service 7 | depends_on: 8 | - postgres 9 | - nats 10 | ports: 11 | - "8080" 12 | environment: 13 | POSTGRES_DB: meower 14 | POSTGRES_USER: meower 15 | POSTGRES_PASSWORD: "123456" 16 | NATS_ADDRESS: nats:4222 17 | query: 18 | build: . 19 | command: query-service 20 | depends_on: 21 | - postgres 22 | - nats 23 | ports: 24 | - 8080 25 | environment: 26 | POSTGRES_DB: meower 27 | POSTGRES_USER: meower 28 | POSTGRES_PASSWORD: "123456" 29 | NATS_ADDRESS: nats:4222 30 | ELASTICSEARCH_ADDRESS: elasticsearch:9200 31 | pusher: 32 | build: . 33 | command: pusher-service 34 | depends_on: 35 | - nats 36 | ports: 37 | - 8080 38 | environment: 39 | NATS_ADDRESS: nats:4222 40 | postgres: 41 | build: ./postgres 42 | restart: always 43 | environment: 44 | POSTGRES_DB: meower 45 | POSTGRES_USER: meower 46 | POSTGRES_PASSWORD: "123456" 47 | nats: 48 | image: nats-streaming:0.17.0 49 | restart: always 50 | elasticsearch: 51 | image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0 52 | ports: 53 | - 9200:9200 54 | environment: 55 | - discovery.type=single-node 56 | nginx: 57 | build: ./nginx 58 | ports: 59 | - "8080:80" 60 | depends_on: 61 | - meow 62 | - query 63 | - pusher 64 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/encoders/builtin/gob_enc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package builtin 15 | 16 | import ( 17 | "bytes" 18 | "encoding/gob" 19 | ) 20 | 21 | // GobEncoder is a Go specific GOB Encoder implementation for EncodedConn. 22 | // This encoder will use the builtin encoding/gob to Marshal 23 | // and Unmarshal most types, including structs. 24 | type GobEncoder struct { 25 | // Empty 26 | } 27 | 28 | // FIXME(dlc) - This could probably be more efficient. 29 | 30 | // Encode 31 | func (ge *GobEncoder) Encode(subject string, v interface{}) ([]byte, error) { 32 | b := new(bytes.Buffer) 33 | enc := gob.NewEncoder(b) 34 | if err := enc.Encode(v); err != nil { 35 | return nil, err 36 | } 37 | return b.Bytes(), nil 38 | } 39 | 40 | // Decode 41 | func (ge *GobEncoder) Decode(subject string, data []byte, vPtr interface{}) (err error) { 42 | dec := gob.NewDecoder(bytes.NewBuffer(data)) 43 | err = dec.Decode(vPtr) 44 | return 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/client_clone_legacy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.8 6 | 7 | package websocket 8 | 9 | import "crypto/tls" 10 | 11 | // cloneTLSConfig clones all public fields except the fields 12 | // SessionTicketsDisabled and SessionTicketKey. This avoids copying the 13 | // sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a 14 | // config in active use. 15 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 16 | if cfg == nil { 17 | return &tls.Config{} 18 | } 19 | return &tls.Config{ 20 | Rand: cfg.Rand, 21 | Time: cfg.Time, 22 | Certificates: cfg.Certificates, 23 | NameToCertificate: cfg.NameToCertificate, 24 | GetCertificate: cfg.GetCertificate, 25 | RootCAs: cfg.RootCAs, 26 | NextProtos: cfg.NextProtos, 27 | ServerName: cfg.ServerName, 28 | ClientAuth: cfg.ClientAuth, 29 | ClientCAs: cfg.ClientCAs, 30 | InsecureSkipVerify: cfg.InsecureSkipVerify, 31 | CipherSuites: cfg.CipherSuites, 32 | PreferServerCipherSuites: cfg.PreferServerCipherSuites, 33 | ClientSessionCache: cfg.ClientSessionCache, 34 | MinVersion: cfg.MinVersion, 35 | MaxVersion: cfg.MaxVersion, 36 | CurvePreferences: cfg.CurvePreferences, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/esapi/esapi.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more agreements. 2 | // Elasticsearch B.V. licenses this file to you under the Apache 2.0 License. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | package esapi 6 | 7 | import ( 8 | "net/http" 9 | "strconv" 10 | "time" 11 | 12 | "github.com/elastic/go-elasticsearch/v7/internal/version" 13 | ) 14 | 15 | // Version returns the package version as a string. 16 | // 17 | const Version = version.Client 18 | 19 | // Transport defines the interface for an API client. 20 | // 21 | type Transport interface { 22 | Perform(*http.Request) (*http.Response, error) 23 | } 24 | 25 | // BoolPtr returns a pointer to v. 26 | // 27 | // It is used as a convenience function for converting a bool value 28 | // into a pointer when passing the value to a function or struct field 29 | // which expects a pointer. 30 | // 31 | func BoolPtr(v bool) *bool { return &v } 32 | 33 | // IntPtr returns a pointer to v. 34 | // 35 | // It is used as a convenience function for converting an int value 36 | // into a pointer when passing the value to a function or struct field 37 | // which expects a pointer. 38 | // 39 | func IntPtr(v int) *int { return &v } 40 | 41 | // formatDuration converts duration to a string in the format 42 | // accepted by Elasticsearch. 43 | // 44 | func formatDuration(d time.Duration) string { 45 | if d < time.Millisecond { 46 | return strconv.FormatInt(int64(d), 10) + "nanos" 47 | } 48 | return strconv.FormatInt(int64(d)/int64(time.Millisecond), 10) + "ms" 49 | } 50 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /db/postgres.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "log" 7 | 8 | _ "github.com/lib/pq" 9 | 10 | "github.com/tinrab/meower/schema" 11 | ) 12 | 13 | type PostgresRepository struct { 14 | db *sql.DB 15 | } 16 | 17 | func NewPostgres(url string) (*PostgresRepository, error) { 18 | db, err := sql.Open("postgres", url) 19 | if err != nil { 20 | return nil, err 21 | } 22 | err = db.Ping() 23 | if err != nil { 24 | return nil, err 25 | } 26 | return &PostgresRepository{ 27 | db, 28 | }, nil 29 | } 30 | 31 | func (r *PostgresRepository) Close() { 32 | if err := r.db.Close(); err != nil { 33 | log.Fatal(err) 34 | } 35 | } 36 | 37 | func (r *PostgresRepository) InsertMeow(ctx context.Context, meow schema.Meow) error { 38 | _, err := r.db.Exec("INSERT INTO meows(id, body, created_at) VALUES($1, $2, $3)", meow.ID, meow.Body, meow.CreatedAt) 39 | return err 40 | } 41 | 42 | func (r *PostgresRepository) ListMeows(ctx context.Context, skip uint64, take uint64) ([]schema.Meow, error) { 43 | rows, err := r.db.Query("SELECT * FROM meows ORDER BY id DESC OFFSET $1 LIMIT $2", skip, take) 44 | if err != nil { 45 | return nil, err 46 | } 47 | defer func() { 48 | err = rows.Close() 49 | if err != nil { 50 | log.Fatal(err) 51 | } 52 | }() 53 | 54 | // Parse all rows into an array of Meows 55 | var meows []schema.Meow 56 | for rows.Next() { 57 | meow := schema.Meow{} 58 | if err = rows.Scan(&meow.ID, &meow.Body, &meow.CreatedAt); err == nil { 59 | meows = append(meows, meow) 60 | } 61 | } 62 | if err = rows.Err(); err != nil { 63 | return nil, err 64 | } 65 | 66 | return meows, nil 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/timer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nats 15 | 16 | import ( 17 | "sync" 18 | "time" 19 | ) 20 | 21 | // global pool of *time.Timer's. can be used by multiple goroutines concurrently. 22 | var globalTimerPool timerPool 23 | 24 | // timerPool provides GC-able pooling of *time.Timer's. 25 | // can be used by multiple goroutines concurrently. 26 | type timerPool struct { 27 | p sync.Pool 28 | } 29 | 30 | // Get returns a timer that completes after the given duration. 31 | func (tp *timerPool) Get(d time.Duration) *time.Timer { 32 | if t, _ := tp.p.Get().(*time.Timer); t != nil { 33 | t.Reset(d) 34 | return t 35 | } 36 | 37 | return time.NewTimer(d) 38 | } 39 | 40 | // Put pools the given timer. 41 | // 42 | // There is no need to call t.Stop() before calling Put. 43 | // 44 | // Put will try to stop the timer before pooling. If the 45 | // given timer already expired, Put will read the unreceived 46 | // value if there is one. 47 | func (tp *timerPool) Put(t *time.Timer) { 48 | if !t.Stop() { 49 | select { 50 | case <-t.C: 51 | default: 52 | } 53 | } 54 | 55 | tp.p.Put(t) 56 | } 57 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "encoding/json" 9 | "io" 10 | ) 11 | 12 | // WriteJSON writes the JSON encoding of v as a message. 13 | // 14 | // Deprecated: Use c.WriteJSON instead. 15 | func WriteJSON(c *Conn, v interface{}) error { 16 | return c.WriteJSON(v) 17 | } 18 | 19 | // WriteJSON writes the JSON encoding of v as a message. 20 | // 21 | // See the documentation for encoding/json Marshal for details about the 22 | // conversion of Go values to JSON. 23 | func (c *Conn) WriteJSON(v interface{}) error { 24 | w, err := c.NextWriter(TextMessage) 25 | if err != nil { 26 | return err 27 | } 28 | err1 := json.NewEncoder(w).Encode(v) 29 | err2 := w.Close() 30 | if err1 != nil { 31 | return err1 32 | } 33 | return err2 34 | } 35 | 36 | // ReadJSON reads the next JSON-encoded message from the connection and stores 37 | // it in the value pointed to by v. 38 | // 39 | // Deprecated: Use c.ReadJSON instead. 40 | func ReadJSON(c *Conn, v interface{}) error { 41 | return c.ReadJSON(v) 42 | } 43 | 44 | // ReadJSON reads the next JSON-encoded message from the connection and stores 45 | // it in the value pointed to by v. 46 | // 47 | // See the documentation for the encoding/json Unmarshal function for details 48 | // about the conversion of JSON to a Go value. 49 | func (c *Conn) ReadJSON(v interface{}) error { 50 | _, r, err := c.NextReader() 51 | if err != nil { 52 | return err 53 | } 54 | err = json.NewDecoder(r).Decode(v) 55 | if err == io.EOF { 56 | // One value is expected in the message. 57 | err = io.ErrUnexpectedEOF 58 | } 59 | return err 60 | } 61 | -------------------------------------------------------------------------------- /vendor/github.com/segmentio/ksuid/sequence.go: -------------------------------------------------------------------------------- 1 | package ksuid 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | "math" 7 | ) 8 | 9 | // Sequence is a KSUID generator which produces a sequence of ordered KSUIDs 10 | // from a seed. 11 | // 12 | // Up to 65536 KSUIDs can be generated by for a single seed. 13 | // 14 | // A typical usage of a Sequence looks like this: 15 | // 16 | // seq := ksuid.Sequence{ 17 | // Seed: ksuid.New(), 18 | // } 19 | // id, err := seq.Next() 20 | // 21 | // Sequence values are not safe to use concurrently from multiple goroutines. 22 | type Sequence struct { 23 | // The seed is used as base for the KSUID generator, all generated KSUIDs 24 | // share the same leading 18 bytes of the seed. 25 | Seed KSUID 26 | count uint32 // uint32 for overflow, only 2 bytes are used 27 | } 28 | 29 | // Next produces the next KSUID in the sequence, or returns an error if the 30 | // sequence has been exhausted. 31 | func (seq *Sequence) Next() (KSUID, error) { 32 | id := seq.Seed // copy 33 | count := seq.count 34 | if count > math.MaxUint16 { 35 | return Nil, errors.New("too many IDs were generated") 36 | } 37 | seq.count++ 38 | return withSequenceNumber(id, uint16(count)), nil 39 | } 40 | 41 | // Bounds returns the inclusive min and max bounds of the KSUIDs that may be 42 | // generated by the sequence. If all ids have been generated already then the 43 | // returned min value is equal to the max. 44 | func (seq *Sequence) Bounds() (min KSUID, max KSUID) { 45 | count := seq.count 46 | if count > math.MaxUint16 { 47 | count = math.MaxUint16 48 | } 49 | return withSequenceNumber(seq.Seed, uint16(count)), withSequenceNumber(seq.Seed, math.MaxUint16) 50 | } 51 | 52 | func withSequenceNumber(id KSUID, n uint16) KSUID { 53 | binary.BigEndian.PutUint16(id[len(id)-2:], n) 54 | return id 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package elasticsearch provides a Go client for Elasticsearch. 3 | 4 | Create the client with the NewDefaultClient function: 5 | 6 | elasticsearch.NewDefaultClient() 7 | 8 | The ELASTICSEARCH_URL environment variable is used instead of the default URL, when set. 9 | Use a comma to separate multiple URLs. 10 | 11 | To configure the client, pass a Config object to the NewClient function: 12 | 13 | cfg := elasticsearch.Config{ 14 | Addresses: []string{ 15 | "http://localhost:9200", 16 | "http://localhost:9201", 17 | }, 18 | Username: "foo", 19 | Password: "bar", 20 | Transport: &http.Transport{ 21 | MaxIdleConnsPerHost: 10, 22 | ResponseHeaderTimeout: time.Second, 23 | DialContext: (&net.Dialer{Timeout: time.Second}).DialContext, 24 | TLSClientConfig: &tls.Config{ 25 | MinVersion: tls.VersionTLS11, 26 | }, 27 | }, 28 | } 29 | 30 | elasticsearch.NewClient(cfg) 31 | 32 | When using the Elastic Service (https://elastic.co/cloud), you can use CloudID instead of Addresses. 33 | When either Addresses or CloudID is set, the ELASTICSEARCH_URL environment variable is ignored. 34 | 35 | See the elasticsearch_integration_test.go file and the _examples folder for more information. 36 | 37 | Call the Elasticsearch APIs by invoking the corresponding methods on the client: 38 | 39 | res, err := es.Info() 40 | if err != nil { 41 | log.Fatalf("Error getting response: %s", err) 42 | } 43 | 44 | log.Println(res) 45 | 46 | See the github.com/elastic/go-elasticsearch/esapi package for more information about using the API. 47 | 48 | See the github.com/elastic/go-elasticsearch/estransport package for more information about configuring the transport. 49 | */ 50 | package elasticsearch 51 | -------------------------------------------------------------------------------- /meow-service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/gorilla/mux" 10 | "github.com/kelseyhightower/envconfig" 11 | "github.com/tinrab/retry" 12 | 13 | "github.com/tinrab/meower/db" 14 | "github.com/tinrab/meower/event" 15 | ) 16 | 17 | type Config struct { 18 | PostgresDB string `envconfig:"POSTGRES_DB"` 19 | PostgresUser string `envconfig:"POSTGRES_USER"` 20 | PostgresPassword string `envconfig:"POSTGRES_PASSWORD"` 21 | NatsAddress string `envconfig:"NATS_ADDRESS"` 22 | } 23 | 24 | func newRouter() (router *mux.Router) { 25 | router = mux.NewRouter() 26 | router.HandleFunc("/meows", createMeowHandler). 27 | Methods(http.MethodPost). 28 | Queries("body", "{body}") 29 | router.Use(mux.CORSMethodMiddleware(router)) 30 | return 31 | } 32 | 33 | func main() { 34 | var cfg Config 35 | err := envconfig.Process("", &cfg) 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | 40 | // Connect to PostgreSQL 41 | retry.ForeverSleep(2*time.Second, func(attempt int) error { 42 | addr := fmt.Sprintf("postgres://%s:%s@postgres/%s?sslmode=disable", cfg.PostgresUser, cfg.PostgresPassword, cfg.PostgresDB) 43 | repo, err := db.NewPostgres(addr) 44 | if err != nil { 45 | log.Println(err) 46 | return err 47 | } 48 | db.SetRepository(repo) 49 | return nil 50 | }) 51 | defer db.Close() 52 | 53 | // Connect to Nats 54 | retry.ForeverSleep(2*time.Second, func(_ int) error { 55 | es, err := event.NewNats(fmt.Sprintf("nats://%s", cfg.NatsAddress)) 56 | if err != nil { 57 | log.Println(err) 58 | return err 59 | } 60 | event.SetEventStore(es) 61 | return nil 62 | }) 63 | defer event.Close() 64 | 65 | // Run HTTP server 66 | router := newRouter() 67 | if err := http.ListenAndServe(":8080", router); err != nil { 68 | log.Fatal(err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/encoders/builtin/json_enc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package builtin 15 | 16 | import ( 17 | "encoding/json" 18 | "strings" 19 | ) 20 | 21 | // JsonEncoder is a JSON Encoder implementation for EncodedConn. 22 | // This encoder will use the builtin encoding/json to Marshal 23 | // and Unmarshal most types, including structs. 24 | type JsonEncoder struct { 25 | // Empty 26 | } 27 | 28 | // Encode 29 | func (je *JsonEncoder) Encode(subject string, v interface{}) ([]byte, error) { 30 | b, err := json.Marshal(v) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return b, nil 35 | } 36 | 37 | // Decode 38 | func (je *JsonEncoder) Decode(subject string, data []byte, vPtr interface{}) (err error) { 39 | switch arg := vPtr.(type) { 40 | case *string: 41 | // If they want a string and it is a JSON string, strip quotes 42 | // This allows someone to send a struct but receive as a plain string 43 | // This cast should be efficient for Go 1.3 and beyond. 44 | str := string(data) 45 | if strings.HasPrefix(str, `"`) && strings.HasSuffix(str, `"`) { 46 | *arg = str[1 : len(str)-1] 47 | } else { 48 | *arg = str 49 | } 50 | case *[]byte: 51 | *arg = data 52 | default: 53 | err = json.Unmarshal(data, arg) 54 | } 55 | return 56 | } 57 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/url.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | nurl "net/url" 7 | "sort" 8 | "strings" 9 | ) 10 | 11 | // ParseURL no longer needs to be used by clients of this library since supplying a URL as a 12 | // connection string to sql.Open() is now supported: 13 | // 14 | // sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full") 15 | // 16 | // It remains exported here for backwards-compatibility. 17 | // 18 | // ParseURL converts a url to a connection string for driver.Open. 19 | // Example: 20 | // 21 | // "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full" 22 | // 23 | // converts to: 24 | // 25 | // "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full" 26 | // 27 | // A minimal example: 28 | // 29 | // "postgres://" 30 | // 31 | // This will be blank, causing driver.Open to use all of the defaults 32 | func ParseURL(url string) (string, error) { 33 | u, err := nurl.Parse(url) 34 | if err != nil { 35 | return "", err 36 | } 37 | 38 | if u.Scheme != "postgres" && u.Scheme != "postgresql" { 39 | return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) 40 | } 41 | 42 | var kvs []string 43 | escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`) 44 | accrue := func(k, v string) { 45 | if v != "" { 46 | kvs = append(kvs, k+"="+escaper.Replace(v)) 47 | } 48 | } 49 | 50 | if u.User != nil { 51 | v := u.User.Username() 52 | accrue("user", v) 53 | 54 | v, _ = u.User.Password() 55 | accrue("password", v) 56 | } 57 | 58 | if host, port, err := net.SplitHostPort(u.Host); err != nil { 59 | accrue("host", u.Host) 60 | } else { 61 | accrue("host", host) 62 | accrue("port", port) 63 | } 64 | 65 | if u.Path != "" { 66 | accrue("dbname", u.Path[1:]) 67 | } 68 | 69 | q := u.Query() 70 | for k := range q { 71 | accrue(k, q.Get(k)) 72 | } 73 | 74 | sort.Strings(kvs) // Makes testing easier (not a performance concern) 75 | return strings.Join(kvs, " "), nil 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nuid/README.md: -------------------------------------------------------------------------------- 1 | # NUID 2 | 3 | [![License Apache 2](https://img.shields.io/badge/License-Apache2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) 4 | [![ReportCard](http://goreportcard.com/badge/nats-io/nuid)](http://goreportcard.com/report/nats-io/nuid) 5 | [![Build Status](https://travis-ci.org/nats-io/nuid.svg?branch=master)](http://travis-ci.org/nats-io/nuid) 6 | [![Release](https://img.shields.io/badge/release-v1.0.1-1eb0fc.svg)](https://github.com/nats-io/nuid/releases/tag/v1.0.1) 7 | [![GoDoc](http://godoc.org/github.com/nats-io/nuid?status.png)](http://godoc.org/github.com/nats-io/nuid) 8 | [![Coverage Status](https://coveralls.io/repos/github/nats-io/nuid/badge.svg?branch=master)](https://coveralls.io/github/nats-io/nuid?branch=master) 9 | 10 | A highly performant unique identifier generator. 11 | 12 | ## Installation 13 | 14 | Use the `go` command: 15 | 16 | $ go get github.com/nats-io/nuid 17 | 18 | ## Basic Usage 19 | ```go 20 | 21 | // Utilize the global locked instance 22 | nuid := nuid.Next() 23 | 24 | // Create an instance, these are not locked. 25 | n := nuid.New() 26 | nuid = n.Next() 27 | 28 | // Generate a new crypto/rand seeded prefix. 29 | // Generally not needed, happens automatically. 30 | n.RandomizePrefix() 31 | ``` 32 | 33 | ## Performance 34 | NUID needs to be very fast to generate and be truly unique, all while being entropy pool friendly. 35 | NUID uses 12 bytes of crypto generated data (entropy draining), and 10 bytes of pseudo-random 36 | sequential data that increments with a pseudo-random increment. 37 | 38 | Total length of a NUID string is 22 bytes of base 62 ascii text, so 62^22 or 39 | 2707803647802660400290261537185326956544 possibilities. 40 | 41 | NUID can generate identifiers as fast as 60ns, or ~16 million per second. There is an associated 42 | benchmark you can use to test performance on your own hardware. 43 | 44 | ## License 45 | 46 | Unless otherwise noted, the NATS source files are distributed 47 | under the Apache Version 2.0 license found in the LICENSE file. 48 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/buf.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | 7 | "github.com/lib/pq/oid" 8 | ) 9 | 10 | type readBuf []byte 11 | 12 | func (b *readBuf) int32() (n int) { 13 | n = int(int32(binary.BigEndian.Uint32(*b))) 14 | *b = (*b)[4:] 15 | return 16 | } 17 | 18 | func (b *readBuf) oid() (n oid.Oid) { 19 | n = oid.Oid(binary.BigEndian.Uint32(*b)) 20 | *b = (*b)[4:] 21 | return 22 | } 23 | 24 | // N.B: this is actually an unsigned 16-bit integer, unlike int32 25 | func (b *readBuf) int16() (n int) { 26 | n = int(binary.BigEndian.Uint16(*b)) 27 | *b = (*b)[2:] 28 | return 29 | } 30 | 31 | func (b *readBuf) string() string { 32 | i := bytes.IndexByte(*b, 0) 33 | if i < 0 { 34 | errorf("invalid message format; expected string terminator") 35 | } 36 | s := (*b)[:i] 37 | *b = (*b)[i+1:] 38 | return string(s) 39 | } 40 | 41 | func (b *readBuf) next(n int) (v []byte) { 42 | v = (*b)[:n] 43 | *b = (*b)[n:] 44 | return 45 | } 46 | 47 | func (b *readBuf) byte() byte { 48 | return b.next(1)[0] 49 | } 50 | 51 | type writeBuf struct { 52 | buf []byte 53 | pos int 54 | } 55 | 56 | func (b *writeBuf) int32(n int) { 57 | x := make([]byte, 4) 58 | binary.BigEndian.PutUint32(x, uint32(n)) 59 | b.buf = append(b.buf, x...) 60 | } 61 | 62 | func (b *writeBuf) int16(n int) { 63 | x := make([]byte, 2) 64 | binary.BigEndian.PutUint16(x, uint16(n)) 65 | b.buf = append(b.buf, x...) 66 | } 67 | 68 | func (b *writeBuf) string(s string) { 69 | b.buf = append(append(b.buf, s...), '\000') 70 | } 71 | 72 | func (b *writeBuf) byte(c byte) { 73 | b.buf = append(b.buf, c) 74 | } 75 | 76 | func (b *writeBuf) bytes(v []byte) { 77 | b.buf = append(b.buf, v...) 78 | } 79 | 80 | func (b *writeBuf) wrap() []byte { 81 | p := b.buf[b.pos:] 82 | binary.BigEndian.PutUint32(p, uint32(len(p))) 83 | return b.buf 84 | } 85 | 86 | func (b *writeBuf) next(c byte) { 87 | p := b.buf[b.pos:] 88 | binary.BigEndian.PutUint32(p, uint32(len(p))) 89 | b.pos = len(b.buf) + 1 90 | b.buf = append(b.buf, c, 0, 0, 0, 0) 91 | } 92 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/README.md: -------------------------------------------------------------------------------- 1 | # JWT 2 | A [JWT](https://jwt.io/) implementation that uses [nkeys](https://github.com/nats-io/nkeys) to digitally sign JWT tokens. 3 | Nkeys use [Ed25519](https://ed25519.cr.yp.to/) to provide authentication of JWT claims. 4 | 5 | 6 | [![License Apache 2](https://img.shields.io/badge/License-Apache2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) 7 | [![ReportCard](http://goreportcard.com/badge/nats-io/jwt)](http://goreportcard.com/report/nats-io/jwt) 8 | [![Build Status](https://travis-ci.org/nats-io/jwt.svg?branch=master)](http://travis-ci.org/nats-io/jwt) 9 | [![GoDoc](http://godoc.org/github.com/nats-io/jwt?status.png)](http://godoc.org/github.com/nats-io/jwt) 10 | [![Coverage Status](https://coveralls.io/repos/github/nats-io/jwt/badge.svg?branch=master&t=NmEFup)](https://coveralls.io/github/nats-io/jwt?branch=master) 11 | 12 | ```go 13 | // Need a private key to sign the claim, nkeys makes it easy to create 14 | kp, err := nkeys.CreateAccount() 15 | if err != nil { 16 | t.Fatal("unable to create account key", err) 17 | } 18 | 19 | pk, err := kp.PublicKey() 20 | if err != nil { 21 | t.Fatal("error getting public key", err) 22 | } 23 | 24 | // create a new claim 25 | claims := NewAccountClaims(pk) 26 | claims.Expires = time.Now().Add(time.Duration(time.Hour)).Unix() 27 | 28 | 29 | // add details by modifying claims.Account 30 | 31 | // serialize the claim to a JWT token 32 | token, err := claims.Encode(kp) 33 | if err != nil { 34 | t.Fatal("error encoding token", err) 35 | } 36 | 37 | // on the receiving side, decode the token 38 | c, err := DecodeAccountClaims(token) 39 | if err != nil { 40 | t.Fatal(err) 41 | } 42 | 43 | // if the token was decoded, it means that it 44 | // validated and it wasn't tampered. the remaining and 45 | // required test is to insure the issuer is trusted 46 | pk, err := kp.PublicKey() 47 | if err != nil { 48 | t.Fatalf("unable to read public key: %v", err) 49 | } 50 | 51 | if c.Issuer != pk { 52 | t.Fatalf("the public key is not trusted") 53 | } 54 | ``` -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/estransport/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package estransport provides the transport layer for the Elasticsearch client. 3 | 4 | It is automatically included in the client provided by the github.com/elastic/go-elasticsearch package 5 | and is not intended for direct use: to configure the client, use the elasticsearch.Config struct. 6 | 7 | The default HTTP transport of the client is http.Transport; use the Transport option to customize it; 8 | see the _examples/coniguration.go and _examples/customization.go files in this repository for information. 9 | 10 | The package will automatically retry requests on network-related errors, and on specific 11 | response status codes (by default 502, 503, 504). Use the RetryOnStatus option to customize the list. 12 | The transport will not retry a timeout network error, unless enabled by setting EnableRetryOnTimeout to true. 13 | 14 | Use the MaxRetries option to configure the number of retries, and set DisableRetry to true 15 | to disable the retry behaviour altogether. 16 | 17 | By default, the retry will be performed without any delay; to configure a backoff interval, 18 | implement the RetryBackoff option function; see an example in the package unit tests for information. 19 | 20 | When multiple addresses are passed in configuration, the package will use them in a round-robin fashion, 21 | and will keep track of live and dead nodes. The status of dead nodes is checked periodically. 22 | 23 | To customize the node selection behaviour, provide a Selector implementation in the configuration. 24 | To replace the connection pool entirely, provide a custom ConnectionPool implementation via 25 | the ConnectionPoolFunc option. 26 | 27 | The package defines the Logger interface for logging information about request and response. 28 | It comes with several bundled loggers for logging in text and JSON. 29 | 30 | Use the EnableDebugLogger option to enable the debugging logger for connection management. 31 | 32 | Use the EnableMetrics option to enable metric collection and export. 33 | */ 34 | package estransport 35 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/esapi/esapi.response.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more agreements. 2 | // Elasticsearch B.V. licenses this file to you under the Apache 2.0 License. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | package esapi 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "io" 11 | "io/ioutil" 12 | "net/http" 13 | "strconv" 14 | "strings" 15 | ) 16 | 17 | // Response represents the API response. 18 | // 19 | type Response struct { 20 | StatusCode int 21 | Header http.Header 22 | Body io.ReadCloser 23 | } 24 | 25 | // String returns the response as a string. 26 | // 27 | // The intended usage is for testing or debugging only. 28 | // 29 | func (r *Response) String() string { 30 | var ( 31 | out = new(bytes.Buffer) 32 | b1 = bytes.NewBuffer([]byte{}) 33 | b2 = bytes.NewBuffer([]byte{}) 34 | tr io.Reader 35 | ) 36 | 37 | if r != nil && r.Body != nil { 38 | tr = io.TeeReader(r.Body, b1) 39 | defer r.Body.Close() 40 | 41 | if _, err := io.Copy(b2, tr); err != nil { 42 | out.WriteString(fmt.Sprintf("", err)) 43 | return out.String() 44 | } 45 | defer func() { r.Body = ioutil.NopCloser(b1) }() 46 | } 47 | 48 | if r != nil { 49 | out.WriteString(fmt.Sprintf("[%d %s]", r.StatusCode, http.StatusText(r.StatusCode))) 50 | if r.StatusCode > 0 { 51 | out.WriteRune(' ') 52 | } 53 | } else { 54 | out.WriteString("[0 ]") 55 | } 56 | 57 | if r != nil && r.Body != nil { 58 | out.ReadFrom(b2) // errcheck exclude (*bytes.Buffer).ReadFrom 59 | } 60 | 61 | return out.String() 62 | } 63 | 64 | // Status returns the response status as a string. 65 | // 66 | func (r *Response) Status() string { 67 | var b strings.Builder 68 | if r != nil { 69 | b.WriteString(strconv.Itoa(r.StatusCode)) 70 | b.WriteString(" ") 71 | b.WriteString(http.StatusText(r.StatusCode)) 72 | } 73 | return b.String() 74 | } 75 | 76 | // IsError returns true when the response status indicates failure. 77 | // 78 | func (r *Response) IsError() bool { 79 | return r.StatusCode > 299 80 | } 81 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/header.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 The NATS Authors 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package jwt 17 | 18 | import ( 19 | "encoding/json" 20 | "fmt" 21 | "strings" 22 | ) 23 | 24 | const ( 25 | // Version is semantic version. 26 | Version = "0.3.0" 27 | 28 | // TokenTypeJwt is the JWT token type supported JWT tokens 29 | // encoded and decoded by this library 30 | TokenTypeJwt = "jwt" 31 | 32 | // AlgorithmNkey is the algorithm supported by JWT tokens 33 | // encoded and decoded by this library 34 | AlgorithmNkey = "ed25519" 35 | ) 36 | 37 | // Header is a JWT Jose Header 38 | type Header struct { 39 | Type string `json:"typ"` 40 | Algorithm string `json:"alg"` 41 | } 42 | 43 | // Parses a header JWT token 44 | func parseHeaders(s string) (*Header, error) { 45 | h, err := decodeString(s) 46 | if err != nil { 47 | return nil, err 48 | } 49 | header := Header{} 50 | if err := json.Unmarshal(h, &header); err != nil { 51 | return nil, err 52 | } 53 | 54 | if err := header.Valid(); err != nil { 55 | return nil, err 56 | } 57 | return &header, nil 58 | } 59 | 60 | // Valid validates the Header. It returns nil if the Header is 61 | // a JWT header, and the algorithm used is the NKEY algorithm. 62 | func (h *Header) Valid() error { 63 | if TokenTypeJwt != strings.ToLower(h.Type) { 64 | return fmt.Errorf("not supported type %q", h.Type) 65 | } 66 | 67 | if AlgorithmNkey != strings.ToLower(h.Algorithm) { 68 | return fmt.Errorf("unexpected %q algorithm", h.Algorithm) 69 | } 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/util/tls_go17.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build go1.7,!go1.8 15 | 16 | package util 17 | 18 | import ( 19 | "crypto/tls" 20 | ) 21 | 22 | // CloneTLSConfig returns a copy of c. Only the exported fields are copied. 23 | // This is temporary, until this is provided by the language. 24 | // https://go-review.googlesource.com/#/c/28075/ 25 | func CloneTLSConfig(c *tls.Config) *tls.Config { 26 | return &tls.Config{ 27 | Rand: c.Rand, 28 | Time: c.Time, 29 | Certificates: c.Certificates, 30 | NameToCertificate: c.NameToCertificate, 31 | GetCertificate: c.GetCertificate, 32 | RootCAs: c.RootCAs, 33 | NextProtos: c.NextProtos, 34 | ServerName: c.ServerName, 35 | ClientAuth: c.ClientAuth, 36 | ClientCAs: c.ClientCAs, 37 | InsecureSkipVerify: c.InsecureSkipVerify, 38 | CipherSuites: c.CipherSuites, 39 | PreferServerCipherSuites: c.PreferServerCipherSuites, 40 | SessionTicketsDisabled: c.SessionTicketsDisabled, 41 | SessionTicketKey: c.SessionTicketKey, 42 | ClientSessionCache: c.ClientSessionCache, 43 | MinVersion: c.MinVersion, 44 | MaxVersion: c.MaxVersion, 45 | CurvePreferences: c.CurvePreferences, 46 | DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, 47 | Renegotiation: c.Renegotiation, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/public.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nkeys 15 | 16 | import ( 17 | "crypto/rand" 18 | "io" 19 | 20 | "golang.org/x/crypto/ed25519" 21 | ) 22 | 23 | // A KeyPair from a public key capable of verifying only. 24 | type pub struct { 25 | pre PrefixByte 26 | pub ed25519.PublicKey 27 | } 28 | 29 | // PublicKey will return the encoded public key associated with the KeyPair. 30 | // All KeyPairs have a public key. 31 | func (p *pub) PublicKey() (string, error) { 32 | pk, err := Encode(p.pre, p.pub) 33 | if err != nil { 34 | return "", err 35 | } 36 | return string(pk), nil 37 | } 38 | 39 | // Seed will return an error since this is not available for public key only KeyPairs. 40 | func (p *pub) Seed() ([]byte, error) { 41 | return nil, ErrPublicKeyOnly 42 | } 43 | 44 | // PrivateKey will return an error since this is not available for public key only KeyPairs. 45 | func (p *pub) PrivateKey() ([]byte, error) { 46 | return nil, ErrPublicKeyOnly 47 | } 48 | 49 | // Sign will return an error since this is not available for public key only KeyPairs. 50 | func (p *pub) Sign(input []byte) ([]byte, error) { 51 | return nil, ErrCannotSign 52 | } 53 | 54 | // Verify will verify the input against a signature utilizing the public key. 55 | func (p *pub) Verify(input []byte, sig []byte) error { 56 | if !ed25519.Verify(p.pub, input, sig) { 57 | return ErrInvalidSignature 58 | } 59 | return nil 60 | } 61 | 62 | // Wipe will randomize the public key and erase the pre byte. 63 | func (p *pub) Wipe() { 64 | p.pre = '0' 65 | io.ReadFull(rand.Reader, p.pub) 66 | } 67 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/proxy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "bufio" 9 | "encoding/base64" 10 | "errors" 11 | "net" 12 | "net/http" 13 | "net/url" 14 | "strings" 15 | ) 16 | 17 | type netDialerFunc func(network, addr string) (net.Conn, error) 18 | 19 | func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { 20 | return fn(network, addr) 21 | } 22 | 23 | func init() { 24 | proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { 25 | return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil 26 | }) 27 | } 28 | 29 | type httpProxyDialer struct { 30 | proxyURL *url.URL 31 | forwardDial func(network, addr string) (net.Conn, error) 32 | } 33 | 34 | func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { 35 | hostPort, _ := hostPortNoPort(hpd.proxyURL) 36 | conn, err := hpd.forwardDial(network, hostPort) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | connectHeader := make(http.Header) 42 | if user := hpd.proxyURL.User; user != nil { 43 | proxyUser := user.Username() 44 | if proxyPassword, passwordSet := user.Password(); passwordSet { 45 | credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) 46 | connectHeader.Set("Proxy-Authorization", "Basic "+credential) 47 | } 48 | } 49 | 50 | connectReq := &http.Request{ 51 | Method: "CONNECT", 52 | URL: &url.URL{Opaque: addr}, 53 | Host: addr, 54 | Header: connectHeader, 55 | } 56 | 57 | if err := connectReq.Write(conn); err != nil { 58 | conn.Close() 59 | return nil, err 60 | } 61 | 62 | // Read response. It's OK to use and discard buffered reader here becaue 63 | // the remote server does not speak until spoken to. 64 | br := bufio.NewReader(conn) 65 | resp, err := http.ReadResponse(br, connectReq) 66 | if err != nil { 67 | conn.Close() 68 | return nil, err 69 | } 70 | 71 | if resp.StatusCode != 200 { 72 | conn.Close() 73 | f := strings.SplitN(resp.Status, " ", 2) 74 | return nil, errors.New(f[1]) 75 | } 76 | return conn, nil 77 | } 78 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/genericlaims.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The NATS Authors 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package jwt 17 | 18 | import "github.com/nats-io/nkeys" 19 | 20 | // GenericClaims can be used to read a JWT as a map for any non-generic fields 21 | type GenericClaims struct { 22 | ClaimsData 23 | Data map[string]interface{} `json:"nats,omitempty"` 24 | } 25 | 26 | // NewGenericClaims creates a map-based Claims 27 | func NewGenericClaims(subject string) *GenericClaims { 28 | if subject == "" { 29 | return nil 30 | } 31 | c := GenericClaims{} 32 | c.Subject = subject 33 | c.Data = make(map[string]interface{}) 34 | return &c 35 | } 36 | 37 | // DecodeGeneric takes a JWT string and decodes it into a ClaimsData and map 38 | func DecodeGeneric(token string) (*GenericClaims, error) { 39 | v := GenericClaims{} 40 | if err := Decode(token, &v); err != nil { 41 | return nil, err 42 | } 43 | return &v, nil 44 | } 45 | 46 | // Claims returns the standard part of the generic claim 47 | func (gc *GenericClaims) Claims() *ClaimsData { 48 | return &gc.ClaimsData 49 | } 50 | 51 | // Payload returns the custom part of the claims data 52 | func (gc *GenericClaims) Payload() interface{} { 53 | return &gc.Data 54 | } 55 | 56 | // Encode takes a generic claims and creates a JWT string 57 | func (gc *GenericClaims) Encode(pair nkeys.KeyPair) (string, error) { 58 | return gc.ClaimsData.Encode(pair, gc) 59 | } 60 | 61 | // Validate checks the generic part of the claims data 62 | func (gc *GenericClaims) Validate(vr *ValidationResults) { 63 | gc.ClaimsData.Validate(vr) 64 | } 65 | 66 | func (gc *GenericClaims) String() string { 67 | return gc.ClaimsData.String(gc) 68 | } 69 | 70 | // ExpectedPrefixes returns the types allowed to encode a generic JWT, which is nil for all 71 | func (gc *GenericClaims) ExpectedPrefixes() []nkeys.PrefixByte { 72 | return nil 73 | } 74 | -------------------------------------------------------------------------------- /frontend/src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | import axios from 'axios'; 4 | import VueNativeSock from 'vue-native-websocket'; 5 | 6 | const BACKEND_URL = 'http://localhost:8080'; 7 | const PUSHER_URL = 'ws://localhost:8080/pusher'; 8 | 9 | const SET_MEOWS = 'SET_MEOWS'; 10 | const CREATE_MEOW = 'CREATE_MEOW'; 11 | const SEARCH_SUCCESS = 'SEARCH_SUCCESS'; 12 | const SEARCH_ERROR = 'SEARCH_ERROR'; 13 | 14 | const MESSAGE_MEOW_CREATED = 1; 15 | 16 | Vue.use(Vuex); 17 | 18 | const store = new Vuex.Store({ 19 | state: { 20 | meows: [], 21 | searchResults: [], 22 | }, 23 | mutations: { 24 | SOCKET_ONOPEN(state, event) { 25 | }, 26 | SOCKET_ONCLOSE(state, event) { 27 | }, 28 | SOCKET_ONERROR(state, event) { 29 | console.error(event); 30 | }, 31 | SOCKET_ONMESSAGE(state, message) { 32 | switch (message.kind) { 33 | case MESSAGE_MEOW_CREATED: 34 | this.commit(CREATE_MEOW, { id: message.id, body: message.body }); 35 | } 36 | }, 37 | [SET_MEOWS](state, meows) { 38 | state.meows = meows; 39 | }, 40 | [CREATE_MEOW](state, meow) { 41 | state.meows = [meow, ...state.meows]; 42 | }, 43 | [SEARCH_SUCCESS](state, meows) { 44 | state.searchResults = meows; 45 | }, 46 | [SEARCH_ERROR](state) { 47 | state.searchResults = []; 48 | }, 49 | }, 50 | actions: { 51 | getMeows({ commit }) { 52 | axios 53 | .get(`${BACKEND_URL}/meows`) 54 | .then(({ data }) => { 55 | commit(SET_MEOWS, data); 56 | }) 57 | .catch((err) => console.error(err)); 58 | }, 59 | async createMeow({ commit }, meow) { 60 | const { data } = await axios.post(`${BACKEND_URL}/meows`, null, { 61 | params: { 62 | body: meow.body, 63 | }, 64 | }); 65 | }, 66 | async searchMeows({ commit }, query) { 67 | if (query.length === 0) { 68 | commit(SEARCH_SUCCESS, []); 69 | return; 70 | } 71 | axios 72 | .get(`${BACKEND_URL}/search`, { 73 | params: { query }, 74 | }) 75 | .then(({ data }) => commit(SEARCH_SUCCESS, data)) 76 | .catch((err) => { 77 | console.error(err); 78 | commit(SEARCH_ERROR); 79 | }); 80 | }, 81 | }, 82 | }); 83 | 84 | Vue.use(VueNativeSock, PUSHER_URL, { store, format: 'json' }); 85 | 86 | store.dispatch('getMeows'); 87 | 88 | export default store; 89 | -------------------------------------------------------------------------------- /query-service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/gorilla/mux" 10 | "github.com/kelseyhightower/envconfig" 11 | "github.com/tinrab/retry" 12 | 13 | "github.com/tinrab/meower/db" 14 | "github.com/tinrab/meower/event" 15 | "github.com/tinrab/meower/search" 16 | ) 17 | 18 | type Config struct { 19 | PostgresDB string `envconfig:"POSTGRES_DB"` 20 | PostgresUser string `envconfig:"POSTGRES_USER"` 21 | PostgresPassword string `envconfig:"POSTGRES_PASSWORD"` 22 | NatsAddress string `envconfig:"NATS_ADDRESS"` 23 | ElasticsearchAddress string `envconfig:"ELASTICSEARCH_ADDRESS"` 24 | } 25 | 26 | func newRouter() (router *mux.Router) { 27 | router = mux.NewRouter() 28 | router.HandleFunc("/meows", listMeowsHandler). 29 | Methods(http.MethodGet) 30 | router.HandleFunc("/search", searchMeowsHandler). 31 | Methods(http.MethodGet) 32 | router.Use(mux.CORSMethodMiddleware(router)) 33 | return 34 | } 35 | 36 | func main() { 37 | var cfg Config 38 | err := envconfig.Process("", &cfg) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | // Connect to PostgreSQL 44 | retry.ForeverSleep(2*time.Second, func(attempt int) error { 45 | addr := fmt.Sprintf("postgres://%s:%s@postgres/%s?sslmode=disable", cfg.PostgresUser, cfg.PostgresPassword, cfg.PostgresDB) 46 | repo, err := db.NewPostgres(addr) 47 | if err != nil { 48 | log.Println(err) 49 | return err 50 | } 51 | db.SetRepository(repo) 52 | return nil 53 | }) 54 | defer db.Close() 55 | 56 | // Connect to ElasticSearch 57 | retry.ForeverSleep(2*time.Second, func(_ int) error { 58 | es, err := search.NewElastic(fmt.Sprintf("http://%s", cfg.ElasticsearchAddress)) 59 | if err != nil { 60 | log.Println(err) 61 | return err 62 | } 63 | search.SetRepository(es) 64 | return nil 65 | }) 66 | defer search.Close() 67 | 68 | // Connect to Nats 69 | retry.ForeverSleep(2*time.Second, func(_ int) error { 70 | es, err := event.NewNats(fmt.Sprintf("nats://%s", cfg.NatsAddress)) 71 | if err != nil { 72 | log.Println(err) 73 | return err 74 | } 75 | err = es.OnMeowCreated(onMeowCreated) 76 | if err != nil { 77 | log.Println(err) 78 | return err 79 | } 80 | event.SetEventStore(es) 81 | return nil 82 | }) 83 | defer event.Close() 84 | 85 | // Run HTTP server 86 | router := newRouter() 87 | if err := http.ListenAndServe(":8080", router); err != nil { 88 | log.Fatal(err) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /event/nats.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "log" 7 | 8 | "github.com/nats-io/nats.go" 9 | 10 | "github.com/tinrab/meower/schema" 11 | ) 12 | 13 | type NatsEventStore struct { 14 | nc *nats.Conn 15 | meowCreatedSubscription *nats.Subscription 16 | meowCreatedChan chan MeowCreatedMessage 17 | } 18 | 19 | func NewNats(url string) (*NatsEventStore, error) { 20 | nc, err := nats.Connect(url) 21 | if err != nil { 22 | return nil, err 23 | } 24 | return &NatsEventStore{nc: nc}, nil 25 | } 26 | 27 | func (es *NatsEventStore) SubscribeMeowCreated() (<-chan MeowCreatedMessage, error) { 28 | m := MeowCreatedMessage{} 29 | es.meowCreatedChan = make(chan MeowCreatedMessage, 64) 30 | ch := make(chan *nats.Msg, 64) 31 | var err error 32 | es.meowCreatedSubscription, err = es.nc.ChanSubscribe(m.Key(), ch) 33 | if err != nil { 34 | return nil, err 35 | } 36 | // Decode message 37 | go func() { 38 | for { 39 | select { 40 | case msg := <-ch: 41 | if err := es.readMessage(msg.Data, &m); err != nil { 42 | log.Fatal(err) 43 | } 44 | es.meowCreatedChan <- m 45 | } 46 | } 47 | }() 48 | return (<-chan MeowCreatedMessage)(es.meowCreatedChan), nil 49 | } 50 | 51 | func (es *NatsEventStore) OnMeowCreated(f func(MeowCreatedMessage)) (err error) { 52 | m := MeowCreatedMessage{} 53 | es.meowCreatedSubscription, err = es.nc.Subscribe(m.Key(), func(msg *nats.Msg) { 54 | if err := es.readMessage(msg.Data, &m); err != nil { 55 | log.Fatal(err) 56 | } 57 | f(m) 58 | }) 59 | return 60 | } 61 | 62 | func (es *NatsEventStore) Close() { 63 | if es.nc != nil { 64 | es.nc.Close() 65 | } 66 | if es.meowCreatedSubscription != nil { 67 | if err := es.meowCreatedSubscription.Unsubscribe(); err != nil { 68 | log.Fatal(err) 69 | } 70 | } 71 | close(es.meowCreatedChan) 72 | } 73 | 74 | func (es *NatsEventStore) PublishMeowCreated(meow schema.Meow) error { 75 | m := MeowCreatedMessage{meow.ID, meow.Body, meow.CreatedAt} 76 | data, err := es.writeMessage(&m) 77 | if err != nil { 78 | return err 79 | } 80 | return es.nc.Publish(m.Key(), data) 81 | } 82 | 83 | func (es *NatsEventStore) writeMessage(m Message) ([]byte, error) { 84 | b := bytes.Buffer{} 85 | err := gob.NewEncoder(&b).Encode(m) 86 | if err != nil { 87 | return nil, err 88 | } 89 | return b.Bytes(), nil 90 | } 91 | 92 | func (es *NatsEventStore) readMessage(data []byte, m interface{}) error { 93 | b := bytes.Buffer{} 94 | b.Write(data) 95 | return gob.NewDecoder(&b).Decode(m) 96 | } 97 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/.travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | client_configure() { 6 | sudo chmod 600 $PQSSLCERTTEST_PATH/postgresql.key 7 | } 8 | 9 | pgdg_repository() { 10 | local sourcelist='sources.list.d/postgresql.list' 11 | 12 | curl -sS 'https://www.postgresql.org/media/keys/ACCC4CF8.asc' | sudo apt-key add - 13 | echo deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main $PGVERSION | sudo tee "/etc/apt/$sourcelist" 14 | sudo apt-get -o Dir::Etc::sourcelist="$sourcelist" -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0' update 15 | } 16 | 17 | postgresql_configure() { 18 | sudo tee /etc/postgresql/$PGVERSION/main/pg_hba.conf > /dev/null <<-config 19 | local all all trust 20 | hostnossl all pqgossltest 127.0.0.1/32 reject 21 | hostnossl all pqgosslcert 127.0.0.1/32 reject 22 | hostssl all pqgossltest 127.0.0.1/32 trust 23 | hostssl all pqgosslcert 127.0.0.1/32 cert 24 | host all all 127.0.0.1/32 trust 25 | hostnossl all pqgossltest ::1/128 reject 26 | hostnossl all pqgosslcert ::1/128 reject 27 | hostssl all pqgossltest ::1/128 trust 28 | hostssl all pqgosslcert ::1/128 cert 29 | host all all ::1/128 trust 30 | config 31 | 32 | xargs sudo install -o postgres -g postgres -m 600 -t /var/lib/postgresql/$PGVERSION/main/ <<-certificates 33 | certs/root.crt 34 | certs/server.crt 35 | certs/server.key 36 | certificates 37 | 38 | sort -VCu <<-versions || 39 | $PGVERSION 40 | 9.2 41 | versions 42 | sudo tee -a /etc/postgresql/$PGVERSION/main/postgresql.conf > /dev/null <<-config 43 | ssl_ca_file = 'root.crt' 44 | ssl_cert_file = 'server.crt' 45 | ssl_key_file = 'server.key' 46 | config 47 | 48 | echo 127.0.0.1 postgres | sudo tee -a /etc/hosts > /dev/null 49 | 50 | sudo service postgresql restart 51 | } 52 | 53 | postgresql_install() { 54 | xargs sudo apt-get -y -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confnew' install <<-packages 55 | postgresql-$PGVERSION 56 | postgresql-server-dev-$PGVERSION 57 | postgresql-contrib-$PGVERSION 58 | packages 59 | } 60 | 61 | postgresql_uninstall() { 62 | sudo service postgresql stop 63 | xargs sudo apt-get -y --purge remove <<-packages 64 | libpq-dev 65 | libpq5 66 | postgresql 67 | postgresql-client-common 68 | postgresql-common 69 | packages 70 | sudo rm -rf /var/lib/postgresql 71 | } 72 | 73 | $1 74 | -------------------------------------------------------------------------------- /pusher-service/hub.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | "sync" 8 | 9 | "github.com/gorilla/websocket" 10 | ) 11 | 12 | var upgrader = websocket.Upgrader{ 13 | CheckOrigin: func(r *http.Request) bool { return true }, 14 | } 15 | 16 | type Hub struct { 17 | clients []*Client 18 | nextID int 19 | register chan *Client 20 | unregister chan *Client 21 | mutex *sync.Mutex 22 | } 23 | 24 | func newHub() *Hub { 25 | return &Hub{ 26 | clients: make([]*Client, 0), 27 | nextID: 0, 28 | register: make(chan *Client), 29 | unregister: make(chan *Client), 30 | mutex: &sync.Mutex{}, 31 | } 32 | } 33 | 34 | func (hub *Hub) run() { 35 | for { 36 | select { 37 | case client := <-hub.register: 38 | hub.onConnect(client) 39 | case client := <-hub.unregister: 40 | hub.onDisconnect(client) 41 | } 42 | } 43 | } 44 | 45 | func (hub *Hub) broadcast(message interface{}, ignore *Client) { 46 | data, _ := json.Marshal(message) 47 | for _, c := range hub.clients { 48 | if c != ignore { 49 | c.outbound <- data 50 | } 51 | } 52 | } 53 | 54 | func (hub *Hub) send(message interface{}, client *Client) { 55 | data, _ := json.Marshal(message) 56 | client.outbound <- data 57 | } 58 | 59 | func (hub *Hub) disconnect(client *Client) { 60 | client.close() 61 | hub.mutex.Lock() 62 | defer hub.mutex.Unlock() 63 | 64 | // Find index of client 65 | i := -1 66 | for j, c := range hub.clients { 67 | if c.id == client.id { 68 | i = j 69 | break 70 | } 71 | } 72 | // Delete client from list 73 | copy(hub.clients[i:], hub.clients[i+1:]) 74 | hub.clients[len(hub.clients)-1] = nil 75 | hub.clients = hub.clients[:len(hub.clients)-1] 76 | } 77 | 78 | func (hub *Hub) handleWebSocket(w http.ResponseWriter, r *http.Request) { 79 | socket, err := upgrader.Upgrade(w, r, nil) 80 | if err != nil { 81 | log.Println(err) 82 | http.Error(w, "could not upgrade", http.StatusInternalServerError) 83 | return 84 | } 85 | client := newClient(hub, socket) 86 | hub.register <- client 87 | 88 | go client.write() 89 | } 90 | 91 | func (hub *Hub) onConnect(client *Client) { 92 | log.Println("client connected: ", client.socket.RemoteAddr()) 93 | 94 | // Make new client 95 | hub.mutex.Lock() 96 | defer hub.mutex.Unlock() 97 | client.id = hub.nextID 98 | hub.nextID++ 99 | hub.clients = append(hub.clients, client) 100 | } 101 | 102 | func (hub *Hub) onDisconnect(client *Client) { 103 | log.Println("client disconnected: ", client.socket.RemoteAddr()) 104 | hub.disconnect(client) 105 | } 106 | -------------------------------------------------------------------------------- /search/elastic.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/json" 7 | "errors" 8 | 9 | elastic "github.com/elastic/go-elasticsearch/v7" 10 | 11 | "github.com/tinrab/meower/schema" 12 | ) 13 | 14 | type ElasticRepository struct { 15 | client *elastic.Client 16 | } 17 | 18 | func NewElastic(url string) (*ElasticRepository, error) { 19 | client, err := elastic.NewClient(elastic.Config{ 20 | Addresses: []string{url}, 21 | }) 22 | if err != nil { 23 | return nil, err 24 | } 25 | _, err = client.Info() 26 | if err != nil { 27 | return nil, err 28 | } 29 | return &ElasticRepository{client}, nil 30 | } 31 | 32 | func (r *ElasticRepository) Close() { 33 | } 34 | 35 | func (r *ElasticRepository) InsertMeow(ctx context.Context, meow schema.Meow) error { 36 | body, _ := json.Marshal(meow) 37 | _, err := r.client.Index( 38 | "meows", 39 | bytes.NewReader(body), 40 | r.client.Index.WithDocumentID(meow.ID), 41 | r.client.Index.WithRefresh("wait_for"), 42 | ) 43 | return err 44 | } 45 | 46 | func (r *ElasticRepository) SearchMeows(ctx context.Context, query string, skip uint64, take uint64) (result []schema.Meow, err error) { 47 | var buf bytes.Buffer 48 | reqBody := map[string]interface{}{ 49 | "query": map[string]interface{}{ 50 | "multi_match": map[string]interface{}{ 51 | "query": query, 52 | "fields": []string{"body"}, 53 | "fuzziness": 3, 54 | "cutoff_frequency": 0.0001, 55 | }, 56 | }, 57 | } 58 | if err = json.NewEncoder(&buf).Encode(reqBody); err != nil { 59 | return nil, err 60 | } 61 | 62 | res, err := r.client.Search( 63 | r.client.Search.WithContext(ctx), 64 | r.client.Search.WithIndex("meows"), 65 | r.client.Search.WithFrom(int(skip)), 66 | r.client.Search.WithSize(int(take)), 67 | r.client.Search.WithBody(&buf), 68 | r.client.Search.WithTrackTotalHits(true), 69 | ) 70 | if err != nil { 71 | return nil, err 72 | } 73 | defer func() { 74 | if err = res.Body.Close(); err != nil { 75 | result = nil 76 | } 77 | }() 78 | if res.IsError() { 79 | return nil, errors.New("search failed") 80 | } 81 | 82 | type Response struct { 83 | Took int64 84 | Hits struct { 85 | Total struct { 86 | Value int64 87 | } 88 | Hits []*struct { 89 | Source schema.Meow `json:"_source"` 90 | } 91 | } 92 | } 93 | resBody := Response{} 94 | if err := json.NewDecoder(res.Body).Decode(&resBody); err != nil { 95 | return nil, err 96 | } 97 | var meows []schema.Meow 98 | for _, hit := range resBody.Hits.Hits { 99 | meows = append(meows, hit.Source) 100 | } 101 | return meows, nil 102 | } 103 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/elastic/go-elasticsearch v0.0.0 h1:Pd5fqOuBxKxv83b0+xOAJDAkziWYwFinWnBO0y+TZaA= 2 | github.com/elastic/go-elasticsearch/v7 v7.6.0 h1:sYpGLpEFHgLUKLsZUBfuaVI9QgHjS3JdH9fX4/z8QI8= 3 | github.com/elastic/go-elasticsearch/v7 v7.6.0/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4= 4 | github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= 5 | github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 6 | github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= 7 | github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 8 | github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= 9 | github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= 10 | github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= 11 | github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 12 | github.com/nats-io/jwt v0.3.0 h1:xdnzwFETV++jNc4W1mw//qFyJGb2ABOombmZJQS4+Qo= 13 | github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= 14 | github.com/nats-io/nats.go v1.9.1 h1:ik3HbLhZ0YABLto7iX80pZLPw/6dx3T+++MZJwLnMrQ= 15 | github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= 16 | github.com/nats-io/nkeys v0.1.0 h1:qMd4+pRHgdr1nAClu+2h/2a5F2TmKcCzjCDazVgRoX4= 17 | github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= 18 | github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= 19 | github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= 20 | github.com/segmentio/ksuid v1.0.2 h1:9yBfKyw4ECGTdALaF09Snw3sLJmYIX6AbPJrAy6MrDc= 21 | github.com/segmentio/ksuid v1.0.2/go.mod h1:BXuJDr2byAiHuQaQtSKoXh1J0YmUDurywOXgB2w+OSU= 22 | github.com/tinrab/retry v1.0.0 h1:u1x0cMZszwG44AaEeH8xx3Z1guNt8syzULeOsDhzg9s= 23 | github.com/tinrab/retry v1.0.0/go.mod h1:PWRlqYOz5dCyuZbxKhtQ60GN6OwSLwMxnjMqof4LIso= 24 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 25 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 26 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 27 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 28 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 29 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 30 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 31 | -------------------------------------------------------------------------------- /query-service/handlers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "log" 6 | "net/http" 7 | "strconv" 8 | 9 | "github.com/tinrab/meower/db" 10 | "github.com/tinrab/meower/event" 11 | "github.com/tinrab/meower/schema" 12 | "github.com/tinrab/meower/search" 13 | "github.com/tinrab/meower/util" 14 | ) 15 | 16 | func onMeowCreated(m event.MeowCreatedMessage) { 17 | // Index meow for searching 18 | meow := schema.Meow{ 19 | ID: m.ID, 20 | Body: m.Body, 21 | CreatedAt: m.CreatedAt, 22 | } 23 | if err := search.InsertMeow(context.Background(), meow); err != nil { 24 | log.Println(err) 25 | } 26 | } 27 | 28 | func listMeowsHandler(w http.ResponseWriter, r *http.Request) { 29 | ctx := r.Context() 30 | var err error 31 | 32 | // Read parameters 33 | skip := uint64(0) 34 | skipStr := r.FormValue("skip") 35 | take := uint64(100) 36 | takeStr := r.FormValue("take") 37 | if len(skipStr) != 0 { 38 | skip, err = strconv.ParseUint(skipStr, 10, 64) 39 | if err != nil { 40 | util.ResponseError(w, http.StatusBadRequest, "Invalid skip parameter") 41 | return 42 | } 43 | } 44 | if len(takeStr) != 0 { 45 | take, err = strconv.ParseUint(takeStr, 10, 64) 46 | if err != nil { 47 | util.ResponseError(w, http.StatusBadRequest, "Invalid take parameter") 48 | return 49 | } 50 | } 51 | 52 | // Fetch meows 53 | meows, err := db.ListMeows(ctx, skip, take) 54 | if err != nil { 55 | log.Println(err) 56 | util.ResponseError(w, http.StatusInternalServerError, "Could not fetch meows") 57 | return 58 | } 59 | 60 | util.ResponseOk(w, meows) 61 | } 62 | 63 | func searchMeowsHandler(w http.ResponseWriter, r *http.Request) { 64 | var err error 65 | ctx := r.Context() 66 | 67 | // Read parameters 68 | query := r.FormValue("query") 69 | if len(query) == 0 { 70 | util.ResponseError(w, http.StatusBadRequest, "Missing query parameter") 71 | return 72 | } 73 | skip := uint64(0) 74 | skipStr := r.FormValue("skip") 75 | take := uint64(100) 76 | takeStr := r.FormValue("take") 77 | if len(skipStr) != 0 { 78 | skip, err = strconv.ParseUint(skipStr, 10, 64) 79 | if err != nil { 80 | util.ResponseError(w, http.StatusBadRequest, "Invalid skip parameter") 81 | return 82 | } 83 | } 84 | if len(takeStr) != 0 { 85 | take, err = strconv.ParseUint(takeStr, 10, 64) 86 | if err != nil { 87 | util.ResponseError(w, http.StatusBadRequest, "Invalid take parameter") 88 | return 89 | } 90 | } 91 | 92 | // Search meows 93 | meows, err := search.SearchMeows(ctx, query, skip, take) 94 | if err != nil { 95 | log.Println(err) 96 | util.ResponseOk(w, []schema.Meow{}) 97 | return 98 | } 99 | 100 | util.ResponseOk(w, meows) 101 | } 102 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/rows.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "math" 5 | "reflect" 6 | "time" 7 | 8 | "github.com/lib/pq/oid" 9 | ) 10 | 11 | const headerSize = 4 12 | 13 | type fieldDesc struct { 14 | // The object ID of the data type. 15 | OID oid.Oid 16 | // The data type size (see pg_type.typlen). 17 | // Note that negative values denote variable-width types. 18 | Len int 19 | // The type modifier (see pg_attribute.atttypmod). 20 | // The meaning of the modifier is type-specific. 21 | Mod int 22 | } 23 | 24 | func (fd fieldDesc) Type() reflect.Type { 25 | switch fd.OID { 26 | case oid.T_int8: 27 | return reflect.TypeOf(int64(0)) 28 | case oid.T_int4: 29 | return reflect.TypeOf(int32(0)) 30 | case oid.T_int2: 31 | return reflect.TypeOf(int16(0)) 32 | case oid.T_varchar, oid.T_text: 33 | return reflect.TypeOf("") 34 | case oid.T_bool: 35 | return reflect.TypeOf(false) 36 | case oid.T_date, oid.T_time, oid.T_timetz, oid.T_timestamp, oid.T_timestamptz: 37 | return reflect.TypeOf(time.Time{}) 38 | case oid.T_bytea: 39 | return reflect.TypeOf([]byte(nil)) 40 | default: 41 | return reflect.TypeOf(new(interface{})).Elem() 42 | } 43 | } 44 | 45 | func (fd fieldDesc) Name() string { 46 | return oid.TypeName[fd.OID] 47 | } 48 | 49 | func (fd fieldDesc) Length() (length int64, ok bool) { 50 | switch fd.OID { 51 | case oid.T_text, oid.T_bytea: 52 | return math.MaxInt64, true 53 | case oid.T_varchar, oid.T_bpchar: 54 | return int64(fd.Mod - headerSize), true 55 | default: 56 | return 0, false 57 | } 58 | } 59 | 60 | func (fd fieldDesc) PrecisionScale() (precision, scale int64, ok bool) { 61 | switch fd.OID { 62 | case oid.T_numeric, oid.T__numeric: 63 | mod := fd.Mod - headerSize 64 | precision = int64((mod >> 16) & 0xffff) 65 | scale = int64(mod & 0xffff) 66 | return precision, scale, true 67 | default: 68 | return 0, 0, false 69 | } 70 | } 71 | 72 | // ColumnTypeScanType returns the value type that can be used to scan types into. 73 | func (rs *rows) ColumnTypeScanType(index int) reflect.Type { 74 | return rs.colTyps[index].Type() 75 | } 76 | 77 | // ColumnTypeDatabaseTypeName return the database system type name. 78 | func (rs *rows) ColumnTypeDatabaseTypeName(index int) string { 79 | return rs.colTyps[index].Name() 80 | } 81 | 82 | // ColumnTypeLength returns the length of the column type if the column is a 83 | // variable length type. If the column is not a variable length type ok 84 | // should return false. 85 | func (rs *rows) ColumnTypeLength(index int) (length int64, ok bool) { 86 | return rs.colTyps[index].Length() 87 | } 88 | 89 | // ColumnTypePrecisionScale should return the precision and scale for decimal 90 | // types. If not applicable, ok should be false. 91 | func (rs *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { 92 | return rs.colTyps[index].PrecisionScale() 93 | } 94 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/mux/middleware.go: -------------------------------------------------------------------------------- 1 | package mux 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | ) 7 | 8 | // MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler. 9 | // Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed 10 | // to it, and then calls the handler passed as parameter to the MiddlewareFunc. 11 | type MiddlewareFunc func(http.Handler) http.Handler 12 | 13 | // middleware interface is anything which implements a MiddlewareFunc named Middleware. 14 | type middleware interface { 15 | Middleware(handler http.Handler) http.Handler 16 | } 17 | 18 | // Middleware allows MiddlewareFunc to implement the middleware interface. 19 | func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler { 20 | return mw(handler) 21 | } 22 | 23 | // Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. 24 | func (r *Router) Use(mwf ...MiddlewareFunc) { 25 | for _, fn := range mwf { 26 | r.middlewares = append(r.middlewares, fn) 27 | } 28 | } 29 | 30 | // useInterface appends a middleware to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. 31 | func (r *Router) useInterface(mw middleware) { 32 | r.middlewares = append(r.middlewares, mw) 33 | } 34 | 35 | // CORSMethodMiddleware automatically sets the Access-Control-Allow-Methods response header 36 | // on requests for routes that have an OPTIONS method matcher to all the method matchers on 37 | // the route. Routes that do not explicitly handle OPTIONS requests will not be processed 38 | // by the middleware. See examples for usage. 39 | func CORSMethodMiddleware(r *Router) MiddlewareFunc { 40 | return func(next http.Handler) http.Handler { 41 | return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 42 | allMethods, err := getAllMethodsForRoute(r, req) 43 | if err == nil { 44 | for _, v := range allMethods { 45 | if v == http.MethodOptions { 46 | w.Header().Set("Access-Control-Allow-Methods", strings.Join(allMethods, ",")) 47 | } 48 | } 49 | } 50 | 51 | next.ServeHTTP(w, req) 52 | }) 53 | } 54 | } 55 | 56 | // getAllMethodsForRoute returns all the methods from method matchers matching a given 57 | // request. 58 | func getAllMethodsForRoute(r *Router, req *http.Request) ([]string, error) { 59 | var allMethods []string 60 | 61 | for _, route := range r.routes { 62 | var match RouteMatch 63 | if route.Match(req, &match) || match.MatchErr == ErrMethodMismatch { 64 | methods, err := route.GetMethods() 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | allMethods = append(allMethods, methods...) 70 | } 71 | } 72 | 73 | return allMethods, nil 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/README.md: -------------------------------------------------------------------------------- 1 | # pq - A pure Go postgres driver for Go's database/sql package 2 | 3 | [![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://godoc.org/github.com/lib/pq) 4 | [![Build Status](https://travis-ci.org/lib/pq.svg?branch=master)](https://travis-ci.org/lib/pq) 5 | 6 | ## Install 7 | 8 | go get github.com/lib/pq 9 | 10 | ## Docs 11 | 12 | For detailed documentation and basic usage examples, please see the package 13 | documentation at . 14 | 15 | ## Tests 16 | 17 | `go test` is used for testing. See [TESTS.md](TESTS.md) for more details. 18 | 19 | ## Features 20 | 21 | * SSL 22 | * Handles bad connections for `database/sql` 23 | * Scan `time.Time` correctly (i.e. `timestamp[tz]`, `time[tz]`, `date`) 24 | * Scan binary blobs correctly (i.e. `bytea`) 25 | * Package for `hstore` support 26 | * COPY FROM support 27 | * pq.ParseURL for converting urls to connection strings for sql.Open. 28 | * Many libpq compatible environment variables 29 | * Unix socket support 30 | * Notifications: `LISTEN`/`NOTIFY` 31 | * pgpass support 32 | 33 | ## Future / Things you can help with 34 | 35 | * Better COPY FROM / COPY TO (see discussion in #181) 36 | 37 | ## Thank you (alphabetical) 38 | 39 | Some of these contributors are from the original library `bmizerany/pq.go` whose 40 | code still exists in here. 41 | 42 | * Andy Balholm (andybalholm) 43 | * Ben Berkert (benburkert) 44 | * Benjamin Heatwole (bheatwole) 45 | * Bill Mill (llimllib) 46 | * Bjørn Madsen (aeons) 47 | * Blake Gentry (bgentry) 48 | * Brad Fitzpatrick (bradfitz) 49 | * Charlie Melbye (cmelbye) 50 | * Chris Bandy (cbandy) 51 | * Chris Gilling (cgilling) 52 | * Chris Walsh (cwds) 53 | * Dan Sosedoff (sosedoff) 54 | * Daniel Farina (fdr) 55 | * Eric Chlebek (echlebek) 56 | * Eric Garrido (minusnine) 57 | * Eric Urban (hydrogen18) 58 | * Everyone at The Go Team 59 | * Evan Shaw (edsrzf) 60 | * Ewan Chou (coocood) 61 | * Fazal Majid (fazalmajid) 62 | * Federico Romero (federomero) 63 | * Fumin (fumin) 64 | * Gary Burd (garyburd) 65 | * Heroku (heroku) 66 | * James Pozdena (jpoz) 67 | * Jason McVetta (jmcvetta) 68 | * Jeremy Jay (pbnjay) 69 | * Joakim Sernbrant (serbaut) 70 | * John Gallagher (jgallagher) 71 | * Jonathan Rudenberg (titanous) 72 | * Joël Stemmer (jstemmer) 73 | * Kamil Kisiel (kisielk) 74 | * Kelly Dunn (kellydunn) 75 | * Keith Rarick (kr) 76 | * Kir Shatrov (kirs) 77 | * Lann Martin (lann) 78 | * Maciek Sakrejda (uhoh-itsmaciek) 79 | * Marc Brinkmann (mbr) 80 | * Marko Tiikkaja (johto) 81 | * Matt Newberry (MattNewberry) 82 | * Matt Robenolt (mattrobenolt) 83 | * Martin Olsen (martinolsen) 84 | * Mike Lewis (mikelikespie) 85 | * Nicolas Patry (Narsil) 86 | * Oliver Tonnhofer (olt) 87 | * Patrick Hayes (phayes) 88 | * Paul Hammond (paulhammond) 89 | * Ryan Smith (ryandotsmith) 90 | * Samuel Stauffer (samuel) 91 | * Timothée Peignier (cyberdelia) 92 | * Travis Cline (tmc) 93 | * TruongSinh Tran-Nguyen (truongsinh) 94 | * Yaismel Miranda (ympons) 95 | * notedit (notedit) 96 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/server_claims.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The NATS Authors 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package jwt 17 | 18 | import ( 19 | "errors" 20 | 21 | "github.com/nats-io/nkeys" 22 | ) 23 | 24 | // Server defines the custom part of a server jwt 25 | type Server struct { 26 | Permissions 27 | Cluster string `json:"cluster,omitempty"` 28 | } 29 | 30 | // Validate checks the cluster and permissions for a server JWT 31 | func (s *Server) Validate(vr *ValidationResults) { 32 | if s.Cluster == "" { 33 | vr.AddError("servers can't contain an empty cluster") 34 | } 35 | } 36 | 37 | // ServerClaims defines the data in a server JWT 38 | type ServerClaims struct { 39 | ClaimsData 40 | Server `json:"nats,omitempty"` 41 | } 42 | 43 | // NewServerClaims creates a new server JWT with the specified subject/public key 44 | func NewServerClaims(subject string) *ServerClaims { 45 | if subject == "" { 46 | return nil 47 | } 48 | c := &ServerClaims{} 49 | c.Subject = subject 50 | return c 51 | } 52 | 53 | // Encode tries to turn the server claims into a JWT string 54 | func (s *ServerClaims) Encode(pair nkeys.KeyPair) (string, error) { 55 | if !nkeys.IsValidPublicServerKey(s.Subject) { 56 | return "", errors.New("expected subject to be a server public key") 57 | } 58 | s.ClaimsData.Type = ServerClaim 59 | return s.ClaimsData.Encode(pair, s) 60 | } 61 | 62 | // DecodeServerClaims tries to parse server claims from a JWT string 63 | func DecodeServerClaims(token string) (*ServerClaims, error) { 64 | v := ServerClaims{} 65 | if err := Decode(token, &v); err != nil { 66 | return nil, err 67 | } 68 | return &v, nil 69 | } 70 | 71 | func (s *ServerClaims) String() string { 72 | return s.ClaimsData.String(s) 73 | } 74 | 75 | // Payload returns the server specific data 76 | func (s *ServerClaims) Payload() interface{} { 77 | return &s.Server 78 | } 79 | 80 | // Validate checks the generic and server data in the server claims 81 | func (s *ServerClaims) Validate(vr *ValidationResults) { 82 | s.ClaimsData.Validate(vr) 83 | s.Server.Validate(vr) 84 | } 85 | 86 | // ExpectedPrefixes defines the types that can encode a server JWT, operator or cluster 87 | func (s *ServerClaims) ExpectedPrefixes() []nkeys.PrefixByte { 88 | return []nkeys.PrefixByte{nkeys.PrefixByteOperator, nkeys.PrefixByteCluster} 89 | } 90 | 91 | // Claims returns the generic data 92 | func (s *ServerClaims) Claims() *ClaimsData { 93 | return &s.ClaimsData 94 | } 95 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ed25519/ed25519_go113.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.13 6 | 7 | // Package ed25519 implements the Ed25519 signature algorithm. See 8 | // https://ed25519.cr.yp.to/. 9 | // 10 | // These functions are also compatible with the “Ed25519” function defined in 11 | // RFC 8032. However, unlike RFC 8032's formulation, this package's private key 12 | // representation includes a public key suffix to make multiple signing 13 | // operations with the same key more efficient. This package refers to the RFC 14 | // 8032 private key as the “seed”. 15 | // 16 | // Beginning with Go 1.13, the functionality of this package was moved to the 17 | // standard library as crypto/ed25519. This package only acts as a compatibility 18 | // wrapper. 19 | package ed25519 20 | 21 | import ( 22 | "crypto/ed25519" 23 | "io" 24 | ) 25 | 26 | const ( 27 | // PublicKeySize is the size, in bytes, of public keys as used in this package. 28 | PublicKeySize = 32 29 | // PrivateKeySize is the size, in bytes, of private keys as used in this package. 30 | PrivateKeySize = 64 31 | // SignatureSize is the size, in bytes, of signatures generated and verified by this package. 32 | SignatureSize = 64 33 | // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. 34 | SeedSize = 32 35 | ) 36 | 37 | // PublicKey is the type of Ed25519 public keys. 38 | // 39 | // This type is an alias for crypto/ed25519's PublicKey type. 40 | // See the crypto/ed25519 package for the methods on this type. 41 | type PublicKey = ed25519.PublicKey 42 | 43 | // PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. 44 | // 45 | // This type is an alias for crypto/ed25519's PrivateKey type. 46 | // See the crypto/ed25519 package for the methods on this type. 47 | type PrivateKey = ed25519.PrivateKey 48 | 49 | // GenerateKey generates a public/private key pair using entropy from rand. 50 | // If rand is nil, crypto/rand.Reader will be used. 51 | func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { 52 | return ed25519.GenerateKey(rand) 53 | } 54 | 55 | // NewKeyFromSeed calculates a private key from a seed. It will panic if 56 | // len(seed) is not SeedSize. This function is provided for interoperability 57 | // with RFC 8032. RFC 8032's private keys correspond to seeds in this 58 | // package. 59 | func NewKeyFromSeed(seed []byte) PrivateKey { 60 | return ed25519.NewKeyFromSeed(seed) 61 | } 62 | 63 | // Sign signs the message with privateKey and returns a signature. It will 64 | // panic if len(privateKey) is not PrivateKeySize. 65 | func Sign(privateKey PrivateKey, message []byte) []byte { 66 | return ed25519.Sign(privateKey, message) 67 | } 68 | 69 | // Verify reports whether sig is a valid signature of message by publicKey. It 70 | // will panic if len(publicKey) is not PublicKeySize. 71 | func Verify(publicKey PublicKey, message, sig []byte) bool { 72 | return ed25519.Verify(publicKey, message, sig) 73 | } 74 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/cluster_claims.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The NATS Authors 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package jwt 17 | 18 | import ( 19 | "errors" 20 | 21 | "github.com/nats-io/nkeys" 22 | ) 23 | 24 | // Cluster stores the cluster specific elements of a cluster JWT 25 | type Cluster struct { 26 | Trust []string `json:"identity,omitempty"` 27 | Accounts []string `json:"accts,omitempty"` 28 | AccountURL string `json:"accturl,omitempty"` 29 | OperatorURL string `json:"opurl,omitempty"` 30 | } 31 | 32 | // Validate checks the cluster and permissions for a cluster JWT 33 | func (c *Cluster) Validate(vr *ValidationResults) { 34 | // fixme validate cluster data 35 | } 36 | 37 | // ClusterClaims defines the data in a cluster JWT 38 | type ClusterClaims struct { 39 | ClaimsData 40 | Cluster `json:"nats,omitempty"` 41 | } 42 | 43 | // NewClusterClaims creates a new cluster JWT with the specified subject/public key 44 | func NewClusterClaims(subject string) *ClusterClaims { 45 | if subject == "" { 46 | return nil 47 | } 48 | c := &ClusterClaims{} 49 | c.Subject = subject 50 | return c 51 | } 52 | 53 | // Encode tries to turn the cluster claims into a JWT string 54 | func (c *ClusterClaims) Encode(pair nkeys.KeyPair) (string, error) { 55 | if !nkeys.IsValidPublicClusterKey(c.Subject) { 56 | return "", errors.New("expected subject to be a cluster public key") 57 | } 58 | c.ClaimsData.Type = ClusterClaim 59 | return c.ClaimsData.Encode(pair, c) 60 | } 61 | 62 | // DecodeClusterClaims tries to parse cluster claims from a JWT string 63 | func DecodeClusterClaims(token string) (*ClusterClaims, error) { 64 | v := ClusterClaims{} 65 | if err := Decode(token, &v); err != nil { 66 | return nil, err 67 | } 68 | return &v, nil 69 | } 70 | 71 | func (c *ClusterClaims) String() string { 72 | return c.ClaimsData.String(c) 73 | } 74 | 75 | // Payload returns the cluster specific data 76 | func (c *ClusterClaims) Payload() interface{} { 77 | return &c.Cluster 78 | } 79 | 80 | // Validate checks the generic and cluster data in the cluster claims 81 | func (c *ClusterClaims) Validate(vr *ValidationResults) { 82 | c.ClaimsData.Validate(vr) 83 | c.Cluster.Validate(vr) 84 | } 85 | 86 | // ExpectedPrefixes defines the types that can encode a cluster JWT, operator or cluster 87 | func (c *ClusterClaims) ExpectedPrefixes() []nkeys.PrefixByte { 88 | return []nkeys.PrefixByte{nkeys.PrefixByteOperator, nkeys.PrefixByteCluster} 89 | } 90 | 91 | // Claims returns the generic data 92 | func (c *ClusterClaims) Claims() *ClaimsData { 93 | return &c.ClaimsData 94 | } 95 | -------------------------------------------------------------------------------- /vendor/github.com/segmentio/ksuid/uint128.go: -------------------------------------------------------------------------------- 1 | package ksuid 2 | 3 | import "fmt" 4 | 5 | // uint128 represents an unsigned 128 bits little endian integer. 6 | type uint128 [2]uint64 7 | 8 | func uint128Payload(ksuid KSUID) uint128 { 9 | return makeUint128FromPayload(ksuid[timestampLengthInBytes:]) 10 | } 11 | 12 | func makeUint128(high uint64, low uint64) uint128 { 13 | return uint128{low, high} 14 | } 15 | 16 | func makeUint128FromPayload(payload []byte) uint128 { 17 | return uint128{ 18 | // low 19 | uint64(payload[8])<<56 | 20 | uint64(payload[9])<<48 | 21 | uint64(payload[10])<<40 | 22 | uint64(payload[11])<<32 | 23 | uint64(payload[12])<<24 | 24 | uint64(payload[13])<<16 | 25 | uint64(payload[14])<<8 | 26 | uint64(payload[15]), 27 | // high 28 | uint64(payload[0])<<56 | 29 | uint64(payload[1])<<48 | 30 | uint64(payload[2])<<40 | 31 | uint64(payload[3])<<32 | 32 | uint64(payload[4])<<24 | 33 | uint64(payload[5])<<16 | 34 | uint64(payload[6])<<8 | 35 | uint64(payload[7]), 36 | } 37 | } 38 | 39 | func (v uint128) ksuid(timestamp uint32) KSUID { 40 | return KSUID{ 41 | // time 42 | byte(timestamp >> 24), 43 | byte(timestamp >> 16), 44 | byte(timestamp >> 8), 45 | byte(timestamp), 46 | 47 | // high 48 | byte(v[1] >> 56), 49 | byte(v[1] >> 48), 50 | byte(v[1] >> 40), 51 | byte(v[1] >> 32), 52 | byte(v[1] >> 24), 53 | byte(v[1] >> 16), 54 | byte(v[1] >> 8), 55 | byte(v[1]), 56 | 57 | // low 58 | byte(v[0] >> 56), 59 | byte(v[0] >> 48), 60 | byte(v[0] >> 40), 61 | byte(v[0] >> 32), 62 | byte(v[0] >> 24), 63 | byte(v[0] >> 16), 64 | byte(v[0] >> 8), 65 | byte(v[0]), 66 | } 67 | } 68 | 69 | func (v uint128) bytes() [16]byte { 70 | return [16]byte{ 71 | // high 72 | byte(v[1] >> 56), 73 | byte(v[1] >> 48), 74 | byte(v[1] >> 40), 75 | byte(v[1] >> 32), 76 | byte(v[1] >> 24), 77 | byte(v[1] >> 16), 78 | byte(v[1] >> 8), 79 | byte(v[1]), 80 | 81 | // low 82 | byte(v[0] >> 56), 83 | byte(v[0] >> 48), 84 | byte(v[0] >> 40), 85 | byte(v[0] >> 32), 86 | byte(v[0] >> 24), 87 | byte(v[0] >> 16), 88 | byte(v[0] >> 8), 89 | byte(v[0]), 90 | } 91 | } 92 | 93 | func (v uint128) String() string { 94 | return fmt.Sprintf("0x%016X%016X", v[0], v[1]) 95 | } 96 | 97 | const wordBitSize = 64 98 | 99 | func cmp128(x, y uint128) int { 100 | if x[1] < y[1] { 101 | return -1 102 | } 103 | if x[1] > y[1] { 104 | return 1 105 | } 106 | if x[0] < y[0] { 107 | return -1 108 | } 109 | if x[0] > y[0] { 110 | return 1 111 | } 112 | return 0 113 | } 114 | 115 | func add128(x, y uint128) (z uint128) { 116 | x0 := x[0] 117 | y0 := y[0] 118 | z0 := x0 + y0 119 | z[0] = z0 120 | 121 | c := (x0&y0 | (x0|y0)&^z0) >> (wordBitSize - 1) 122 | 123 | z[1] = x[1] + y[1] + c 124 | return 125 | } 126 | 127 | func sub128(x, y uint128) (z uint128) { 128 | x0 := x[0] 129 | y0 := y[0] 130 | z0 := x0 - y0 131 | z[0] = z0 132 | 133 | c := (y0&^x0 | (y0|^x0)&z0) >> (wordBitSize - 1) 134 | 135 | z[1] = x[1] - y[1] - c 136 | return 137 | } 138 | 139 | func incr128(x uint128) uint128 { 140 | return add128(x, uint128{1, 0}) 141 | } 142 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/user_claims.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 The NATS Authors 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package jwt 17 | 18 | import ( 19 | "errors" 20 | 21 | "github.com/nats-io/nkeys" 22 | ) 23 | 24 | // User defines the user specific data in a user JWT 25 | type User struct { 26 | Permissions 27 | Limits 28 | } 29 | 30 | // Validate checks the permissions and limits in a User jwt 31 | func (u *User) Validate(vr *ValidationResults) { 32 | u.Permissions.Validate(vr) 33 | u.Limits.Validate(vr) 34 | } 35 | 36 | // UserClaims defines a user JWT 37 | type UserClaims struct { 38 | ClaimsData 39 | User `json:"nats,omitempty"` 40 | // IssuerAccount stores the public key for the account the issuer represents. 41 | // When set, the claim was issued by a signing key. 42 | IssuerAccount string `json:"issuer_account,omitempty"` 43 | } 44 | 45 | // NewUserClaims creates a user JWT with the specific subject/public key 46 | func NewUserClaims(subject string) *UserClaims { 47 | if subject == "" { 48 | return nil 49 | } 50 | c := &UserClaims{} 51 | c.Subject = subject 52 | return c 53 | } 54 | 55 | // Encode tries to turn the user claims into a JWT string 56 | func (u *UserClaims) Encode(pair nkeys.KeyPair) (string, error) { 57 | if !nkeys.IsValidPublicUserKey(u.Subject) { 58 | return "", errors.New("expected subject to be user public key") 59 | } 60 | u.ClaimsData.Type = UserClaim 61 | return u.ClaimsData.Encode(pair, u) 62 | } 63 | 64 | // DecodeUserClaims tries to parse a user claims from a JWT string 65 | func DecodeUserClaims(token string) (*UserClaims, error) { 66 | v := UserClaims{} 67 | if err := Decode(token, &v); err != nil { 68 | return nil, err 69 | } 70 | return &v, nil 71 | } 72 | 73 | // Validate checks the generic and specific parts of the user jwt 74 | func (u *UserClaims) Validate(vr *ValidationResults) { 75 | u.ClaimsData.Validate(vr) 76 | u.User.Validate(vr) 77 | if u.IssuerAccount != "" && !nkeys.IsValidPublicAccountKey(u.IssuerAccount) { 78 | vr.AddError("account_id is not an account public key") 79 | } 80 | } 81 | 82 | // ExpectedPrefixes defines the types that can encode a user JWT, account 83 | func (u *UserClaims) ExpectedPrefixes() []nkeys.PrefixByte { 84 | return []nkeys.PrefixByte{nkeys.PrefixByteAccount} 85 | } 86 | 87 | // Claims returns the generic data from a user jwt 88 | func (u *UserClaims) Claims() *ClaimsData { 89 | return &u.ClaimsData 90 | } 91 | 92 | // Payload returns the user specific data from a user JWT 93 | func (u *UserClaims) Payload() interface{} { 94 | return &u.User 95 | } 96 | 97 | func (u *UserClaims) String() string { 98 | return u.ClaimsData.String(u) 99 | } 100 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/encoders/builtin/default_enc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package builtin 15 | 16 | import ( 17 | "bytes" 18 | "fmt" 19 | "reflect" 20 | "strconv" 21 | "unsafe" 22 | ) 23 | 24 | // DefaultEncoder implementation for EncodedConn. 25 | // This encoder will leave []byte and string untouched, but will attempt to 26 | // turn numbers into appropriate strings that can be decoded. It will also 27 | // propely encoded and decode bools. If will encode a struct, but if you want 28 | // to properly handle structures you should use JsonEncoder. 29 | type DefaultEncoder struct { 30 | // Empty 31 | } 32 | 33 | var trueB = []byte("true") 34 | var falseB = []byte("false") 35 | var nilB = []byte("") 36 | 37 | // Encode 38 | func (je *DefaultEncoder) Encode(subject string, v interface{}) ([]byte, error) { 39 | switch arg := v.(type) { 40 | case string: 41 | bytes := *(*[]byte)(unsafe.Pointer(&arg)) 42 | return bytes, nil 43 | case []byte: 44 | return arg, nil 45 | case bool: 46 | if arg { 47 | return trueB, nil 48 | } else { 49 | return falseB, nil 50 | } 51 | case nil: 52 | return nilB, nil 53 | default: 54 | var buf bytes.Buffer 55 | fmt.Fprintf(&buf, "%+v", arg) 56 | return buf.Bytes(), nil 57 | } 58 | } 59 | 60 | // Decode 61 | func (je *DefaultEncoder) Decode(subject string, data []byte, vPtr interface{}) error { 62 | // Figure out what it's pointing to... 63 | sData := *(*string)(unsafe.Pointer(&data)) 64 | switch arg := vPtr.(type) { 65 | case *string: 66 | *arg = sData 67 | return nil 68 | case *[]byte: 69 | *arg = data 70 | return nil 71 | case *int: 72 | n, err := strconv.ParseInt(sData, 10, 64) 73 | if err != nil { 74 | return err 75 | } 76 | *arg = int(n) 77 | return nil 78 | case *int32: 79 | n, err := strconv.ParseInt(sData, 10, 64) 80 | if err != nil { 81 | return err 82 | } 83 | *arg = int32(n) 84 | return nil 85 | case *int64: 86 | n, err := strconv.ParseInt(sData, 10, 64) 87 | if err != nil { 88 | return err 89 | } 90 | *arg = int64(n) 91 | return nil 92 | case *float32: 93 | n, err := strconv.ParseFloat(sData, 32) 94 | if err != nil { 95 | return err 96 | } 97 | *arg = float32(n) 98 | return nil 99 | case *float64: 100 | n, err := strconv.ParseFloat(sData, 64) 101 | if err != nil { 102 | return err 103 | } 104 | *arg = float64(n) 105 | return nil 106 | case *bool: 107 | b, err := strconv.ParseBool(sData) 108 | if err != nil { 109 | return err 110 | } 111 | *arg = b 112 | return nil 113 | default: 114 | vt := reflect.TypeOf(arg).Elem() 115 | return fmt.Errorf("nats: Default Encoder can't decode to type %s", vt) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/jwt/validation.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 The NATS Authors 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package jwt 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | ) 22 | 23 | // ValidationIssue represents an issue during JWT validation, it may or may not be a blocking error 24 | type ValidationIssue struct { 25 | Description string 26 | Blocking bool 27 | TimeCheck bool 28 | } 29 | 30 | func (ve *ValidationIssue) Error() string { 31 | return ve.Description 32 | } 33 | 34 | // ValidationResults is a list of ValidationIssue pointers 35 | type ValidationResults struct { 36 | Issues []*ValidationIssue 37 | } 38 | 39 | // CreateValidationResults creates an empty list of validation issues 40 | func CreateValidationResults() *ValidationResults { 41 | issues := []*ValidationIssue{} 42 | return &ValidationResults{ 43 | Issues: issues, 44 | } 45 | } 46 | 47 | //Add appends an issue to the list 48 | func (v *ValidationResults) Add(vi *ValidationIssue) { 49 | v.Issues = append(v.Issues, vi) 50 | } 51 | 52 | // AddError creates a new validation error and adds it to the list 53 | func (v *ValidationResults) AddError(format string, args ...interface{}) { 54 | v.Add(&ValidationIssue{ 55 | Description: fmt.Sprintf(format, args...), 56 | Blocking: true, 57 | TimeCheck: false, 58 | }) 59 | } 60 | 61 | // AddTimeCheck creates a new validation issue related to a time check and adds it to the list 62 | func (v *ValidationResults) AddTimeCheck(format string, args ...interface{}) { 63 | v.Add(&ValidationIssue{ 64 | Description: fmt.Sprintf(format, args...), 65 | Blocking: false, 66 | TimeCheck: true, 67 | }) 68 | } 69 | 70 | // AddWarning creates a new validation warning and adds it to the list 71 | func (v *ValidationResults) AddWarning(format string, args ...interface{}) { 72 | v.Add(&ValidationIssue{ 73 | Description: fmt.Sprintf(format, args...), 74 | Blocking: false, 75 | TimeCheck: false, 76 | }) 77 | } 78 | 79 | // IsBlocking returns true if the list contains a blocking error 80 | func (v *ValidationResults) IsBlocking(includeTimeChecks bool) bool { 81 | for _, i := range v.Issues { 82 | if i.Blocking { 83 | return true 84 | } 85 | 86 | if includeTimeChecks && i.TimeCheck { 87 | return true 88 | } 89 | } 90 | return false 91 | } 92 | 93 | // IsEmpty returns true if the list is empty 94 | func (v *ValidationResults) IsEmpty() bool { 95 | return len(v.Issues) == 0 96 | } 97 | 98 | // Errors returns only blocking issues as errors 99 | func (v *ValidationResults) Errors() []error { 100 | var errs []error 101 | for _, v := range v.Issues { 102 | if v.Blocking { 103 | errs = append(errs, errors.New(v.Description)) 104 | } 105 | } 106 | return errs 107 | } 108 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/prepared.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "bytes" 9 | "net" 10 | "sync" 11 | "time" 12 | ) 13 | 14 | // PreparedMessage caches on the wire representations of a message payload. 15 | // Use PreparedMessage to efficiently send a message payload to multiple 16 | // connections. PreparedMessage is especially useful when compression is used 17 | // because the CPU and memory expensive compression operation can be executed 18 | // once for a given set of compression options. 19 | type PreparedMessage struct { 20 | messageType int 21 | data []byte 22 | mu sync.Mutex 23 | frames map[prepareKey]*preparedFrame 24 | } 25 | 26 | // prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. 27 | type prepareKey struct { 28 | isServer bool 29 | compress bool 30 | compressionLevel int 31 | } 32 | 33 | // preparedFrame contains data in wire representation. 34 | type preparedFrame struct { 35 | once sync.Once 36 | data []byte 37 | } 38 | 39 | // NewPreparedMessage returns an initialized PreparedMessage. You can then send 40 | // it to connection using WritePreparedMessage method. Valid wire 41 | // representation will be calculated lazily only once for a set of current 42 | // connection options. 43 | func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { 44 | pm := &PreparedMessage{ 45 | messageType: messageType, 46 | frames: make(map[prepareKey]*preparedFrame), 47 | data: data, 48 | } 49 | 50 | // Prepare a plain server frame. 51 | _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) 52 | if err != nil { 53 | return nil, err 54 | } 55 | 56 | // To protect against caller modifying the data argument, remember the data 57 | // copied to the plain server frame. 58 | pm.data = frameData[len(frameData)-len(data):] 59 | return pm, nil 60 | } 61 | 62 | func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { 63 | pm.mu.Lock() 64 | frame, ok := pm.frames[key] 65 | if !ok { 66 | frame = &preparedFrame{} 67 | pm.frames[key] = frame 68 | } 69 | pm.mu.Unlock() 70 | 71 | var err error 72 | frame.once.Do(func() { 73 | // Prepare a frame using a 'fake' connection. 74 | // TODO: Refactor code in conn.go to allow more direct construction of 75 | // the frame. 76 | mu := make(chan bool, 1) 77 | mu <- true 78 | var nc prepareConn 79 | c := &Conn{ 80 | conn: &nc, 81 | mu: mu, 82 | isServer: key.isServer, 83 | compressionLevel: key.compressionLevel, 84 | enableWriteCompression: true, 85 | writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), 86 | } 87 | if key.compress { 88 | c.newCompressionWriter = compressNoContextTakeover 89 | } 90 | err = c.WriteMessage(pm.messageType, pm.data) 91 | frame.data = nc.buf.Bytes() 92 | }) 93 | return pm.messageType, frame.data, err 94 | } 95 | 96 | type prepareConn struct { 97 | buf bytes.Buffer 98 | net.Conn 99 | } 100 | 101 | func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } 102 | func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } 103 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/keypair.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nkeys 15 | 16 | import ( 17 | "bytes" 18 | "crypto/rand" 19 | "io" 20 | 21 | "golang.org/x/crypto/ed25519" 22 | ) 23 | 24 | // kp is the internal struct for a kepypair using seed. 25 | type kp struct { 26 | seed []byte 27 | } 28 | 29 | // CreatePair will create a KeyPair based on the rand entropy and a type/prefix byte. rand can be nil. 30 | func CreatePair(prefix PrefixByte) (KeyPair, error) { 31 | var rawSeed [32]byte 32 | 33 | _, err := io.ReadFull(rand.Reader, rawSeed[:]) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | seed, err := EncodeSeed(prefix, rawSeed[:]) 39 | if err != nil { 40 | return nil, err 41 | } 42 | return &kp{seed}, nil 43 | } 44 | 45 | // rawSeed will return the raw, decoded 64 byte seed. 46 | func (pair *kp) rawSeed() ([]byte, error) { 47 | _, raw, err := DecodeSeed(pair.seed) 48 | return raw, err 49 | } 50 | 51 | // keys will return a 32 byte public key and a 64 byte private key utilizing the seed. 52 | func (pair *kp) keys() (ed25519.PublicKey, ed25519.PrivateKey, error) { 53 | raw, err := pair.rawSeed() 54 | if err != nil { 55 | return nil, nil, err 56 | } 57 | return ed25519.GenerateKey(bytes.NewReader(raw)) 58 | } 59 | 60 | // Wipe will randomize the contents of the seed key 61 | func (pair *kp) Wipe() { 62 | io.ReadFull(rand.Reader, pair.seed) 63 | pair.seed = nil 64 | } 65 | 66 | // Seed will return the encoded seed. 67 | func (pair *kp) Seed() ([]byte, error) { 68 | return pair.seed, nil 69 | } 70 | 71 | // PublicKey will return the encoded public key associated with the KeyPair. 72 | // All KeyPairs have a public key. 73 | func (pair *kp) PublicKey() (string, error) { 74 | public, raw, err := DecodeSeed(pair.seed) 75 | if err != nil { 76 | return "", err 77 | } 78 | pub, _, err := ed25519.GenerateKey(bytes.NewReader(raw)) 79 | if err != nil { 80 | return "", err 81 | } 82 | pk, err := Encode(public, pub) 83 | if err != nil { 84 | return "", err 85 | } 86 | return string(pk), nil 87 | } 88 | 89 | // PrivateKey will return the encoded private key for KeyPair. 90 | func (pair *kp) PrivateKey() ([]byte, error) { 91 | _, priv, err := pair.keys() 92 | if err != nil { 93 | return nil, err 94 | } 95 | return Encode(PrefixBytePrivate, priv) 96 | } 97 | 98 | // Sign will sign the input with KeyPair's private key. 99 | func (pair *kp) Sign(input []byte) ([]byte, error) { 100 | _, priv, err := pair.keys() 101 | if err != nil { 102 | return nil, err 103 | } 104 | return ed25519.Sign(priv, input), nil 105 | } 106 | 107 | // Verify will verify the input against a signature utilizing the public key. 108 | func (pair *kp) Verify(input []byte, sig []byte) error { 109 | pub, _, err := pair.keys() 110 | if err != nil { 111 | return err 112 | } 113 | if !ed25519.Verify(pub, input, sig) { 114 | return ErrInvalidSignature 115 | } 116 | return nil 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/crc16.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nkeys 15 | 16 | import ( 17 | "errors" 18 | ) 19 | 20 | // An implementation of crc16 according to CCITT standards for XMODEM. 21 | 22 | // ErrInvalidChecksum indicates a failed verification. 23 | var ErrInvalidChecksum = errors.New("nkeys: invalid checksum") 24 | 25 | var crc16tab = [256]uint16{ 26 | 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 27 | 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 28 | 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 29 | 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 30 | 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 31 | 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 32 | 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 33 | 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 34 | 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 35 | 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 36 | 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 37 | 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 38 | 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 39 | 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 40 | 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 41 | 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 42 | 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 43 | 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 44 | 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 45 | 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 46 | 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 47 | 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 48 | 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 49 | 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 50 | 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 51 | 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 52 | 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 53 | 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 54 | 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 55 | 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 56 | 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 57 | 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, 58 | } 59 | 60 | // crc16 returns the 2-byte crc for the data provided. 61 | func crc16(data []byte) uint16 { 62 | var crc uint16 63 | for _, b := range data { 64 | crc = ((crc << 8) & 0xffff) ^ crc16tab[((crc>>8)^uint16(b))&0x00FF] 65 | } 66 | return crc 67 | } 68 | 69 | // validate will check the calculated crc16 checksum for data against the expected. 70 | func validate(data []byte, expected uint16) error { 71 | if crc16(data) != expected { 72 | return ErrInvalidChecksum 73 | } 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2019 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package nkeys is an Ed25519 based public-key signature system that simplifies keys and seeds 15 | // and performs signing and verification. 16 | package nkeys 17 | 18 | import ( 19 | "errors" 20 | ) 21 | 22 | // Version 23 | const Version = "0.1.0" 24 | 25 | // Errors 26 | var ( 27 | ErrInvalidPrefixByte = errors.New("nkeys: invalid prefix byte") 28 | ErrInvalidKey = errors.New("nkeys: invalid key") 29 | ErrInvalidPublicKey = errors.New("nkeys: invalid public key") 30 | ErrInvalidSeedLen = errors.New("nkeys: invalid seed length") 31 | ErrInvalidSeed = errors.New("nkeys: invalid seed") 32 | ErrInvalidEncoding = errors.New("nkeys: invalid encoded key") 33 | ErrInvalidSignature = errors.New("nkeys: signature verification failed") 34 | ErrCannotSign = errors.New("nkeys: can not sign, no private key available") 35 | ErrPublicKeyOnly = errors.New("nkeys: no seed or private key available") 36 | ) 37 | 38 | // KeyPair provides the central interface to nkeys. 39 | type KeyPair interface { 40 | Seed() ([]byte, error) 41 | PublicKey() (string, error) 42 | PrivateKey() ([]byte, error) 43 | Sign(input []byte) ([]byte, error) 44 | Verify(input []byte, sig []byte) error 45 | Wipe() 46 | } 47 | 48 | // CreateUser will create a User typed KeyPair. 49 | func CreateUser() (KeyPair, error) { 50 | return CreatePair(PrefixByteUser) 51 | } 52 | 53 | // CreateAccount will create an Account typed KeyPair. 54 | func CreateAccount() (KeyPair, error) { 55 | return CreatePair(PrefixByteAccount) 56 | } 57 | 58 | // CreateServer will create a Server typed KeyPair. 59 | func CreateServer() (KeyPair, error) { 60 | return CreatePair(PrefixByteServer) 61 | } 62 | 63 | // CreateCluster will create a Cluster typed KeyPair. 64 | func CreateCluster() (KeyPair, error) { 65 | return CreatePair(PrefixByteCluster) 66 | } 67 | 68 | // CreateOperator will create an Operator typed KeyPair. 69 | func CreateOperator() (KeyPair, error) { 70 | return CreatePair(PrefixByteOperator) 71 | } 72 | 73 | // FromPublicKey will create a KeyPair capable of verifying signatures. 74 | func FromPublicKey(public string) (KeyPair, error) { 75 | raw, err := decode([]byte(public)) 76 | if err != nil { 77 | return nil, err 78 | } 79 | pre := PrefixByte(raw[0]) 80 | if err := checkValidPublicPrefixByte(pre); err != nil { 81 | return nil, ErrInvalidPublicKey 82 | } 83 | return &pub{pre, raw[1:]}, nil 84 | } 85 | 86 | // FromSeed will create a KeyPair capable of signing and verifying signatures. 87 | func FromSeed(seed []byte) (KeyPair, error) { 88 | _, _, err := DecodeSeed(seed) 89 | if err != nil { 90 | return nil, err 91 | } 92 | copy := append([]byte{}, seed...) 93 | return &kp{copy}, nil 94 | } 95 | 96 | // Create a KeyPair from the raw 32 byte seed for a given type. 97 | func FromRawSeed(prefix PrefixByte, rawSeed []byte) (KeyPair, error) { 98 | seed, err := EncodeSeed(prefix, rawSeed) 99 | if err != nil { 100 | return nil, err 101 | } 102 | return &kp{seed}, nil 103 | } 104 | -------------------------------------------------------------------------------- /vendor/github.com/elastic/go-elasticsearch/v7/esapi/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package esapi provides the Go API for Elasticsearch. 3 | 4 | It is automatically included in the client provided by the 5 | github.com/elastic/go-elasticsearch package: 6 | 7 | es, _ := elasticsearch.NewDefaultClient() 8 | res, _ := es.Info() 9 | log.Println(res) 10 | 11 | For each Elasticsearch API, such as "Index", the package exports two corresponding types: 12 | a function and a struct. 13 | 14 | The function type allows you to call the Elasticsearch API as a method on the client, 15 | passing the parameters as arguments: 16 | 17 | res, err := es.Index( 18 | "test", // Index name 19 | strings.NewReader(`{"title" : "Test"}`), // Document body 20 | es.Index.WithDocumentID("1"), // Document ID 21 | es.Index.WithRefresh("true"), // Refresh 22 | ) 23 | if err != nil { 24 | log.Fatalf("ERROR: %s", err) 25 | } 26 | defer res.Body.Close() 27 | 28 | log.Println(res) 29 | 30 | // => [201 Created] {"_index":"test","_type":"_doc","_id":"1" ... 31 | 32 | The struct type allows for a more hands-on approach, where you create a new struct, with the 33 | request configuration as fields, and call the Do() method 34 | with a context and the client as arguments: 35 | 36 | req := esapi.IndexRequest{ 37 | Index: "test", // Index name 38 | Body: strings.NewReader(`{"title" : "Test"}`), // Document body 39 | DocumentID: "1", // Document ID 40 | Refresh: "true", // Refresh 41 | } 42 | 43 | res, err := req.Do(context.Background(), es) 44 | if err != nil { 45 | log.Fatalf("Error getting response: %s", err) 46 | } 47 | defer res.Body.Close() 48 | 49 | log.Println(res) 50 | 51 | // => [200 OK] {"_index":"test","_type":"_doc","_id":"1","_version":2 ... 52 | 53 | The function type is a wrapper around the struct, and allows 54 | to configure and perform the request in a more expressive way. 55 | It has a minor overhead compared to using a struct directly; 56 | refer to the esapi_benchmark_test.go suite for concrete numbers. 57 | 58 | See the documentation for each API function or struct at 59 | https://godoc.org/github.com/elastic/go-elasticsearch, 60 | or locally by: 61 | 62 | go doc github.com/elastic/go-elasticsearch/v7/esapi Index 63 | go doc github.com/elastic/go-elasticsearch/v7/esapi IndexRequest 64 | 65 | Response 66 | 67 | The esapi.Response type is a lightweight wrapper around http.Response. 68 | 69 | The res.Body field is an io.ReadCloser, leaving the JSON parsing to the 70 | calling code, in the interest of performance and flexibility 71 | (eg. to allow using a custom JSON parser). 72 | 73 | It is imperative to close the response body for a non-nil response. 74 | 75 | The Response type implements a couple of convenience methods for accessing 76 | the status, checking an error status code or printing 77 | the response body for debugging purposes. 78 | 79 | Additional Information 80 | 81 | See the Elasticsearch documentation at 82 | https://www.elastic.co/guide/en/elasticsearch/reference/master/api-conventions.html for detailed information 83 | about the API endpoints and parameters. 84 | 85 | The Go API is generated from the Elasticsearch JSON specification at 86 | https://github.com/elastic/elasticsearch/tree/master/rest-api-spec/src/main/resources/rest-api-spec/api 87 | by the internal package available at 88 | https://github.com/elastic/go-elasticsearch/tree/master/internal/cmd/generate/commands/gensource. 89 | 90 | The API is tested by integration tests common to all Elasticsearch official clients, generated from the 91 | source at https://github.com/elastic/elasticsearch/tree/master/rest-api-spec/src/main/resources/rest-api-spec/test. 92 | The generator is provided by the internal package available at internal/cmd/generate/commands/gentests. 93 | 94 | */ 95 | package esapi 96 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/connector.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "context" 5 | "database/sql/driver" 6 | "errors" 7 | "fmt" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | // Connector represents a fixed configuration for the pq driver with a given 13 | // name. Connector satisfies the database/sql/driver Connector interface and 14 | // can be used to create any number of DB Conn's via the database/sql OpenDB 15 | // function. 16 | // 17 | // See https://golang.org/pkg/database/sql/driver/#Connector. 18 | // See https://golang.org/pkg/database/sql/#OpenDB. 19 | type Connector struct { 20 | opts values 21 | dialer Dialer 22 | } 23 | 24 | // Connect returns a connection to the database using the fixed configuration 25 | // of this Connector. Context is not used. 26 | func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) { 27 | return c.open(ctx) 28 | } 29 | 30 | // Driver returnst the underlying driver of this Connector. 31 | func (c *Connector) Driver() driver.Driver { 32 | return &Driver{} 33 | } 34 | 35 | // NewConnector returns a connector for the pq driver in a fixed configuration 36 | // with the given dsn. The returned connector can be used to create any number 37 | // of equivalent Conn's. The returned connector is intended to be used with 38 | // database/sql.OpenDB. 39 | // 40 | // See https://golang.org/pkg/database/sql/driver/#Connector. 41 | // See https://golang.org/pkg/database/sql/#OpenDB. 42 | func NewConnector(dsn string) (*Connector, error) { 43 | var err error 44 | o := make(values) 45 | 46 | // A number of defaults are applied here, in this order: 47 | // 48 | // * Very low precedence defaults applied in every situation 49 | // * Environment variables 50 | // * Explicitly passed connection information 51 | o["host"] = "localhost" 52 | o["port"] = "5432" 53 | // N.B.: Extra float digits should be set to 3, but that breaks 54 | // Postgres 8.4 and older, where the max is 2. 55 | o["extra_float_digits"] = "2" 56 | for k, v := range parseEnviron(os.Environ()) { 57 | o[k] = v 58 | } 59 | 60 | if strings.HasPrefix(dsn, "postgres://") || strings.HasPrefix(dsn, "postgresql://") { 61 | dsn, err = ParseURL(dsn) 62 | if err != nil { 63 | return nil, err 64 | } 65 | } 66 | 67 | if err := parseOpts(dsn, o); err != nil { 68 | return nil, err 69 | } 70 | 71 | // Use the "fallback" application name if necessary 72 | if fallback, ok := o["fallback_application_name"]; ok { 73 | if _, ok := o["application_name"]; !ok { 74 | o["application_name"] = fallback 75 | } 76 | } 77 | 78 | // We can't work with any client_encoding other than UTF-8 currently. 79 | // However, we have historically allowed the user to set it to UTF-8 80 | // explicitly, and there's no reason to break such programs, so allow that. 81 | // Note that the "options" setting could also set client_encoding, but 82 | // parsing its value is not worth it. Instead, we always explicitly send 83 | // client_encoding as a separate run-time parameter, which should override 84 | // anything set in options. 85 | if enc, ok := o["client_encoding"]; ok && !isUTF8(enc) { 86 | return nil, errors.New("client_encoding must be absent or 'UTF8'") 87 | } 88 | o["client_encoding"] = "UTF8" 89 | // DateStyle needs a similar treatment. 90 | if datestyle, ok := o["datestyle"]; ok { 91 | if datestyle != "ISO, MDY" { 92 | return nil, fmt.Errorf("setting datestyle must be absent or %v; got %v", "ISO, MDY", datestyle) 93 | } 94 | } else { 95 | o["datestyle"] = "ISO, MDY" 96 | } 97 | 98 | // If a user is not provided by any other means, the last 99 | // resort is to use the current operating system provided user 100 | // name. 101 | if _, ok := o["user"]; !ok { 102 | u, err := userCurrent() 103 | if err != nil { 104 | return nil, err 105 | } 106 | o["user"] = u 107 | } 108 | 109 | return &Connector{opts: o, dialer: defaultDialer{}}, nil 110 | } 111 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/compression.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "compress/flate" 9 | "errors" 10 | "io" 11 | "strings" 12 | "sync" 13 | ) 14 | 15 | const ( 16 | minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 17 | maxCompressionLevel = flate.BestCompression 18 | defaultCompressionLevel = 1 19 | ) 20 | 21 | var ( 22 | flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool 23 | flateReaderPool = sync.Pool{New: func() interface{} { 24 | return flate.NewReader(nil) 25 | }} 26 | ) 27 | 28 | func decompressNoContextTakeover(r io.Reader) io.ReadCloser { 29 | const tail = 30 | // Add four bytes as specified in RFC 31 | "\x00\x00\xff\xff" + 32 | // Add final block to squelch unexpected EOF error from flate reader. 33 | "\x01\x00\x00\xff\xff" 34 | 35 | fr, _ := flateReaderPool.Get().(io.ReadCloser) 36 | fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) 37 | return &flateReadWrapper{fr} 38 | } 39 | 40 | func isValidCompressionLevel(level int) bool { 41 | return minCompressionLevel <= level && level <= maxCompressionLevel 42 | } 43 | 44 | func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { 45 | p := &flateWriterPools[level-minCompressionLevel] 46 | tw := &truncWriter{w: w} 47 | fw, _ := p.Get().(*flate.Writer) 48 | if fw == nil { 49 | fw, _ = flate.NewWriter(tw, level) 50 | } else { 51 | fw.Reset(tw) 52 | } 53 | return &flateWriteWrapper{fw: fw, tw: tw, p: p} 54 | } 55 | 56 | // truncWriter is an io.Writer that writes all but the last four bytes of the 57 | // stream to another io.Writer. 58 | type truncWriter struct { 59 | w io.WriteCloser 60 | n int 61 | p [4]byte 62 | } 63 | 64 | func (w *truncWriter) Write(p []byte) (int, error) { 65 | n := 0 66 | 67 | // fill buffer first for simplicity. 68 | if w.n < len(w.p) { 69 | n = copy(w.p[w.n:], p) 70 | p = p[n:] 71 | w.n += n 72 | if len(p) == 0 { 73 | return n, nil 74 | } 75 | } 76 | 77 | m := len(p) 78 | if m > len(w.p) { 79 | m = len(w.p) 80 | } 81 | 82 | if nn, err := w.w.Write(w.p[:m]); err != nil { 83 | return n + nn, err 84 | } 85 | 86 | copy(w.p[:], w.p[m:]) 87 | copy(w.p[len(w.p)-m:], p[len(p)-m:]) 88 | nn, err := w.w.Write(p[:len(p)-m]) 89 | return n + nn, err 90 | } 91 | 92 | type flateWriteWrapper struct { 93 | fw *flate.Writer 94 | tw *truncWriter 95 | p *sync.Pool 96 | } 97 | 98 | func (w *flateWriteWrapper) Write(p []byte) (int, error) { 99 | if w.fw == nil { 100 | return 0, errWriteClosed 101 | } 102 | return w.fw.Write(p) 103 | } 104 | 105 | func (w *flateWriteWrapper) Close() error { 106 | if w.fw == nil { 107 | return errWriteClosed 108 | } 109 | err1 := w.fw.Flush() 110 | w.p.Put(w.fw) 111 | w.fw = nil 112 | if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { 113 | return errors.New("websocket: internal error, unexpected bytes at end of flate stream") 114 | } 115 | err2 := w.tw.w.Close() 116 | if err1 != nil { 117 | return err1 118 | } 119 | return err2 120 | } 121 | 122 | type flateReadWrapper struct { 123 | fr io.ReadCloser 124 | } 125 | 126 | func (r *flateReadWrapper) Read(p []byte) (int, error) { 127 | if r.fr == nil { 128 | return 0, io.ErrClosedPipe 129 | } 130 | n, err := r.fr.Read(p) 131 | if err == io.EOF { 132 | // Preemptively place the reader back in the pool. This helps with 133 | // scenarios where the application does not call NextReader() soon after 134 | // this final read. 135 | r.Close() 136 | } 137 | return n, err 138 | } 139 | 140 | func (r *flateReadWrapper) Close() error { 141 | if r.fr == nil { 142 | return io.ErrClosedPipe 143 | } 144 | err := r.fr.Close() 145 | flateReaderPool.Put(r.fr) 146 | r.fr = nil 147 | return err 148 | } 149 | -------------------------------------------------------------------------------- /vendor/github.com/lib/pq/conn_go18.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "database/sql/driver" 7 | "fmt" 8 | "io" 9 | "io/ioutil" 10 | "time" 11 | ) 12 | 13 | // Implement the "QueryerContext" interface 14 | func (cn *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { 15 | list := make([]driver.Value, len(args)) 16 | for i, nv := range args { 17 | list[i] = nv.Value 18 | } 19 | finish := cn.watchCancel(ctx) 20 | r, err := cn.query(query, list) 21 | if err != nil { 22 | if finish != nil { 23 | finish() 24 | } 25 | return nil, err 26 | } 27 | r.finish = finish 28 | return r, nil 29 | } 30 | 31 | // Implement the "ExecerContext" interface 32 | func (cn *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { 33 | list := make([]driver.Value, len(args)) 34 | for i, nv := range args { 35 | list[i] = nv.Value 36 | } 37 | 38 | if finish := cn.watchCancel(ctx); finish != nil { 39 | defer finish() 40 | } 41 | 42 | return cn.Exec(query, list) 43 | } 44 | 45 | // Implement the "ConnBeginTx" interface 46 | func (cn *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { 47 | var mode string 48 | 49 | switch sql.IsolationLevel(opts.Isolation) { 50 | case sql.LevelDefault: 51 | // Don't touch mode: use the server's default 52 | case sql.LevelReadUncommitted: 53 | mode = " ISOLATION LEVEL READ UNCOMMITTED" 54 | case sql.LevelReadCommitted: 55 | mode = " ISOLATION LEVEL READ COMMITTED" 56 | case sql.LevelRepeatableRead: 57 | mode = " ISOLATION LEVEL REPEATABLE READ" 58 | case sql.LevelSerializable: 59 | mode = " ISOLATION LEVEL SERIALIZABLE" 60 | default: 61 | return nil, fmt.Errorf("pq: isolation level not supported: %d", opts.Isolation) 62 | } 63 | 64 | if opts.ReadOnly { 65 | mode += " READ ONLY" 66 | } else { 67 | mode += " READ WRITE" 68 | } 69 | 70 | tx, err := cn.begin(mode) 71 | if err != nil { 72 | return nil, err 73 | } 74 | cn.txnFinish = cn.watchCancel(ctx) 75 | return tx, nil 76 | } 77 | 78 | func (cn *conn) Ping(ctx context.Context) error { 79 | if finish := cn.watchCancel(ctx); finish != nil { 80 | defer finish() 81 | } 82 | rows, err := cn.simpleQuery(";") 83 | if err != nil { 84 | return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger 85 | } 86 | rows.Close() 87 | return nil 88 | } 89 | 90 | func (cn *conn) watchCancel(ctx context.Context) func() { 91 | if done := ctx.Done(); done != nil { 92 | finished := make(chan struct{}) 93 | go func() { 94 | select { 95 | case <-done: 96 | // At this point the function level context is canceled, 97 | // so it must not be used for the additional network 98 | // request to cancel the query. 99 | // Create a new context to pass into the dial. 100 | ctxCancel, cancel := context.WithTimeout(context.Background(), time.Second*10) 101 | defer cancel() 102 | 103 | _ = cn.cancel(ctxCancel) 104 | finished <- struct{}{} 105 | case <-finished: 106 | } 107 | }() 108 | return func() { 109 | select { 110 | case <-finished: 111 | case finished <- struct{}{}: 112 | } 113 | } 114 | } 115 | return nil 116 | } 117 | 118 | func (cn *conn) cancel(ctx context.Context) error { 119 | c, err := dial(ctx, cn.dialer, cn.opts) 120 | if err != nil { 121 | return err 122 | } 123 | defer c.Close() 124 | 125 | { 126 | can := conn{ 127 | c: c, 128 | } 129 | err = can.ssl(cn.opts) 130 | if err != nil { 131 | return err 132 | } 133 | 134 | w := can.writeBuf(0) 135 | w.int32(80877102) // cancel request code 136 | w.int32(cn.processID) 137 | w.int32(cn.secretKey) 138 | 139 | if err := can.sendStartupPacket(w); err != nil { 140 | return err 141 | } 142 | } 143 | 144 | // Read until EOF to ensure that the server received the cancel. 145 | { 146 | _, err := io.Copy(ioutil.Discard, c) 147 | return err 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nuid/nuid.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016-2019 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // A unique identifier generator that is high performance, very fast, and tries to be entropy pool friendly. 15 | package nuid 16 | 17 | import ( 18 | "crypto/rand" 19 | "fmt" 20 | "math" 21 | "math/big" 22 | "sync" 23 | "time" 24 | 25 | prand "math/rand" 26 | ) 27 | 28 | // NUID needs to be very fast to generate and truly unique, all while being entropy pool friendly. 29 | // We will use 12 bytes of crypto generated data (entropy draining), and 10 bytes of sequential data 30 | // that is started at a pseudo random number and increments with a pseudo-random increment. 31 | // Total is 22 bytes of base 62 ascii text :) 32 | 33 | // Version of the library 34 | const Version = "1.0.1" 35 | 36 | const ( 37 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 38 | base = 62 39 | preLen = 12 40 | seqLen = 10 41 | maxSeq = int64(839299365868340224) // base^seqLen == 62^10 42 | minInc = int64(33) 43 | maxInc = int64(333) 44 | totalLen = preLen + seqLen 45 | ) 46 | 47 | type NUID struct { 48 | pre []byte 49 | seq int64 50 | inc int64 51 | } 52 | 53 | type lockedNUID struct { 54 | sync.Mutex 55 | *NUID 56 | } 57 | 58 | // Global NUID 59 | var globalNUID *lockedNUID 60 | 61 | // Seed sequential random with crypto or math/random and current time 62 | // and generate crypto prefix. 63 | func init() { 64 | r, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) 65 | if err != nil { 66 | prand.Seed(time.Now().UnixNano()) 67 | } else { 68 | prand.Seed(r.Int64()) 69 | } 70 | globalNUID = &lockedNUID{NUID: New()} 71 | globalNUID.RandomizePrefix() 72 | } 73 | 74 | // New will generate a new NUID and properly initialize the prefix, sequential start, and sequential increment. 75 | func New() *NUID { 76 | n := &NUID{ 77 | seq: prand.Int63n(maxSeq), 78 | inc: minInc + prand.Int63n(maxInc-minInc), 79 | pre: make([]byte, preLen), 80 | } 81 | n.RandomizePrefix() 82 | return n 83 | } 84 | 85 | // Generate the next NUID string from the global locked NUID instance. 86 | func Next() string { 87 | globalNUID.Lock() 88 | nuid := globalNUID.Next() 89 | globalNUID.Unlock() 90 | return nuid 91 | } 92 | 93 | // Generate the next NUID string. 94 | func (n *NUID) Next() string { 95 | // Increment and capture. 96 | n.seq += n.inc 97 | if n.seq >= maxSeq { 98 | n.RandomizePrefix() 99 | n.resetSequential() 100 | } 101 | seq := n.seq 102 | 103 | // Copy prefix 104 | var b [totalLen]byte 105 | bs := b[:preLen] 106 | copy(bs, n.pre) 107 | 108 | // copy in the seq in base62. 109 | for i, l := len(b), seq; i > preLen; l /= base { 110 | i -= 1 111 | b[i] = digits[l%base] 112 | } 113 | return string(b[:]) 114 | } 115 | 116 | // Resets the sequential portion of the NUID. 117 | func (n *NUID) resetSequential() { 118 | n.seq = prand.Int63n(maxSeq) 119 | n.inc = minInc + prand.Int63n(maxInc-minInc) 120 | } 121 | 122 | // Generate a new prefix from crypto/rand. 123 | // This call *can* drain entropy and will be called automatically when we exhaust the sequential range. 124 | // Will panic if it gets an error from rand.Int() 125 | func (n *NUID) RandomizePrefix() { 126 | var cb [preLen]byte 127 | cbs := cb[:] 128 | if nb, err := rand.Read(cbs); nb != preLen || err != nil { 129 | panic(fmt.Sprintf("nuid: failed generating crypto random number: %v\n", err)) 130 | } 131 | 132 | for i := 0; i < preLen; i++ { 133 | n.pre[i] = digits[int(cbs[i])%base] 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nkeys/README.md: -------------------------------------------------------------------------------- 1 | # NKEYS 2 | 3 | [![License Apache 2](https://img.shields.io/badge/License-Apache2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) 4 | [![ReportCard](http://goreportcard.com/badge/nats-io/nkeys)](http://goreportcard.com/report/nats-io/nkeys) 5 | [![Build Status](https://travis-ci.org/nats-io/nkeys.svg?branch=master)](http://travis-ci.org/nats-io/nkeys) 6 | [![GoDoc](http://godoc.org/github.com/nats-io/nkeys?status.svg)](http://godoc.org/github.com/nats-io/nkeys) 7 | [![Coverage Status](https://coveralls.io/repos/github/nats-io/nkeys/badge.svg?branch=master&service=github)](https://coveralls.io/github/nats-io/nkeys?branch=master) 8 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnats-io%2Fnkeys.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnats-io%2Fnkeys?ref=badge_shield) 9 | 10 | A public-key signature system based on [Ed25519](https://ed25519.cr.yp.to/) for the NATS ecosystem. 11 | 12 | ## About 13 | 14 | The NATS ecosystem will be moving to [Ed25519](https://ed25519.cr.yp.to/) keys for identity, authentication and authorization for entities such as Accounts, Users, Servers and Clusters. 15 | 16 | Ed25519 is fast and resistant to side channel attacks. Generation of a seed key is all that is needed to be stored and kept safe, as the seed can generate both the public and private keys. 17 | 18 | The NATS system will utilize Ed25519 keys, meaning that NATS systems will never store or even have access to any private keys. Authentication will utilize a random challenge response mechanism. 19 | 20 | Dealing with 32 byte and 64 byte raw keys can be challenging. NKEYS is designed to formulate keys in a much friendlier fashion and references work done in cryptocurrencies, specifically [Stellar](https://www.stellar.org/). Bitcoin and others used a form of Base58 (or Base58Check) to endode raw keys. Stellar utilized a more traditonal Base32 with a CRC16 and a version or prefix byte. NKEYS utilizes a similar format where the prefix will be 1 byte for public and private keys and will be 2 bytes for seeds. The base32 encoding of these prefixes will yield friendly human readbable prefixes, e.g. '**N**' = server, '**C**' = cluster, '**O**' = operator, '**A**' = account, and '**U**' = user. '**P**' is used for private keys. For seeds, the first encoded prefix is '**S**', and the second character will be the type for the public key, e.g. "**SU**" is a seed for a user key pair, "**SA**" is a seed for an account key pair. 21 | 22 | ## Installation 23 | 24 | Use the `go` command: 25 | 26 | $ go get github.com/nats-io/nkeys 27 | 28 | ## nk - Command Line Utility 29 | 30 | Located under the nk [directory](https://github.com/nats-io/nkeys/tree/master/nk). 31 | 32 | ## Basic API Usage 33 | ```go 34 | 35 | // Create a new User KeyPair 36 | user, _ := nkeys.CreateUser() 37 | 38 | // Sign some data with a full key pair user. 39 | data := []byte("Hello World") 40 | sig, _ := user.Sign(data) 41 | 42 | // Verify the signature. 43 | err = user.Verify(data, sig) 44 | 45 | // Access the seed, the only thing that needs to be stored and kept safe. 46 | // seed = "SUAKYRHVIOREXV7EUZTBHUHL7NUMHPMAS7QMDU3GTIUWEI5LDNOXD43IZY" 47 | seed, _ := user.Seed() 48 | 49 | // Access the public key which can be shared. 50 | // publicKey = "UD466L6EBCM3YY5HEGHJANNTN4LSKTSUXTH7RILHCKEQMQHTBNLHJJXT" 51 | publicKey, _ := user.PublicKey() 52 | 53 | // Create a full User who can sign and verify from a private seed. 54 | user, _ = nkeys.FromSeed(seed) 55 | 56 | // Create a User who can only verify signatures via a public key. 57 | user, _ = nkeys.FromPublicKey(publicKey) 58 | 59 | // Create a User KeyPair with our own random data. 60 | var rawSeed [32]byte 61 | _, err := io.ReadFull(rand.Reader, rawSeed[:]) // Or some other random source. 62 | user2, _ := nkeys.FromRawSeed(PrefixByteUser, rawSeed) 63 | 64 | ``` 65 | 66 | ## License 67 | 68 | Unless otherwise noted, the NATS source files are distributed 69 | under the Apache Version 2.0 license found in the LICENSE file. 70 | 71 | 72 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnats-io%2Fnkeys.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnats-io%2Fnkeys?ref=badge_large) -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/README.md: -------------------------------------------------------------------------------- 1 | # Gorilla WebSocket 2 | 3 | [![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) 4 | [![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket) 5 | 6 | Gorilla WebSocket is a [Go](http://golang.org/) implementation of the 7 | [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. 8 | 9 | ### Documentation 10 | 11 | * [API Reference](http://godoc.org/github.com/gorilla/websocket) 12 | * [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) 13 | * [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) 14 | * [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) 15 | * [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) 16 | 17 | ### Status 18 | 19 | The Gorilla WebSocket package provides a complete and tested implementation of 20 | the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The 21 | package API is stable. 22 | 23 | ### Installation 24 | 25 | go get github.com/gorilla/websocket 26 | 27 | ### Protocol Compliance 28 | 29 | The Gorilla WebSocket package passes the server tests in the [Autobahn Test 30 | Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn 31 | subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). 32 | 33 | ### Gorilla WebSocket compared with other packages 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Compression ExtensionsExperimentalNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
53 | 54 | Notes: 55 | 56 | 1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). 57 | 2. The application can get the type of a received data message by implementing 58 | a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) 59 | function. 60 | 3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. 61 | Read returns when the input buffer is full or a frame boundary is 62 | encountered. Each call to Write sends a single frame message. The Gorilla 63 | io.Reader and io.WriteCloser operate on a single WebSocket message. 64 | 65 | -------------------------------------------------------------------------------- /vendor/github.com/nats-io/nats.go/netchan.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013-2018 The NATS Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nats 15 | 16 | import ( 17 | "errors" 18 | "reflect" 19 | ) 20 | 21 | // This allows the functionality for network channels by binding send and receive Go chans 22 | // to subjects and optionally queue groups. 23 | // Data will be encoded and decoded via the EncodedConn and its associated encoders. 24 | 25 | // BindSendChan binds a channel for send operations to NATS. 26 | func (c *EncodedConn) BindSendChan(subject string, channel interface{}) error { 27 | chVal := reflect.ValueOf(channel) 28 | if chVal.Kind() != reflect.Chan { 29 | return ErrChanArg 30 | } 31 | go chPublish(c, chVal, subject) 32 | return nil 33 | } 34 | 35 | // Publish all values that arrive on the channel until it is closed or we 36 | // encounter an error. 37 | func chPublish(c *EncodedConn, chVal reflect.Value, subject string) { 38 | for { 39 | val, ok := chVal.Recv() 40 | if !ok { 41 | // Channel has most likely been closed. 42 | return 43 | } 44 | if e := c.Publish(subject, val.Interface()); e != nil { 45 | // Do this under lock. 46 | c.Conn.mu.Lock() 47 | defer c.Conn.mu.Unlock() 48 | 49 | if c.Conn.Opts.AsyncErrorCB != nil { 50 | // FIXME(dlc) - Not sure this is the right thing to do. 51 | // FIXME(ivan) - If the connection is not yet closed, try to schedule the callback 52 | if c.Conn.isClosed() { 53 | go c.Conn.Opts.AsyncErrorCB(c.Conn, nil, e) 54 | } else { 55 | c.Conn.ach.push(func() { c.Conn.Opts.AsyncErrorCB(c.Conn, nil, e) }) 56 | } 57 | } 58 | return 59 | } 60 | } 61 | } 62 | 63 | // BindRecvChan binds a channel for receive operations from NATS. 64 | func (c *EncodedConn) BindRecvChan(subject string, channel interface{}) (*Subscription, error) { 65 | return c.bindRecvChan(subject, _EMPTY_, channel) 66 | } 67 | 68 | // BindRecvQueueChan binds a channel for queue-based receive operations from NATS. 69 | func (c *EncodedConn) BindRecvQueueChan(subject, queue string, channel interface{}) (*Subscription, error) { 70 | return c.bindRecvChan(subject, queue, channel) 71 | } 72 | 73 | // Internal function to bind receive operations for a channel. 74 | func (c *EncodedConn) bindRecvChan(subject, queue string, channel interface{}) (*Subscription, error) { 75 | chVal := reflect.ValueOf(channel) 76 | if chVal.Kind() != reflect.Chan { 77 | return nil, ErrChanArg 78 | } 79 | argType := chVal.Type().Elem() 80 | 81 | cb := func(m *Msg) { 82 | var oPtr reflect.Value 83 | if argType.Kind() != reflect.Ptr { 84 | oPtr = reflect.New(argType) 85 | } else { 86 | oPtr = reflect.New(argType.Elem()) 87 | } 88 | if err := c.Enc.Decode(m.Subject, m.Data, oPtr.Interface()); err != nil { 89 | c.Conn.err = errors.New("nats: Got an error trying to unmarshal: " + err.Error()) 90 | if c.Conn.Opts.AsyncErrorCB != nil { 91 | c.Conn.ach.push(func() { c.Conn.Opts.AsyncErrorCB(c.Conn, m.Sub, c.Conn.err) }) 92 | } 93 | return 94 | } 95 | if argType.Kind() != reflect.Ptr { 96 | oPtr = reflect.Indirect(oPtr) 97 | } 98 | // This is a bit hacky, but in this instance we may be trying to send to a closed channel. 99 | // and the user does not know when it is safe to close the channel. 100 | defer func() { 101 | // If we have panicked, recover and close the subscription. 102 | if r := recover(); r != nil { 103 | m.Sub.Unsubscribe() 104 | } 105 | }() 106 | // Actually do the send to the channel. 107 | chVal.Send(oPtr) 108 | } 109 | 110 | return c.Conn.subscribe(subject, queue, cb, nil, false) 111 | } 112 | --------------------------------------------------------------------------------