Update vendor and makefile
Change-Id: I25bd3edf05652c1215eba4d98a965bee310c99f8
This commit is contained in:
parent
0ff4a00a71
commit
f3545f50a4
@ -1,6 +1,6 @@
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery",
|
||||
"GoVersion": "go1.7",
|
||||
"ImportPath": "github.com/openstack/stackube",
|
||||
"GoVersion": "go1.8",
|
||||
"GodepVersion": "v79",
|
||||
"Packages": [
|
||||
"./..."
|
||||
@ -15,23 +15,6 @@
|
||||
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/spdystream",
|
||||
"Rev": "449fdfce4d962303d702fec724ef0ad181c92528"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/spdystream/spdy",
|
||||
"Rev": "449fdfce4d962303d702fec724ef0ad181c92528"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/elazarl/goproxy",
|
||||
"Comment": "v1.0-104-gc4fc265",
|
||||
"Rev": "c4fc26588b6ef8af07a191fcb6476387bdd46711"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/emicklei/go-restful",
|
||||
"Comment": "2.2.0-4-gff4f55a",
|
||||
@ -42,14 +25,6 @@
|
||||
"Comment": "2.2.0-4-gff4f55a",
|
||||
"Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/evanphx/json-patch",
|
||||
"Rev": "ba18e35c5c1b36ef6334cad706eb681153d2d379"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ghodss/yaml",
|
||||
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/jsonpointer",
|
||||
"Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98"
|
||||
@ -80,26 +55,10 @@
|
||||
"ImportPath": "github.com/golang/glog",
|
||||
"Rev": "44145f04b68cf362d9c4df2182967c2275eaefed"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/groupcache/lru",
|
||||
"Rev": "02826c3e79038b59d737d3b1c0a1d937f71a4433"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "4bd1920723d7b7c925de087aa32e2187708897f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/gofuzz",
|
||||
"Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/golang-lru/simplelru",
|
||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/buffer",
|
||||
"Rev": "d5b7844b561a7bc640052f1b935f7b800330d7e0"
|
||||
@ -112,18 +71,10 @@
|
||||
"ImportPath": "github.com/mailru/easyjson/jwriter",
|
||||
"Rev": "d5b7844b561a7bc640052f1b935f7b800330d7e0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pborman/uuid",
|
||||
"Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ugorji/go/codec",
|
||||
"Rev": "ded73eae5db7e7a0ef6f55aace87a2873c5d2b74"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/http2",
|
||||
"Rev": "f2499483f923065a842d38eb4c7f1927e6fc6e6d"
|
||||
@ -186,8 +137,84 @@
|
||||
"Rev": "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/yaml.v2",
|
||||
"Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/openapi",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||
"Rev": "2de00c78cb6d6127fb51b9531c1b3def1cbcac8c"
|
||||
}
|
||||
]
|
||||
}
|
10
Makefile
10
Makefile
@ -12,7 +12,7 @@ BASE_DIR := $(shell basename $(PWD))
|
||||
# Keep an existing GOPATH, make a private one if it is undefined
|
||||
GOPATH_DEFAULT := $(PWD)/.go
|
||||
export GOPATH ?= $(GOPATH_DEFAULT)
|
||||
PKG := $(shell awk '/^package: / { print $$2 }' glide.yaml)
|
||||
PKG := git.openstack.org/openstack/stackube
|
||||
DEST := $(GOPATH)/src/$(PKG)
|
||||
|
||||
GOFLAGS :=
|
||||
@ -27,19 +27,19 @@ all: build
|
||||
|
||||
.PHONY: depend
|
||||
depend: work
|
||||
cd $(DEST) && glide install
|
||||
# cd $(DEST) && glide install
|
||||
|
||||
.PHONY: depend-update
|
||||
depend-update: work
|
||||
cd $(DEST) && glide update
|
||||
# cd $(DEST) && glide update
|
||||
|
||||
.PHONY: build
|
||||
build: depend
|
||||
cd $(DEST) && go build $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)'' ./...
|
||||
cd $(DEST) && go build $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./...
|
||||
|
||||
.PHONY: install
|
||||
install: depend
|
||||
cd $(DEST) && go install $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)'' ./...
|
||||
cd $(DEST) && go install $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./...
|
||||
|
||||
.PHONY: test
|
||||
test: test-unit
|
||||
|
98
glide.lock
generated
98
glide.lock
generated
@ -1,98 +0,0 @@
|
||||
hash: aa28871e98a60b6b588574caba38da993b57576bdeb7beba3d65a8d41c585775
|
||||
updated: 2017-06-01T14:59:16.583022179+08:00
|
||||
imports:
|
||||
- name: github.com/emicklei/go-restful
|
||||
version: ff4f55a206334ef123e4f79bbf348980da81ca46
|
||||
subpackages:
|
||||
- log
|
||||
- name: github.com/emicklei/go-restful-swagger12
|
||||
version: dcef7f55730566d41eae5db10e7d6981829720f6
|
||||
- name: github.com/go-openapi/jsonpointer
|
||||
version: 46af16f9f7b149af66e5d1bd010e3574dc06de98
|
||||
- name: github.com/go-openapi/jsonreference
|
||||
version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272
|
||||
- name: github.com/go-openapi/spec
|
||||
version: 6aced65f8501fe1217321abf0749d354824ba2ff
|
||||
- name: github.com/go-openapi/swag
|
||||
version: 1d0bd113de87027671077d3c71eb3ac5d7dbba72
|
||||
- name: github.com/gogo/protobuf
|
||||
version: c0656edd0d9eab7c66d1eb0c568f9039345796f7
|
||||
subpackages:
|
||||
- proto
|
||||
- sortkeys
|
||||
- name: github.com/golang/glog
|
||||
version: 44145f04b68cf362d9c4df2182967c2275eaefed
|
||||
- name: github.com/google/gofuzz
|
||||
version: 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
||||
- name: github.com/mailru/easyjson
|
||||
version: d5b7844b561a7bc640052f1b935f7b800330d7e0
|
||||
subpackages:
|
||||
- buffer
|
||||
- jlexer
|
||||
- jwriter
|
||||
- name: github.com/mjibson/appstats
|
||||
version: 0542d5f0e87ea3a8fa4174322b9532f5d04f9fa8
|
||||
- name: github.com/PuerkitoBio/purell
|
||||
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
|
||||
- name: github.com/PuerkitoBio/urlesc
|
||||
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
|
||||
- name: github.com/spf13/pflag
|
||||
version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
|
||||
- name: golang.org/x/crypto
|
||||
version: 080743b21912ae11ad9222778a048b795a5aae00
|
||||
subpackages:
|
||||
- ssh/terminal
|
||||
- name: golang.org/x/net
|
||||
version: f2499483f923065a842d38eb4c7f1927e6fc6e6d
|
||||
subpackages:
|
||||
- http2
|
||||
- http2/hpack
|
||||
- idna
|
||||
- lex/httplex
|
||||
- name: golang.org/x/text
|
||||
version: 2910a502d2bf9e43193af9d68ca516529614eed3
|
||||
subpackages:
|
||||
- cases
|
||||
- internal/tag
|
||||
- language
|
||||
- runes
|
||||
- secure/bidirule
|
||||
- secure/precis
|
||||
- transform
|
||||
- unicode/bidi
|
||||
- unicode/norm
|
||||
- width
|
||||
- name: google.golang.org/appengine
|
||||
version: 150dc57a1b433e64154302bdc40b6bb8aefa313a
|
||||
subpackages:
|
||||
- datastore
|
||||
- memcache
|
||||
- user
|
||||
- name: gopkg.in/inf.v0
|
||||
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||
- name: gopkg.in/vmihailenco/msgpack.v2
|
||||
version: f4f8982de4ef0de18be76456617cc3f5d8d8141e
|
||||
- name: k8s.io/apimachinery
|
||||
version: 2de00c78cb6d6127fb51b9531c1b3def1cbcac8c
|
||||
subpackages:
|
||||
- pkg/api/resource
|
||||
- pkg/apis/meta/v1
|
||||
- pkg/conversion
|
||||
- pkg/conversion/queryparams
|
||||
- pkg/fields
|
||||
- pkg/labels
|
||||
- pkg/openapi
|
||||
- pkg/runtime
|
||||
- pkg/runtime/schema
|
||||
- pkg/selection
|
||||
- pkg/types
|
||||
- pkg/util/errors
|
||||
- pkg/util/intstr
|
||||
- pkg/util/net
|
||||
- pkg/util/runtime
|
||||
- pkg/util/sets
|
||||
- pkg/util/validation
|
||||
- pkg/util/wait
|
||||
- pkg/watch
|
||||
- third_party/forked/golang/reflect
|
||||
testImports: []
|
21
glide.yaml
21
glide.yaml
@ -1,21 +0,0 @@
|
||||
package: git.openstack.org/openstack/stackube
|
||||
import:
|
||||
- package: k8s.io/apimachinery
|
||||
subpackages:
|
||||
- pkg/apis/meta/v1
|
||||
- pkg/runtime
|
||||
- pkg/runtime/schema
|
||||
- package: github.com/emicklei/go-restful-swagger12
|
||||
version: 1.0.1
|
||||
- package: github.com/mjibson/appstats
|
||||
- package: google.golang.org/appengine
|
||||
version: v1.0.0
|
||||
subpackages:
|
||||
- memcache
|
||||
- datastore
|
||||
- user
|
||||
- package: gopkg.in/vmihailenco/msgpack.v2
|
||||
version: v2.9.1
|
||||
- package: golang.org/x/crypto
|
||||
subpackages:
|
||||
- ssh/terminal
|
@ -3,7 +3,7 @@
|
||||
# Used in both CI jobs and locally
|
||||
#
|
||||
# Install the following tools:
|
||||
# * glide
|
||||
# * godep
|
||||
|
||||
# Get OS
|
||||
case $(uname -s) in
|
||||
@ -31,24 +31,10 @@ case $(uname -s) in
|
||||
;;
|
||||
esac
|
||||
|
||||
case $OS in
|
||||
darwin)
|
||||
if which brew 1>/dev/null; then
|
||||
if ! which glide 1>/dev/null; then
|
||||
brew install glide
|
||||
fi
|
||||
else
|
||||
echo "Homebrew not found, install Glide from source?"
|
||||
fi
|
||||
;;
|
||||
xenial)
|
||||
APT_GET="DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get -q --option "Dpkg::Options::=--force-confold" \
|
||||
--assume-yes"
|
||||
if ! which add-apt-repository 1>/dev/null; then
|
||||
sudo $APT_GET install software-properties-common
|
||||
fi
|
||||
sudo add-apt-repository --yes ppa:masterminds/glide && sudo apt-get update
|
||||
sudo $APT_GET install glide
|
||||
;;
|
||||
esac
|
||||
if which go 1>/dev/null; then
|
||||
if ! which go 1>/dev/null; then
|
||||
go get -u -v github.com/tools/godep
|
||||
fi
|
||||
else
|
||||
echo "go not found, install golang from source?"
|
||||
fi
|
||||
|
57
vendor/github.com/PuerkitoBio/purell/bench_test.go
generated
vendored
57
vendor/github.com/PuerkitoBio/purell/bench_test.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
package purell
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
safeUrl = "HttPS://..iaMHost..Test:443/paTh^A%ef//./%41PaTH/..//?"
|
||||
usuallySafeUrl = "HttPS://..iaMHost..Test:443/paTh^A%ef//./%41PaTH/../final/"
|
||||
unsafeUrl = "HttPS://..www.iaMHost..Test:443/paTh^A%ef//./%41PaTH/../final/index.html?t=val1&a=val4&z=val5&a=val1#fragment"
|
||||
allDWORDUrl = "HttPS://1113982867:/paTh^A%ef//./%41PaTH/../final/index.html?t=val1&a=val4&z=val5&a=val1#fragment"
|
||||
allOctalUrl = "HttPS://0102.0146.07.0223:/paTh^A%ef//./%41PaTH/../final/index.html?t=val1&a=val4&z=val5&a=val1#fragment"
|
||||
allHexUrl = "HttPS://0x42660793:/paTh^A%ef//./%41PaTH/../final/index.html?t=val1&a=val4&z=val5&a=val1#fragment"
|
||||
allCombinedUrl = "HttPS://..0x42660793.:/paTh^A%ef//./%41PaTH/../final/index.html?t=val1&a=val4&z=val5&a=val1#fragment"
|
||||
)
|
||||
|
||||
func BenchmarkSafe(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(safeUrl, FlagsSafe)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUsuallySafe(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(usuallySafeUrl, FlagsUsuallySafeGreedy)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnsafe(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(unsafeUrl, FlagsUnsafeGreedy)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAllDWORD(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(allDWORDUrl, FlagsAllGreedy)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAllOctal(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(allOctalUrl, FlagsAllGreedy)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAllHex(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(allHexUrl, FlagsAllGreedy)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAllCombined(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NormalizeURLString(allCombinedUrl, FlagsAllGreedy)
|
||||
}
|
||||
}
|
9
vendor/github.com/PuerkitoBio/purell/benchmarks/v0.1.0
generated
vendored
9
vendor/github.com/PuerkitoBio/purell/benchmarks/v0.1.0
generated
vendored
@ -1,9 +0,0 @@
|
||||
PASS
|
||||
BenchmarkSafe 500000 6131 ns/op
|
||||
BenchmarkUsuallySafe 200000 7864 ns/op
|
||||
BenchmarkUnsafe 100000 28560 ns/op
|
||||
BenchmarkAllDWORD 50000 38722 ns/op
|
||||
BenchmarkAllOctal 50000 40941 ns/op
|
||||
BenchmarkAllHex 50000 44063 ns/op
|
||||
BenchmarkAllCombined 50000 33613 ns/op
|
||||
ok github.com/PuerkitoBio/purell 17.404s
|
35
vendor/github.com/PuerkitoBio/purell/example_test.go
generated
vendored
35
vendor/github.com/PuerkitoBio/purell/example_test.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package purell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func ExampleNormalizeURLString() {
|
||||
if normalized, err := NormalizeURLString("hTTp://someWEBsite.com:80/Amazing%3f/url/",
|
||||
FlagLowercaseScheme|FlagLowercaseHost|FlagUppercaseEscapes); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
fmt.Print(normalized)
|
||||
}
|
||||
// Output: http://somewebsite.com:80/Amazing%3F/url/
|
||||
}
|
||||
|
||||
func ExampleMustNormalizeURLString() {
|
||||
normalized := MustNormalizeURLString("hTTpS://someWEBsite.com:443/Amazing%fa/url/",
|
||||
FlagsUnsafeGreedy)
|
||||
fmt.Print(normalized)
|
||||
|
||||
// Output: http://somewebsite.com/Amazing%FA/url
|
||||
}
|
||||
|
||||
func ExampleNormalizeURL() {
|
||||
if u, err := url.Parse("Http://SomeUrl.com:8080/a/b/.././c///g?c=3&a=1&b=9&c=0#target"); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
normalized := NormalizeURL(u, FlagsUsuallySafeGreedy|FlagRemoveDuplicateSlashes|FlagRemoveFragment)
|
||||
fmt.Print(normalized)
|
||||
}
|
||||
|
||||
// Output: http://someurl.com:8080/a/c/g?c=3&a=1&b=9&c=0
|
||||
}
|
768
vendor/github.com/PuerkitoBio/purell/purell_test.go
generated
vendored
768
vendor/github.com/PuerkitoBio/purell/purell_test.go
generated
vendored
@ -1,768 +0,0 @@
|
||||
package purell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
nm string
|
||||
src string
|
||||
flgs NormalizationFlags
|
||||
res string
|
||||
parsed bool
|
||||
}
|
||||
|
||||
var (
|
||||
cases = [...]*testCase{
|
||||
&testCase{
|
||||
"LowerScheme",
|
||||
"HTTP://www.SRC.ca",
|
||||
FlagLowercaseScheme,
|
||||
"http://www.SRC.ca",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"LowerScheme2",
|
||||
"http://www.SRC.ca",
|
||||
FlagLowercaseScheme,
|
||||
"http://www.SRC.ca",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"LowerHost",
|
||||
"HTTP://www.SRC.ca/",
|
||||
FlagLowercaseHost,
|
||||
"http://www.src.ca/", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UpperEscapes",
|
||||
`http://www.whatever.com/Some%aa%20Special%8Ecases/`,
|
||||
FlagUppercaseEscapes,
|
||||
"http://www.whatever.com/Some%AA%20Special%8Ecases/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UnnecessaryEscapes",
|
||||
`http://www.toto.com/%41%42%2E%44/%32%33%52%2D/%5f%7E`,
|
||||
FlagDecodeUnnecessaryEscapes,
|
||||
"http://www.toto.com/AB.D/23R-/_~",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDefaultPort",
|
||||
"HTTP://www.SRC.ca:80/",
|
||||
FlagRemoveDefaultPort,
|
||||
"http://www.SRC.ca/", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDefaultPort2",
|
||||
"HTTP://www.SRC.ca:80",
|
||||
FlagRemoveDefaultPort,
|
||||
"http://www.SRC.ca", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDefaultPort3",
|
||||
"HTTP://www.SRC.ca:8080",
|
||||
FlagRemoveDefaultPort,
|
||||
"http://www.SRC.ca:8080", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Safe",
|
||||
"HTTP://www.SRC.ca:80/to%1ato%8b%ee/OKnow%41%42%43%7e",
|
||||
FlagsSafe,
|
||||
"http://www.src.ca/to%1Ato%8B%EE/OKnowABC~",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"BothLower",
|
||||
"HTTP://www.SRC.ca:80/to%1ato%8b%ee/OKnow%41%42%43%7e",
|
||||
FlagLowercaseHost | FlagLowercaseScheme,
|
||||
"http://www.src.ca:80/to%1Ato%8B%EE/OKnowABC~",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveTrailingSlash",
|
||||
"HTTP://www.SRC.ca:80/",
|
||||
FlagRemoveTrailingSlash,
|
||||
"http://www.SRC.ca:80", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveTrailingSlash2",
|
||||
"HTTP://www.SRC.ca:80/toto/titi/",
|
||||
FlagRemoveTrailingSlash,
|
||||
"http://www.SRC.ca:80/toto/titi", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveTrailingSlash3",
|
||||
"HTTP://www.SRC.ca:80/toto/titi/fin/?a=1",
|
||||
FlagRemoveTrailingSlash,
|
||||
"http://www.SRC.ca:80/toto/titi/fin?a=1", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"AddTrailingSlash",
|
||||
"HTTP://www.SRC.ca:80",
|
||||
FlagAddTrailingSlash,
|
||||
"http://www.SRC.ca:80/", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"AddTrailingSlash2",
|
||||
"HTTP://www.SRC.ca:80/toto/titi.html",
|
||||
FlagAddTrailingSlash,
|
||||
"http://www.SRC.ca:80/toto/titi.html/", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"AddTrailingSlash3",
|
||||
"HTTP://www.SRC.ca:80/toto/titi/fin?a=1",
|
||||
FlagAddTrailingSlash,
|
||||
"http://www.SRC.ca:80/toto/titi/fin/?a=1", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDotSegments",
|
||||
"HTTP://root/a/b/./../../c/",
|
||||
FlagRemoveDotSegments,
|
||||
"http://root/c/", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDotSegments2",
|
||||
"HTTP://root/../a/b/./../c/../d",
|
||||
FlagRemoveDotSegments,
|
||||
"http://root/a/d", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UsuallySafe",
|
||||
"HTTP://www.SRC.ca:80/to%1ato%8b%ee/./c/d/../OKnow%41%42%43%7e/?a=b#test",
|
||||
FlagsUsuallySafeGreedy,
|
||||
"http://www.src.ca/to%1Ato%8B%EE/c/OKnowABC~?a=b#test",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDirectoryIndex",
|
||||
"HTTP://root/a/b/c/default.aspx",
|
||||
FlagRemoveDirectoryIndex,
|
||||
"http://root/a/b/c/", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDirectoryIndex2",
|
||||
"HTTP://root/a/b/c/default#a=b",
|
||||
FlagRemoveDirectoryIndex,
|
||||
"http://root/a/b/c/default#a=b", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveFragment",
|
||||
"HTTP://root/a/b/c/default#toto=tata",
|
||||
FlagRemoveFragment,
|
||||
"http://root/a/b/c/default", // Since Go1.1, scheme is automatically lowercased
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"ForceHTTP",
|
||||
"https://root/a/b/c/default#toto=tata",
|
||||
FlagForceHTTP,
|
||||
"http://root/a/b/c/default#toto=tata",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDuplicateSlashes",
|
||||
"https://root/a//b///c////default#toto=tata",
|
||||
FlagRemoveDuplicateSlashes,
|
||||
"https://root/a/b/c/default#toto=tata",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveDuplicateSlashes2",
|
||||
"https://root//a//b///c////default#toto=tata",
|
||||
FlagRemoveDuplicateSlashes,
|
||||
"https://root/a/b/c/default#toto=tata",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveWWW",
|
||||
"https://www.root/a/b/c/",
|
||||
FlagRemoveWWW,
|
||||
"https://root/a/b/c/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveWWW2",
|
||||
"https://WwW.Root/a/b/c/",
|
||||
FlagRemoveWWW,
|
||||
"https://Root/a/b/c/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"AddWWW",
|
||||
"https://Root/a/b/c/",
|
||||
FlagAddWWW,
|
||||
"https://www.Root/a/b/c/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"SortQuery",
|
||||
"http://root/toto/?b=4&a=1&c=3&b=2&a=5",
|
||||
FlagSortQuery,
|
||||
"http://root/toto/?a=1&a=5&b=2&b=4&c=3",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"RemoveEmptyQuerySeparator",
|
||||
"http://root/toto/?",
|
||||
FlagRemoveEmptyQuerySeparator,
|
||||
"http://root/toto/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Unsafe",
|
||||
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||||
FlagsUnsafeGreedy,
|
||||
"http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Safe2",
|
||||
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||||
FlagsSafe,
|
||||
"https://www.root.com/toto/tE%1F///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UsuallySafe2",
|
||||
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||||
FlagsUsuallySafeGreedy,
|
||||
"https://www.root.com/toto/tE%1F///a/c?z=3&w=2&a=4&w=1#invalid",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"AddTrailingSlashBug",
|
||||
"http://src.ca/",
|
||||
FlagsAllNonGreedy,
|
||||
"http://www.src.ca/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"SourceModified",
|
||||
"HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid",
|
||||
FlagsUnsafeGreedy,
|
||||
"http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3",
|
||||
true,
|
||||
},
|
||||
&testCase{
|
||||
"IPv6-1",
|
||||
"http://[2001:db8:1f70::999:de8:7648:6e8]/test",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://[2001:db8:1f70::999:de8:7648:6e8]/test",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"IPv6-2",
|
||||
"http://[::ffff:192.168.1.1]/test",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://[::ffff:192.168.1.1]/test",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"IPv6-3",
|
||||
"http://[::ffff:192.168.1.1]:80/test",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://[::ffff:192.168.1.1]/test",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"IPv6-4",
|
||||
"htTps://[::fFff:192.168.1.1]:443/test",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"https://[::ffff:192.168.1.1]/test",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"FTP",
|
||||
"ftp://user:pass@ftp.foo.net/foo/bar",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"ftp://user:pass@ftp.foo.net/foo/bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-1",
|
||||
"http://www.foo.com:80/foo",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://www.foo.com/foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-2",
|
||||
"http://www.foo.com:8000/foo",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://www.foo.com:8000/foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-3",
|
||||
"http://www.foo.com/%7ebar",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://www.foo.com/~bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-4",
|
||||
"http://www.foo.com/%7Ebar",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://www.foo.com/~bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-5",
|
||||
"http://USER:pass@www.Example.COM/foo/bar",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://USER:pass@www.example.com/foo/bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-6",
|
||||
"http://test.example/?a=%26&b=1",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://test.example/?a=%26&b=1",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-7",
|
||||
"http://test.example/%25/?p=%20val%20%25",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://test.example/%25/?p=%20val%20%25",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-8",
|
||||
"http://test.example/path/with a%20space+/",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://test.example/path/with%20a%20space+/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-9",
|
||||
"http://test.example/?",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://test.example/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Standard-10",
|
||||
"http://a.COM/path/?b&a",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://a.com/path/?b&a",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"StandardCasesAddTrailingSlash",
|
||||
"http://test.example?",
|
||||
FlagsSafe | FlagAddTrailingSlash,
|
||||
"http://test.example/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"OctalIP-1",
|
||||
"http://0123.011.0.4/",
|
||||
FlagsSafe | FlagDecodeOctalHost,
|
||||
"http://0123.011.0.4/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"OctalIP-2",
|
||||
"http://0102.0146.07.0223/",
|
||||
FlagsSafe | FlagDecodeOctalHost,
|
||||
"http://66.102.7.147/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"OctalIP-3",
|
||||
"http://0102.0146.07.0223.:23/",
|
||||
FlagsSafe | FlagDecodeOctalHost,
|
||||
"http://66.102.7.147.:23/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"OctalIP-4",
|
||||
"http://USER:pass@0102.0146.07.0223../",
|
||||
FlagsSafe | FlagDecodeOctalHost,
|
||||
"http://USER:pass@66.102.7.147../",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"DWORDIP-1",
|
||||
"http://123.1113982867/",
|
||||
FlagsSafe | FlagDecodeDWORDHost,
|
||||
"http://123.1113982867/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"DWORDIP-2",
|
||||
"http://1113982867/",
|
||||
FlagsSafe | FlagDecodeDWORDHost,
|
||||
"http://66.102.7.147/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"DWORDIP-3",
|
||||
"http://1113982867.:23/",
|
||||
FlagsSafe | FlagDecodeDWORDHost,
|
||||
"http://66.102.7.147.:23/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"DWORDIP-4",
|
||||
"http://USER:pass@1113982867../",
|
||||
FlagsSafe | FlagDecodeDWORDHost,
|
||||
"http://USER:pass@66.102.7.147../",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"HexIP-1",
|
||||
"http://0x123.1113982867/",
|
||||
FlagsSafe | FlagDecodeHexHost,
|
||||
"http://0x123.1113982867/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"HexIP-2",
|
||||
"http://0x42660793/",
|
||||
FlagsSafe | FlagDecodeHexHost,
|
||||
"http://66.102.7.147/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"HexIP-3",
|
||||
"http://0x42660793.:23/",
|
||||
FlagsSafe | FlagDecodeHexHost,
|
||||
"http://66.102.7.147.:23/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"HexIP-4",
|
||||
"http://USER:pass@0x42660793../",
|
||||
FlagsSafe | FlagDecodeHexHost,
|
||||
"http://USER:pass@66.102.7.147../",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UnnecessaryHostDots-1",
|
||||
"http://.www.foo.com../foo/bar.html",
|
||||
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||||
"http://www.foo.com/foo/bar.html",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UnnecessaryHostDots-2",
|
||||
"http://www.foo.com./foo/bar.html",
|
||||
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||||
"http://www.foo.com/foo/bar.html",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UnnecessaryHostDots-3",
|
||||
"http://www.foo.com.:81/foo",
|
||||
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||||
"http://www.foo.com:81/foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UnnecessaryHostDots-4",
|
||||
"http://www.example.com./",
|
||||
FlagsSafe | FlagRemoveUnnecessaryHostDots,
|
||||
"http://www.example.com/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"EmptyPort-1",
|
||||
"http://www.thedraymin.co.uk:/main/?p=308",
|
||||
FlagsSafe | FlagRemoveEmptyPortSeparator,
|
||||
"http://www.thedraymin.co.uk/main/?p=308",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"EmptyPort-2",
|
||||
"http://www.src.ca:",
|
||||
FlagsSafe | FlagRemoveEmptyPortSeparator,
|
||||
"http://www.src.ca",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-1",
|
||||
"http://test.example/foo/bar/.",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/bar/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-2",
|
||||
"http://test.example/foo/bar/./",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/bar/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-3",
|
||||
"http://test.example/foo/bar/..",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-4",
|
||||
"http://test.example/foo/bar/../",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-5",
|
||||
"http://test.example/foo/bar/../baz",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/baz",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-6",
|
||||
"http://test.example/foo/bar/../..",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-7",
|
||||
"http://test.example/foo/bar/../../",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-8",
|
||||
"http://test.example/foo/bar/../../baz",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/baz",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-9",
|
||||
"http://test.example/foo/bar/../../../baz",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/baz",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-10",
|
||||
"http://test.example/foo/bar/../../../../baz",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/baz",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-11",
|
||||
"http://test.example/./foo",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-12",
|
||||
"http://test.example/../foo",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-13",
|
||||
"http://test.example/foo.",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo.",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-14",
|
||||
"http://test.example/.foo",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/.foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-15",
|
||||
"http://test.example/foo..",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo..",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-16",
|
||||
"http://test.example/..foo",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/..foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-17",
|
||||
"http://test.example/./../foo",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-18",
|
||||
"http://test.example/./foo/.",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-19",
|
||||
"http://test.example/foo/./bar",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-20",
|
||||
"http://test.example/foo/../bar",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-21",
|
||||
"http://test.example/foo//",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Slashes-22",
|
||||
"http://test.example/foo///bar//",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"http://test.example/foo/bar/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Relative",
|
||||
"foo/bar",
|
||||
FlagsAllGreedy,
|
||||
"foo/bar",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Relative-1",
|
||||
"./../foo",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"foo",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Relative-2",
|
||||
"./foo/bar/../baz/../bang/..",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"foo/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Relative-3",
|
||||
"foo///bar//",
|
||||
FlagsSafe | FlagRemoveDotSegments | FlagRemoveDuplicateSlashes,
|
||||
"foo/bar/",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"Relative-4",
|
||||
"www.youtube.com",
|
||||
FlagsUsuallySafeGreedy,
|
||||
"www.youtube.com",
|
||||
false,
|
||||
},
|
||||
/*&testCase{
|
||||
"UrlNorm-5",
|
||||
"http://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%82%BF%E3%83%94%E3%83%A9%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3",
|
||||
FlagsSafe | FlagRemoveDotSegments,
|
||||
"http://ja.wikipedia.org/wiki/\xe3\x82\xad\xe3\x83\xa3\xe3\x82\xbf\xe3\x83\x94\xe3\x83\xa9\xe3\x83\xbc\xe3\x82\xb8\xe3\x83\xa3\xe3\x83\x91\xe3\x83\xb3",
|
||||
false,
|
||||
},
|
||||
&testCase{
|
||||
"UrlNorm-1",
|
||||
"http://test.example/?a=%e3%82%82%26",
|
||||
FlagsAllGreedy,
|
||||
"http://test.example/?a=\xe3\x82\x82%26",
|
||||
false,
|
||||
},*/
|
||||
}
|
||||
)
|
||||
|
||||
func TestRunner(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
runCase(tc, t)
|
||||
}
|
||||
}
|
||||
|
||||
func runCase(tc *testCase, t *testing.T) {
|
||||
t.Logf("running %s...", tc.nm)
|
||||
if tc.parsed {
|
||||
u, e := url.Parse(tc.src)
|
||||
if e != nil {
|
||||
t.Errorf("%s - FAIL : %s", tc.nm, e)
|
||||
return
|
||||
} else {
|
||||
NormalizeURL(u, tc.flgs)
|
||||
if s := u.String(); s != tc.res {
|
||||
t.Errorf("%s - FAIL expected '%s', got '%s'", tc.nm, tc.res, s)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if s, e := NormalizeURLString(tc.src, tc.flgs); e != nil {
|
||||
t.Errorf("%s - FAIL : %s", tc.nm, e)
|
||||
} else if s != tc.res {
|
||||
t.Errorf("%s - FAIL expected '%s', got '%s'", tc.nm, tc.res, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeUnnecessaryEscapesAll(t *testing.T) {
|
||||
var url = "http://host/"
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
url += fmt.Sprintf("%%%02x", i)
|
||||
}
|
||||
if s, e := NormalizeURLString(url, FlagDecodeUnnecessaryEscapes); e != nil {
|
||||
t.Fatalf("Got error %s", e.Error())
|
||||
} else {
|
||||
const want = "http://host/%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22%23$%25&'()*+,-./0123456789:;%3C=%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"
|
||||
if s != want {
|
||||
t.Errorf("DecodeUnnecessaryEscapesAll:\nwant\n%s\ngot\n%s", want, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeNecessaryEscapesAll(t *testing.T) {
|
||||
var url = "http://host/"
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
if i != 0x25 {
|
||||
url += string(i)
|
||||
}
|
||||
}
|
||||
if s, e := NormalizeURLString(url, FlagEncodeNecessaryEscapes); e != nil {
|
||||
t.Fatalf("Got error %s", e.Error())
|
||||
} else {
|
||||
const want = "http://host/%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%C2%80%C2%81%C2%82%C2%83%C2%84%C2%85%C2%86%C2%87%C2%88%C2%89%C2%8A%C2%8B%C2%8C%C2%8D%C2%8E%C2%8F%C2%90%C2%91%C2%92%C2%93%C2%94%C2%95%C2%96%C2%97%C2%98%C2%99%C2%9A%C2%9B%C2%9C%C2%9D%C2%9E%C2%9F%C2%A0%C2%A1%C2%A2%C2%A3%C2%A4%C2%A5%C2%A6%C2%A7%C2%A8%C2%A9%C2%AA%C2%AB%C2%AC%C2%AD%C2%AE%C2%AF%C2%B0%C2%B1%C2%B2%C2%B3%C2%B4%C2%B5%C2%B6%C2%B7%C2%B8%C2%B9%C2%BA%C2%BB%C2%BC%C2%BD%C2%BE%C2%BF%C3%80%C3%81%C3%82%C3%83%C3%84%C3%85%C3%86%C3%87%C3%88%C3%89%C3%8A%C3%8B%C3%8C%C3%8D%C3%8E%C3%8F%C3%90%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%9B%C3%9C%C3%9D%C3%9E%C3%9F%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%A8%C3%A9%C3%AA%C3%AB%C3%AC%C3%AD%C3%AE%C3%AF%C3%B0%C3%B1%C3%B2%C3%B3%C3%B4%C3%B5%C3%B6%C3%B7%C3%B8%C3%B9%C3%BA%C3%BB%C3%BC%C3%BD%C3%BE%C3%BF"
|
||||
if s != want {
|
||||
t.Errorf("EncodeNecessaryEscapesAll:\nwant\n%s\ngot\n%s", want, s)
|
||||
}
|
||||
}
|
||||
}
|
52
vendor/github.com/PuerkitoBio/purell/urlnorm_test.go
generated
vendored
52
vendor/github.com/PuerkitoBio/purell/urlnorm_test.go
generated
vendored
@ -1,52 +0,0 @@
|
||||
package purell
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Test cases merged from PR #1
|
||||
// Originally from https://github.com/jehiah/urlnorm/blob/master/test_urlnorm.py
|
||||
|
||||
func assertMap(t *testing.T, cases map[string]string, f NormalizationFlags) {
|
||||
for bad, good := range cases {
|
||||
s, e := NormalizeURLString(bad, f)
|
||||
if e != nil {
|
||||
t.Errorf("%s normalizing %v to %v", e.Error(), bad, good)
|
||||
} else {
|
||||
if s != good {
|
||||
t.Errorf("source: %v expected: %v got: %v", bad, good, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This tests normalization to a unicode representation
|
||||
// precent escapes for unreserved values are unescaped to their unicode value
|
||||
// tests normalization to idna domains
|
||||
// test ip word handling, ipv6 address handling, and trailing domain periods
|
||||
// in general, this matches google chromes unescaping for things in the address bar.
|
||||
// spaces are converted to '+' (perhaphs controversial)
|
||||
// http://code.google.com/p/google-url/ probably is another good reference for this approach
|
||||
func TestUrlnorm(t *testing.T) {
|
||||
testcases := map[string]string{
|
||||
"http://test.example/?a=%e3%82%82%26": "http://test.example/?a=%e3%82%82%26",
|
||||
//"http://test.example/?a=%e3%82%82%26": "http://test.example/?a=\xe3\x82\x82%26", //should return a unicode character
|
||||
"http://s.xn--q-bga.DE/": "http://s.xn--q-bga.de/", //should be in idna format
|
||||
"http://XBLA\u306eXbox.com": "http://xn--xblaxbox-jf4g.com", //test utf8 and unicode
|
||||
"http://президент.рф": "http://xn--d1abbgf6aiiy.xn--p1ai",
|
||||
"http://ПРЕЗИДЕНТ.РФ": "http://xn--d1abbgf6aiiy.xn--p1ai",
|
||||
"http://\u00e9.com": "http://xn--9ca.com",
|
||||
"http://e\u0301.com": "http://xn--9ca.com",
|
||||
"http://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%82%BF%E3%83%94%E3%83%A9%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3": "http://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%82%BF%E3%83%94%E3%83%A9%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3",
|
||||
//"http://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%82%BF%E3%83%94%E3%83%A9%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3": "http://ja.wikipedia.org/wiki/\xe3\x82\xad\xe3\x83\xa3\xe3\x82\xbf\xe3\x83\x94\xe3\x83\xa9\xe3\x83\xbc\xe3\x82\xb8\xe3\x83\xa3\xe3\x83\x91\xe3\x83\xb3",
|
||||
|
||||
"http://test.example/\xe3\x82\xad": "http://test.example/%E3%82%AD",
|
||||
//"http://test.example/\xe3\x82\xad": "http://test.example/\xe3\x82\xad",
|
||||
"http://test.example/?p=%23val#test-%23-val%25": "http://test.example/?p=%23val#test-%23-val%25", //check that %23 (#) is not escaped where it shouldn't be
|
||||
|
||||
"http://test.domain/I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%EF%BF%BDliz%C3%A6ti%C3%B8n": "http://test.domain/I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%EF%BF%BDliz%C3%A6ti%C3%B8n",
|
||||
//"http://test.domain/I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%EF%BF%BDliz%C3%A6ti%C3%B8n": "http://test.domain/I\xc3\xb1t\xc3\xabrn\xc3\xa2ti\xc3\xb4n\xef\xbf\xbdliz\xc3\xa6ti\xc3\xb8n",
|
||||
}
|
||||
|
||||
assertMap(t, testcases, FlagsSafe|FlagRemoveDotSegments)
|
||||
}
|
641
vendor/github.com/PuerkitoBio/urlesc/urlesc_test.go
generated
vendored
641
vendor/github.com/PuerkitoBio/urlesc/urlesc_test.go
generated
vendored
@ -1,641 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package urlesc
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type URLTest struct {
|
||||
in string
|
||||
out *url.URL
|
||||
roundtrip string // expected result of reserializing the URL; empty means same as "in".
|
||||
}
|
||||
|
||||
var urltests = []URLTest{
|
||||
// no path
|
||||
{
|
||||
"http://www.google.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// path
|
||||
{
|
||||
"http://www.google.com/",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// path with hex escaping
|
||||
{
|
||||
"http://www.google.com/file%20one%26two",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/file one&two",
|
||||
},
|
||||
"http://www.google.com/file%20one&two",
|
||||
},
|
||||
// user
|
||||
{
|
||||
"ftp://webmaster@www.google.com/",
|
||||
&url.URL{
|
||||
Scheme: "ftp",
|
||||
User: url.User("webmaster"),
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// escape sequence in username
|
||||
{
|
||||
"ftp://john%20doe@www.google.com/",
|
||||
&url.URL{
|
||||
Scheme: "ftp",
|
||||
User: url.User("john doe"),
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
},
|
||||
"ftp://john%20doe@www.google.com/",
|
||||
},
|
||||
// query
|
||||
{
|
||||
"http://www.google.com/?q=go+language",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
RawQuery: "q=go+language",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// query with hex escaping: NOT parsed
|
||||
{
|
||||
"http://www.google.com/?q=go%20language",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
RawQuery: "q=go%20language",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// %20 outside query
|
||||
{
|
||||
"http://www.google.com/a%20b?q=c+d",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/a b",
|
||||
RawQuery: "q=c+d",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// path without leading /, so no parsing
|
||||
{
|
||||
"http:www.google.com/?q=go+language",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Opaque: "www.google.com/",
|
||||
RawQuery: "q=go+language",
|
||||
},
|
||||
"http:www.google.com/?q=go+language",
|
||||
},
|
||||
// path without leading /, so no parsing
|
||||
{
|
||||
"http:%2f%2fwww.google.com/?q=go+language",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Opaque: "%2f%2fwww.google.com/",
|
||||
RawQuery: "q=go+language",
|
||||
},
|
||||
"http:%2f%2fwww.google.com/?q=go+language",
|
||||
},
|
||||
// non-authority with path
|
||||
{
|
||||
"mailto:/webmaster@golang.org",
|
||||
&url.URL{
|
||||
Scheme: "mailto",
|
||||
Path: "/webmaster@golang.org",
|
||||
},
|
||||
"mailto:///webmaster@golang.org", // unfortunate compromise
|
||||
},
|
||||
// non-authority
|
||||
{
|
||||
"mailto:webmaster@golang.org",
|
||||
&url.URL{
|
||||
Scheme: "mailto",
|
||||
Opaque: "webmaster@golang.org",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// unescaped :// in query should not create a scheme
|
||||
{
|
||||
"/foo?query=http://bad",
|
||||
&url.URL{
|
||||
Path: "/foo",
|
||||
RawQuery: "query=http://bad",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// leading // without scheme should create an authority
|
||||
{
|
||||
"//foo",
|
||||
&url.URL{
|
||||
Host: "foo",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// leading // without scheme, with userinfo, path, and query
|
||||
{
|
||||
"//user@foo/path?a=b",
|
||||
&url.URL{
|
||||
User: url.User("user"),
|
||||
Host: "foo",
|
||||
Path: "/path",
|
||||
RawQuery: "a=b",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// Three leading slashes isn't an authority, but doesn't return an error.
|
||||
// (We can't return an error, as this code is also used via
|
||||
// ServeHTTP -> ReadRequest -> Parse, which is arguably a
|
||||
// different URL parsing context, but currently shares the
|
||||
// same codepath)
|
||||
{
|
||||
"///threeslashes",
|
||||
&url.URL{
|
||||
Path: "///threeslashes",
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
"http://user:password@google.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword("user", "password"),
|
||||
Host: "google.com",
|
||||
},
|
||||
"http://user:password@google.com",
|
||||
},
|
||||
// unescaped @ in username should not confuse host
|
||||
{
|
||||
"http://j@ne:password@google.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword("j@ne", "password"),
|
||||
Host: "google.com",
|
||||
},
|
||||
"http://j%40ne:password@google.com",
|
||||
},
|
||||
// unescaped @ in password should not confuse host
|
||||
{
|
||||
"http://jane:p@ssword@google.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword("jane", "p@ssword"),
|
||||
Host: "google.com",
|
||||
},
|
||||
"http://jane:p%40ssword@google.com",
|
||||
},
|
||||
{
|
||||
"http://j@ne:password@google.com/p@th?q=@go",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword("j@ne", "password"),
|
||||
Host: "google.com",
|
||||
Path: "/p@th",
|
||||
RawQuery: "q=@go",
|
||||
},
|
||||
"http://j%40ne:password@google.com/p@th?q=@go",
|
||||
},
|
||||
{
|
||||
"http://www.google.com/?q=go+language#foo",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
RawQuery: "q=go+language",
|
||||
Fragment: "foo",
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
"http://www.google.com/?q=go+language#foo%26bar",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "/",
|
||||
RawQuery: "q=go+language",
|
||||
Fragment: "foo&bar",
|
||||
},
|
||||
"http://www.google.com/?q=go+language#foo&bar",
|
||||
},
|
||||
{
|
||||
"file:///home/adg/rabbits",
|
||||
&url.URL{
|
||||
Scheme: "file",
|
||||
Host: "",
|
||||
Path: "/home/adg/rabbits",
|
||||
},
|
||||
"file:///home/adg/rabbits",
|
||||
},
|
||||
// "Windows" paths are no exception to the rule.
|
||||
// See golang.org/issue/6027, especially comment #9.
|
||||
{
|
||||
"file:///C:/FooBar/Baz.txt",
|
||||
&url.URL{
|
||||
Scheme: "file",
|
||||
Host: "",
|
||||
Path: "/C:/FooBar/Baz.txt",
|
||||
},
|
||||
"file:///C:/FooBar/Baz.txt",
|
||||
},
|
||||
// case-insensitive scheme
|
||||
{
|
||||
"MaIlTo:webmaster@golang.org",
|
||||
&url.URL{
|
||||
Scheme: "mailto",
|
||||
Opaque: "webmaster@golang.org",
|
||||
},
|
||||
"mailto:webmaster@golang.org",
|
||||
},
|
||||
// Relative path
|
||||
{
|
||||
"a/b/c",
|
||||
&url.URL{
|
||||
Path: "a/b/c",
|
||||
},
|
||||
"a/b/c",
|
||||
},
|
||||
// escaped '?' in username and password
|
||||
{
|
||||
"http://%3Fam:pa%3Fsword@google.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword("?am", "pa?sword"),
|
||||
Host: "google.com",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// escaped '?' and '#' in path
|
||||
{
|
||||
"http://example.com/%3F%23",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "example.com",
|
||||
Path: "?#",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// unescaped [ ] ! ' ( ) * in path
|
||||
{
|
||||
"http://example.com/[]!'()*",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "example.com",
|
||||
Path: "[]!'()*",
|
||||
},
|
||||
"http://example.com/[]!'()*",
|
||||
},
|
||||
// escaped : / ? # [ ] @ in username and password
|
||||
{
|
||||
"http://%3A%2F%3F:%23%5B%5D%40@example.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword(":/?", "#[]@"),
|
||||
Host: "example.com",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// unescaped ! $ & ' ( ) * + , ; = in username and password
|
||||
{
|
||||
"http://!$&'():*+,;=@example.com",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
User: url.UserPassword("!$&'()", "*+,;="),
|
||||
Host: "example.com",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// unescaped = : / . ? = in query component
|
||||
{
|
||||
"http://example.com/?q=http://google.com/?q=",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "example.com",
|
||||
Path: "/",
|
||||
RawQuery: "q=http://google.com/?q=",
|
||||
},
|
||||
"",
|
||||
},
|
||||
// unescaped : / ? [ ] @ ! $ & ' ( ) * + , ; = in fragment
|
||||
{
|
||||
"http://example.com/#:/?%23[]@!$&'()*+,;=",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "example.com",
|
||||
Path: "/",
|
||||
Fragment: ":/?#[]@!$&'()*+,;=",
|
||||
},
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
func DoTestString(t *testing.T, parse func(string) (*url.URL, error), name string, tests []URLTest) {
|
||||
for _, tt := range tests {
|
||||
u, err := parse(tt.in)
|
||||
if err != nil {
|
||||
t.Errorf("%s(%q) returned error %s", name, tt.in, err)
|
||||
continue
|
||||
}
|
||||
expected := tt.in
|
||||
if len(tt.roundtrip) > 0 {
|
||||
expected = tt.roundtrip
|
||||
}
|
||||
s := Escape(u)
|
||||
if s != expected {
|
||||
t.Errorf("Escape(%s(%q)) == %q (expected %q)", name, tt.in, s, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLString(t *testing.T) {
|
||||
DoTestString(t, url.Parse, "Parse", urltests)
|
||||
|
||||
// no leading slash on path should prepend
|
||||
// slash on String() call
|
||||
noslash := URLTest{
|
||||
"http://www.google.com/search",
|
||||
&url.URL{
|
||||
Scheme: "http",
|
||||
Host: "www.google.com",
|
||||
Path: "search",
|
||||
},
|
||||
"",
|
||||
}
|
||||
s := Escape(noslash.out)
|
||||
if s != noslash.in {
|
||||
t.Errorf("Expected %s; go %s", noslash.in, s)
|
||||
}
|
||||
}
|
||||
|
||||
type EscapeTest struct {
|
||||
in string
|
||||
out string
|
||||
err error
|
||||
}
|
||||
|
||||
var escapeTests = []EscapeTest{
|
||||
{
|
||||
"",
|
||||
"",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"abc",
|
||||
"abc",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"one two",
|
||||
"one+two",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"10%",
|
||||
"10%25",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
" ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;",
|
||||
"+?%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A/%40%24%27%28%29%2A%2C%3B",
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
func TestEscape(t *testing.T) {
|
||||
for _, tt := range escapeTests {
|
||||
actual := QueryEscape(tt.in)
|
||||
if tt.out != actual {
|
||||
t.Errorf("QueryEscape(%q) = %q, want %q", tt.in, actual, tt.out)
|
||||
}
|
||||
|
||||
// for bonus points, verify that escape:unescape is an identity.
|
||||
roundtrip, err := url.QueryUnescape(actual)
|
||||
if roundtrip != tt.in || err != nil {
|
||||
t.Errorf("QueryUnescape(%q) = %q, %s; want %q, %s", actual, roundtrip, err, tt.in, "[no error]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var resolveReferenceTests = []struct {
|
||||
base, rel, expected string
|
||||
}{
|
||||
// Absolute URL references
|
||||
{"http://foo.com?a=b", "https://bar.com/", "https://bar.com/"},
|
||||
{"http://foo.com/", "https://bar.com/?a=b", "https://bar.com/?a=b"},
|
||||
{"http://foo.com/bar", "mailto:foo@example.com", "mailto:foo@example.com"},
|
||||
|
||||
// Path-absolute references
|
||||
{"http://foo.com/bar", "/baz", "http://foo.com/baz"},
|
||||
{"http://foo.com/bar?a=b#f", "/baz", "http://foo.com/baz"},
|
||||
{"http://foo.com/bar?a=b", "/baz?c=d", "http://foo.com/baz?c=d"},
|
||||
|
||||
// Scheme-relative
|
||||
{"https://foo.com/bar?a=b", "//bar.com/quux", "https://bar.com/quux"},
|
||||
|
||||
// Path-relative references:
|
||||
|
||||
// ... current directory
|
||||
{"http://foo.com", ".", "http://foo.com/"},
|
||||
{"http://foo.com/bar", ".", "http://foo.com/"},
|
||||
{"http://foo.com/bar/", ".", "http://foo.com/bar/"},
|
||||
|
||||
// ... going down
|
||||
{"http://foo.com", "bar", "http://foo.com/bar"},
|
||||
{"http://foo.com/", "bar", "http://foo.com/bar"},
|
||||
{"http://foo.com/bar/baz", "quux", "http://foo.com/bar/quux"},
|
||||
|
||||
// ... going up
|
||||
{"http://foo.com/bar/baz", "../quux", "http://foo.com/quux"},
|
||||
{"http://foo.com/bar/baz", "../../../../../quux", "http://foo.com/quux"},
|
||||
{"http://foo.com/bar", "..", "http://foo.com/"},
|
||||
{"http://foo.com/bar/baz", "./..", "http://foo.com/"},
|
||||
// ".." in the middle (issue 3560)
|
||||
{"http://foo.com/bar/baz", "quux/dotdot/../tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/../tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/.././tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/./../tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/././../../tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/./.././../tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/dotdot/./../../.././././tail", "http://foo.com/bar/quux/tail"},
|
||||
{"http://foo.com/bar/baz", "quux/./dotdot/../dotdot/../dot/./tail/..", "http://foo.com/bar/quux/dot/"},
|
||||
|
||||
// Remove any dot-segments prior to forming the target URI.
|
||||
// http://tools.ietf.org/html/rfc3986#section-5.2.4
|
||||
{"http://foo.com/dot/./dotdot/../foo/bar", "../baz", "http://foo.com/dot/baz"},
|
||||
|
||||
// Triple dot isn't special
|
||||
{"http://foo.com/bar", "...", "http://foo.com/..."},
|
||||
|
||||
// Fragment
|
||||
{"http://foo.com/bar", ".#frag", "http://foo.com/#frag"},
|
||||
|
||||
// RFC 3986: Normal Examples
|
||||
// http://tools.ietf.org/html/rfc3986#section-5.4.1
|
||||
{"http://a/b/c/d;p?q", "g:h", "g:h"},
|
||||
{"http://a/b/c/d;p?q", "g", "http://a/b/c/g"},
|
||||
{"http://a/b/c/d;p?q", "./g", "http://a/b/c/g"},
|
||||
{"http://a/b/c/d;p?q", "g/", "http://a/b/c/g/"},
|
||||
{"http://a/b/c/d;p?q", "/g", "http://a/g"},
|
||||
{"http://a/b/c/d;p?q", "//g", "http://g"},
|
||||
{"http://a/b/c/d;p?q", "?y", "http://a/b/c/d;p?y"},
|
||||
{"http://a/b/c/d;p?q", "g?y", "http://a/b/c/g?y"},
|
||||
{"http://a/b/c/d;p?q", "#s", "http://a/b/c/d;p?q#s"},
|
||||
{"http://a/b/c/d;p?q", "g#s", "http://a/b/c/g#s"},
|
||||
{"http://a/b/c/d;p?q", "g?y#s", "http://a/b/c/g?y#s"},
|
||||
{"http://a/b/c/d;p?q", ";x", "http://a/b/c/;x"},
|
||||
{"http://a/b/c/d;p?q", "g;x", "http://a/b/c/g;x"},
|
||||
{"http://a/b/c/d;p?q", "g;x?y#s", "http://a/b/c/g;x?y#s"},
|
||||
{"http://a/b/c/d;p?q", "", "http://a/b/c/d;p?q"},
|
||||
{"http://a/b/c/d;p?q", ".", "http://a/b/c/"},
|
||||
{"http://a/b/c/d;p?q", "./", "http://a/b/c/"},
|
||||
{"http://a/b/c/d;p?q", "..", "http://a/b/"},
|
||||
{"http://a/b/c/d;p?q", "../", "http://a/b/"},
|
||||
{"http://a/b/c/d;p?q", "../g", "http://a/b/g"},
|
||||
{"http://a/b/c/d;p?q", "../..", "http://a/"},
|
||||
{"http://a/b/c/d;p?q", "../../", "http://a/"},
|
||||
{"http://a/b/c/d;p?q", "../../g", "http://a/g"},
|
||||
|
||||
// RFC 3986: Abnormal Examples
|
||||
// http://tools.ietf.org/html/rfc3986#section-5.4.2
|
||||
{"http://a/b/c/d;p?q", "../../../g", "http://a/g"},
|
||||
{"http://a/b/c/d;p?q", "../../../../g", "http://a/g"},
|
||||
{"http://a/b/c/d;p?q", "/./g", "http://a/g"},
|
||||
{"http://a/b/c/d;p?q", "/../g", "http://a/g"},
|
||||
{"http://a/b/c/d;p?q", "g.", "http://a/b/c/g."},
|
||||
{"http://a/b/c/d;p?q", ".g", "http://a/b/c/.g"},
|
||||
{"http://a/b/c/d;p?q", "g..", "http://a/b/c/g.."},
|
||||
{"http://a/b/c/d;p?q", "..g", "http://a/b/c/..g"},
|
||||
{"http://a/b/c/d;p?q", "./../g", "http://a/b/g"},
|
||||
{"http://a/b/c/d;p?q", "./g/.", "http://a/b/c/g/"},
|
||||
{"http://a/b/c/d;p?q", "g/./h", "http://a/b/c/g/h"},
|
||||
{"http://a/b/c/d;p?q", "g/../h", "http://a/b/c/h"},
|
||||
{"http://a/b/c/d;p?q", "g;x=1/./y", "http://a/b/c/g;x=1/y"},
|
||||
{"http://a/b/c/d;p?q", "g;x=1/../y", "http://a/b/c/y"},
|
||||
{"http://a/b/c/d;p?q", "g?y/./x", "http://a/b/c/g?y/./x"},
|
||||
{"http://a/b/c/d;p?q", "g?y/../x", "http://a/b/c/g?y/../x"},
|
||||
{"http://a/b/c/d;p?q", "g#s/./x", "http://a/b/c/g#s/./x"},
|
||||
{"http://a/b/c/d;p?q", "g#s/../x", "http://a/b/c/g#s/../x"},
|
||||
|
||||
// Extras.
|
||||
{"https://a/b/c/d;p?q", "//g?q", "https://g?q"},
|
||||
{"https://a/b/c/d;p?q", "//g#s", "https://g#s"},
|
||||
{"https://a/b/c/d;p?q", "//g/d/e/f?y#s", "https://g/d/e/f?y#s"},
|
||||
{"https://a/b/c/d;p#s", "?y", "https://a/b/c/d;p?y"},
|
||||
{"https://a/b/c/d;p?q#s", "?y", "https://a/b/c/d;p?y"},
|
||||
}
|
||||
|
||||
func TestResolveReference(t *testing.T) {
|
||||
mustParse := func(url_ string) *url.URL {
|
||||
u, err := url.Parse(url_)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected URL to parse: %q, got error: %v", url_, err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
opaque := &url.URL{Scheme: "scheme", Opaque: "opaque"}
|
||||
for _, test := range resolveReferenceTests {
|
||||
base := mustParse(test.base)
|
||||
rel := mustParse(test.rel)
|
||||
url := base.ResolveReference(rel)
|
||||
if Escape(url) != test.expected {
|
||||
t.Errorf("URL(%q).ResolveReference(%q) == %q, got %q", test.base, test.rel, test.expected, Escape(url))
|
||||
}
|
||||
// Ensure that new instances are returned.
|
||||
if base == url {
|
||||
t.Errorf("Expected URL.ResolveReference to return new URL instance.")
|
||||
}
|
||||
// Test the convenience wrapper too.
|
||||
url, err := base.Parse(test.rel)
|
||||
if err != nil {
|
||||
t.Errorf("URL(%q).Parse(%q) failed: %v", test.base, test.rel, err)
|
||||
} else if Escape(url) != test.expected {
|
||||
t.Errorf("URL(%q).Parse(%q) == %q, got %q", test.base, test.rel, test.expected, Escape(url))
|
||||
} else if base == url {
|
||||
// Ensure that new instances are returned for the wrapper too.
|
||||
t.Errorf("Expected URL.Parse to return new URL instance.")
|
||||
}
|
||||
// Ensure Opaque resets the URL.
|
||||
url = base.ResolveReference(opaque)
|
||||
if *url != *opaque {
|
||||
t.Errorf("ResolveReference failed to resolve opaque URL: want %#v, got %#v", url, opaque)
|
||||
}
|
||||
// Test the convenience wrapper with an opaque URL too.
|
||||
url, err = base.Parse("scheme:opaque")
|
||||
if err != nil {
|
||||
t.Errorf(`URL(%q).Parse("scheme:opaque") failed: %v`, test.base, err)
|
||||
} else if *url != *opaque {
|
||||
t.Errorf("Parse failed to resolve opaque URL: want %#v, got %#v", url, opaque)
|
||||
} else if base == url {
|
||||
// Ensure that new instances are returned, again.
|
||||
t.Errorf("Expected URL.Parse to return new URL instance.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type shouldEscapeTest struct {
|
||||
in byte
|
||||
mode encoding
|
||||
escape bool
|
||||
}
|
||||
|
||||
var shouldEscapeTests = []shouldEscapeTest{
|
||||
// Unreserved characters (§2.3)
|
||||
{'a', encodePath, false},
|
||||
{'a', encodeUserPassword, false},
|
||||
{'a', encodeQueryComponent, false},
|
||||
{'a', encodeFragment, false},
|
||||
{'z', encodePath, false},
|
||||
{'A', encodePath, false},
|
||||
{'Z', encodePath, false},
|
||||
{'0', encodePath, false},
|
||||
{'9', encodePath, false},
|
||||
{'-', encodePath, false},
|
||||
{'-', encodeUserPassword, false},
|
||||
{'-', encodeQueryComponent, false},
|
||||
{'-', encodeFragment, false},
|
||||
{'.', encodePath, false},
|
||||
{'_', encodePath, false},
|
||||
{'~', encodePath, false},
|
||||
|
||||
// User information (§3.2.1)
|
||||
{':', encodeUserPassword, true},
|
||||
{'/', encodeUserPassword, true},
|
||||
{'?', encodeUserPassword, true},
|
||||
{'@', encodeUserPassword, true},
|
||||
{'$', encodeUserPassword, false},
|
||||
{'&', encodeUserPassword, false},
|
||||
{'+', encodeUserPassword, false},
|
||||
{',', encodeUserPassword, false},
|
||||
{';', encodeUserPassword, false},
|
||||
{'=', encodeUserPassword, false},
|
||||
}
|
||||
|
||||
func TestShouldEscape(t *testing.T) {
|
||||
for _, tt := range shouldEscapeTests {
|
||||
if shouldEscape(tt.in, tt.mode) != tt.escape {
|
||||
t.Errorf("shouldEscape(%q, %v) returned %v; expected %v", tt.in, tt.mode, !tt.escape, tt.escape)
|
||||
}
|
||||
}
|
||||
}
|
4
vendor/github.com/emicklei/go-restful-swagger12/.travis.yml
generated
vendored
4
vendor/github.com/emicklei/go-restful-swagger12/.travis.yml
generated
vendored
@ -1,4 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.x
|
46
vendor/github.com/emicklei/go-restful-swagger12/CHANGES.md
generated
vendored
46
vendor/github.com/emicklei/go-restful-swagger12/CHANGES.md
generated
vendored
@ -1,46 +0,0 @@
|
||||
Change history of swagger
|
||||
=
|
||||
2017-01-30
|
||||
- moved from go-restful/swagger to go-restful-swagger12
|
||||
|
||||
2015-10-16
|
||||
- add type override mechanism for swagger models (MR 254, nathanejohnson)
|
||||
- replace uses of wildcard in generated apidocs (issue 251)
|
||||
|
||||
2015-05-25
|
||||
- (api break) changed the type of Properties in Model
|
||||
- (api break) changed the type of Models in ApiDeclaration
|
||||
- (api break) changed the parameter type of PostBuildDeclarationMapFunc
|
||||
|
||||
2015-04-09
|
||||
- add ModelBuildable interface for customization of Model
|
||||
|
||||
2015-03-17
|
||||
- preserve order of Routes per WebService in Swagger listing
|
||||
- fix use of $ref and type in Swagger models
|
||||
- add api version to listing
|
||||
|
||||
2014-11-14
|
||||
- operation parameters are now sorted using ordering path,query,form,header,body
|
||||
|
||||
2014-11-12
|
||||
- respect omitempty tag value for embedded structs
|
||||
- expose ApiVersion of WebService to Swagger ApiDeclaration
|
||||
|
||||
2014-05-29
|
||||
- (api add) Ability to define custom http.Handler to serve swagger-ui static files
|
||||
|
||||
2014-05-04
|
||||
- (fix) include model for array element type of response
|
||||
|
||||
2014-01-03
|
||||
- (fix) do not add primitive type to the Api models
|
||||
|
||||
2013-11-27
|
||||
- (fix) make Swagger work for WebServices with root ("/" or "") paths
|
||||
|
||||
2013-10-29
|
||||
- (api add) package variable LogInfo to customize logging function
|
||||
|
||||
2013-10-15
|
||||
- upgraded to spec version 1.2 (https://github.com/wordnik/swagger-core/wiki/1.2-transition)
|
22
vendor/github.com/emicklei/go-restful-swagger12/LICENSE
generated
vendored
22
vendor/github.com/emicklei/go-restful-swagger12/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
||||
Copyright (c) 2017 Ernest Micklei
|
||||
|
||||
MIT License
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
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.
|
83
vendor/github.com/emicklei/go-restful-swagger12/README.md
generated
vendored
83
vendor/github.com/emicklei/go-restful-swagger12/README.md
generated
vendored
@ -1,83 +0,0 @@
|
||||
# go-restful-swagger12
|
||||
|
||||
[![Build Status](https://travis-ci.org/emicklei/go-restful-swagger12.png)](https://travis-ci.org/emicklei/go-restful-swagger12)
|
||||
[![GoDoc](https://godoc.org/github.com/emicklei/go-restful-swagger12?status.svg)](https://godoc.org/github.com/emicklei/go-restful-swagger12)
|
||||
|
||||
How to use Swagger UI with go-restful
|
||||
=
|
||||
|
||||
Get the Swagger UI sources (version 1.2 only)
|
||||
|
||||
git clone https://github.com/wordnik/swagger-ui.git
|
||||
|
||||
The project contains a "dist" folder.
|
||||
Its contents has all the Swagger UI files you need.
|
||||
|
||||
The `index.html` has an `url` set to `http://petstore.swagger.wordnik.com/api/api-docs`.
|
||||
You need to change that to match your WebService JSON endpoint e.g. `http://localhost:8080/apidocs.json`
|
||||
|
||||
Now, you can install the Swagger WebService for serving the Swagger specification in JSON.
|
||||
|
||||
config := swagger.Config{
|
||||
WebServices: restful.RegisteredWebServices(),
|
||||
ApiPath: "/apidocs.json",
|
||||
SwaggerPath: "/apidocs/",
|
||||
SwaggerFilePath: "/Users/emicklei/Projects/swagger-ui/dist"}
|
||||
swagger.InstallSwaggerService(config)
|
||||
|
||||
|
||||
Documenting Structs
|
||||
--
|
||||
|
||||
Currently there are 2 ways to document your structs in the go-restful Swagger.
|
||||
|
||||
###### By using struct tags
|
||||
- Use tag "description" to annotate a struct field with a description to show in the UI
|
||||
- Use tag "modelDescription" to annotate the struct itself with a description to show in the UI. The tag can be added in an field of the struct and in case that there are multiple definition, they will be appended with an empty line.
|
||||
|
||||
###### By using the SwaggerDoc method
|
||||
Here is an example with an `Address` struct and the documentation for each of the fields. The `""` is a special entry for **documenting the struct itself**.
|
||||
|
||||
type Address struct {
|
||||
Country string `json:"country,omitempty"`
|
||||
PostCode int `json:"postcode,omitempty"`
|
||||
}
|
||||
|
||||
func (Address) SwaggerDoc() map[string]string {
|
||||
return map[string]string{
|
||||
"": "Address doc",
|
||||
"country": "Country doc",
|
||||
"postcode": "PostCode doc",
|
||||
}
|
||||
}
|
||||
|
||||
This example will generate a JSON like this
|
||||
|
||||
{
|
||||
"Address": {
|
||||
"id": "Address",
|
||||
"description": "Address doc",
|
||||
"properties": {
|
||||
"country": {
|
||||
"type": "string",
|
||||
"description": "Country doc"
|
||||
},
|
||||
"postcode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "PostCode doc"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
**Very Important Notes:**
|
||||
- `SwaggerDoc()` is using a **NON-Pointer** receiver (e.g. func (Address) and not func (*Address))
|
||||
- The returned map should use as key the name of the field as defined in the JSON parameter (e.g. `"postcode"` and not `"PostCode"`)
|
||||
|
||||
Notes
|
||||
--
|
||||
- The Nickname of an Operation is automatically set by finding the name of the function. You can override it using RouteBuilder.Operation(..)
|
||||
- The WebServices field of swagger.Config can be used to control which service you want to expose and document ; you can have multiple configs and therefore multiple endpoints.
|
||||
|
||||
© 2017, ernestmicklei.com. MIT License. Contributions welcome.
|
64
vendor/github.com/emicklei/go-restful-swagger12/api_declaration_list.go
generated
vendored
64
vendor/github.com/emicklei/go-restful-swagger12/api_declaration_list.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
package swagger
|
||||
|
||||
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||
// Use of this source code is governed by a license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// ApiDeclarationList maintains an ordered list of ApiDeclaration.
|
||||
type ApiDeclarationList struct {
|
||||
List []ApiDeclaration
|
||||
}
|
||||
|
||||
// At returns the ApiDeclaration by its path unless absent, then ok is false
|
||||
func (l *ApiDeclarationList) At(path string) (a ApiDeclaration, ok bool) {
|
||||
for _, each := range l.List {
|
||||
if each.ResourcePath == path {
|
||||
return each, true
|
||||
}
|
||||
}
|
||||
return a, false
|
||||
}
|
||||
|
||||
// Put adds or replaces a ApiDeclaration with this name
|
||||
func (l *ApiDeclarationList) Put(path string, a ApiDeclaration) {
|
||||
// maybe replace existing
|
||||
for i, each := range l.List {
|
||||
if each.ResourcePath == path {
|
||||
// replace
|
||||
l.List[i] = a
|
||||
return
|
||||
}
|
||||
}
|
||||
// add
|
||||
l.List = append(l.List, a)
|
||||
}
|
||||
|
||||
// Do enumerates all the properties, each with its assigned name
|
||||
func (l *ApiDeclarationList) Do(block func(path string, decl ApiDeclaration)) {
|
||||
for _, each := range l.List {
|
||||
block(each.ResourcePath, each)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON writes the ModelPropertyList as if it was a map[string]ModelProperty
|
||||
func (l ApiDeclarationList) MarshalJSON() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
encoder := json.NewEncoder(&buf)
|
||||
buf.WriteString("{\n")
|
||||
for i, each := range l.List {
|
||||
buf.WriteString("\"")
|
||||
buf.WriteString(each.ResourcePath)
|
||||
buf.WriteString("\": ")
|
||||
encoder.Encode(each)
|
||||
if i < len(l.List)-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
buf.WriteString("}")
|
||||
return buf.Bytes(), nil
|
||||
}
|
46
vendor/github.com/emicklei/go-restful-swagger12/config.go
generated
vendored
46
vendor/github.com/emicklei/go-restful-swagger12/config.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// PostBuildDeclarationMapFunc can be used to modify the api declaration map.
|
||||
type PostBuildDeclarationMapFunc func(apiDeclarationMap *ApiDeclarationList)
|
||||
|
||||
// MapSchemaFormatFunc can be used to modify typeName at definition time.
|
||||
type MapSchemaFormatFunc func(typeName string) string
|
||||
|
||||
// MapModelTypeNameFunc can be used to return the desired typeName for a given
|
||||
// type. It will return false if the default name should be used.
|
||||
type MapModelTypeNameFunc func(t reflect.Type) (string, bool)
|
||||
|
||||
type Config struct {
|
||||
// url where the services are available, e.g. http://localhost:8080
|
||||
// if left empty then the basePath of Swagger is taken from the actual request
|
||||
WebServicesUrl string
|
||||
// path where the JSON api is avaiable , e.g. /apidocs
|
||||
ApiPath string
|
||||
// [optional] path where the swagger UI will be served, e.g. /swagger
|
||||
SwaggerPath string
|
||||
// [optional] location of folder containing Swagger HTML5 application index.html
|
||||
SwaggerFilePath string
|
||||
// api listing is constructed from this list of restful WebServices.
|
||||
WebServices []*restful.WebService
|
||||
// will serve all static content (scripts,pages,images)
|
||||
StaticHandler http.Handler
|
||||
// [optional] on default CORS (Cross-Origin-Resource-Sharing) is enabled.
|
||||
DisableCORS bool
|
||||
// Top-level API version. Is reflected in the resource listing.
|
||||
ApiVersion string
|
||||
// If set then call this handler after building the complete ApiDeclaration Map
|
||||
PostBuildHandler PostBuildDeclarationMapFunc
|
||||
// Swagger global info struct
|
||||
Info Info
|
||||
// [optional] If set, model builder should call this handler to get addition typename-to-swagger-format-field conversion.
|
||||
SchemaFormatHandler MapSchemaFormatFunc
|
||||
// [optional] If set, model builder should call this handler to retrieve the name for a given type.
|
||||
ModelTypeNameHandler MapModelTypeNameFunc
|
||||
}
|
467
vendor/github.com/emicklei/go-restful-swagger12/model_builder.go
generated
vendored
467
vendor/github.com/emicklei/go-restful-swagger12/model_builder.go
generated
vendored
@ -1,467 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ModelBuildable is used for extending Structs that need more control over
|
||||
// how the Model appears in the Swagger api declaration.
|
||||
type ModelBuildable interface {
|
||||
PostBuildModel(m *Model) *Model
|
||||
}
|
||||
|
||||
type modelBuilder struct {
|
||||
Models *ModelList
|
||||
Config *Config
|
||||
}
|
||||
|
||||
type documentable interface {
|
||||
SwaggerDoc() map[string]string
|
||||
}
|
||||
|
||||
// Check if this structure has a method with signature func (<theModel>) SwaggerDoc() map[string]string
|
||||
// If it exists, retrive the documentation and overwrite all struct tag descriptions
|
||||
func getDocFromMethodSwaggerDoc2(model reflect.Type) map[string]string {
|
||||
if docable, ok := reflect.New(model).Elem().Interface().(documentable); ok {
|
||||
return docable.SwaggerDoc()
|
||||
}
|
||||
return make(map[string]string)
|
||||
}
|
||||
|
||||
// addModelFrom creates and adds a Model to the builder and detects and calls
|
||||
// the post build hook for customizations
|
||||
func (b modelBuilder) addModelFrom(sample interface{}) {
|
||||
if modelOrNil := b.addModel(reflect.TypeOf(sample), ""); modelOrNil != nil {
|
||||
// allow customizations
|
||||
if buildable, ok := sample.(ModelBuildable); ok {
|
||||
modelOrNil = buildable.PostBuildModel(modelOrNil)
|
||||
b.Models.Put(modelOrNil.Id, *modelOrNil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b modelBuilder) addModel(st reflect.Type, nameOverride string) *Model {
|
||||
// Turn pointers into simpler types so further checks are
|
||||
// correct.
|
||||
if st.Kind() == reflect.Ptr {
|
||||
st = st.Elem()
|
||||
}
|
||||
|
||||
modelName := b.keyFrom(st)
|
||||
if nameOverride != "" {
|
||||
modelName = nameOverride
|
||||
}
|
||||
// no models needed for primitive types
|
||||
if b.isPrimitiveType(modelName) {
|
||||
return nil
|
||||
}
|
||||
// golang encoding/json packages says array and slice values encode as
|
||||
// JSON arrays, except that []byte encodes as a base64-encoded string.
|
||||
// If we see a []byte here, treat it at as a primitive type (string)
|
||||
// and deal with it in buildArrayTypeProperty.
|
||||
if (st.Kind() == reflect.Slice || st.Kind() == reflect.Array) &&
|
||||
st.Elem().Kind() == reflect.Uint8 {
|
||||
return nil
|
||||
}
|
||||
// see if we already have visited this model
|
||||
if _, ok := b.Models.At(modelName); ok {
|
||||
return nil
|
||||
}
|
||||
sm := Model{
|
||||
Id: modelName,
|
||||
Required: []string{},
|
||||
Properties: ModelPropertyList{}}
|
||||
|
||||
// reference the model before further initializing (enables recursive structs)
|
||||
b.Models.Put(modelName, sm)
|
||||
|
||||
// check for slice or array
|
||||
if st.Kind() == reflect.Slice || st.Kind() == reflect.Array {
|
||||
b.addModel(st.Elem(), "")
|
||||
return &sm
|
||||
}
|
||||
// check for structure or primitive type
|
||||
if st.Kind() != reflect.Struct {
|
||||
return &sm
|
||||
}
|
||||
|
||||
fullDoc := getDocFromMethodSwaggerDoc2(st)
|
||||
modelDescriptions := []string{}
|
||||
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
field := st.Field(i)
|
||||
jsonName, modelDescription, prop := b.buildProperty(field, &sm, modelName)
|
||||
if len(modelDescription) > 0 {
|
||||
modelDescriptions = append(modelDescriptions, modelDescription)
|
||||
}
|
||||
|
||||
// add if not omitted
|
||||
if len(jsonName) != 0 {
|
||||
// update description
|
||||
if fieldDoc, ok := fullDoc[jsonName]; ok {
|
||||
prop.Description = fieldDoc
|
||||
}
|
||||
// update Required
|
||||
if b.isPropertyRequired(field) {
|
||||
sm.Required = append(sm.Required, jsonName)
|
||||
}
|
||||
sm.Properties.Put(jsonName, prop)
|
||||
}
|
||||
}
|
||||
|
||||
// We always overwrite documentation if SwaggerDoc method exists
|
||||
// "" is special for documenting the struct itself
|
||||
if modelDoc, ok := fullDoc[""]; ok {
|
||||
sm.Description = modelDoc
|
||||
} else if len(modelDescriptions) != 0 {
|
||||
sm.Description = strings.Join(modelDescriptions, "\n")
|
||||
}
|
||||
|
||||
// update model builder with completed model
|
||||
b.Models.Put(modelName, sm)
|
||||
|
||||
return &sm
|
||||
}
|
||||
|
||||
func (b modelBuilder) isPropertyRequired(field reflect.StructField) bool {
|
||||
required := true
|
||||
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
|
||||
s := strings.Split(jsonTag, ",")
|
||||
if len(s) > 1 && s[1] == "omitempty" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return required
|
||||
}
|
||||
|
||||
func (b modelBuilder) buildProperty(field reflect.StructField, model *Model, modelName string) (jsonName, modelDescription string, prop ModelProperty) {
|
||||
jsonName = b.jsonNameOfField(field)
|
||||
if len(jsonName) == 0 {
|
||||
// empty name signals skip property
|
||||
return "", "", prop
|
||||
}
|
||||
|
||||
if field.Name == "XMLName" && field.Type.String() == "xml.Name" {
|
||||
// property is metadata for the xml.Name attribute, can be skipped
|
||||
return "", "", prop
|
||||
}
|
||||
|
||||
if tag := field.Tag.Get("modelDescription"); tag != "" {
|
||||
modelDescription = tag
|
||||
}
|
||||
|
||||
prop.setPropertyMetadata(field)
|
||||
if prop.Type != nil {
|
||||
return jsonName, modelDescription, prop
|
||||
}
|
||||
fieldType := field.Type
|
||||
|
||||
// check if type is doing its own marshalling
|
||||
marshalerType := reflect.TypeOf((*json.Marshaler)(nil)).Elem()
|
||||
if fieldType.Implements(marshalerType) {
|
||||
var pType = "string"
|
||||
if prop.Type == nil {
|
||||
prop.Type = &pType
|
||||
}
|
||||
if prop.Format == "" {
|
||||
prop.Format = b.jsonSchemaFormat(b.keyFrom(fieldType))
|
||||
}
|
||||
return jsonName, modelDescription, prop
|
||||
}
|
||||
|
||||
// check if annotation says it is a string
|
||||
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
|
||||
s := strings.Split(jsonTag, ",")
|
||||
if len(s) > 1 && s[1] == "string" {
|
||||
stringt := "string"
|
||||
prop.Type = &stringt
|
||||
return jsonName, modelDescription, prop
|
||||
}
|
||||
}
|
||||
|
||||
fieldKind := fieldType.Kind()
|
||||
switch {
|
||||
case fieldKind == reflect.Struct:
|
||||
jsonName, prop := b.buildStructTypeProperty(field, jsonName, model)
|
||||
return jsonName, modelDescription, prop
|
||||
case fieldKind == reflect.Slice || fieldKind == reflect.Array:
|
||||
jsonName, prop := b.buildArrayTypeProperty(field, jsonName, modelName)
|
||||
return jsonName, modelDescription, prop
|
||||
case fieldKind == reflect.Ptr:
|
||||
jsonName, prop := b.buildPointerTypeProperty(field, jsonName, modelName)
|
||||
return jsonName, modelDescription, prop
|
||||
case fieldKind == reflect.String:
|
||||
stringt := "string"
|
||||
prop.Type = &stringt
|
||||
return jsonName, modelDescription, prop
|
||||
case fieldKind == reflect.Map:
|
||||
// if it's a map, it's unstructured, and swagger 1.2 can't handle it
|
||||
objectType := "object"
|
||||
prop.Type = &objectType
|
||||
return jsonName, modelDescription, prop
|
||||
}
|
||||
|
||||
fieldTypeName := b.keyFrom(fieldType)
|
||||
if b.isPrimitiveType(fieldTypeName) {
|
||||
mapped := b.jsonSchemaType(fieldTypeName)
|
||||
prop.Type = &mapped
|
||||
prop.Format = b.jsonSchemaFormat(fieldTypeName)
|
||||
return jsonName, modelDescription, prop
|
||||
}
|
||||
modelType := b.keyFrom(fieldType)
|
||||
prop.Ref = &modelType
|
||||
|
||||
if fieldType.Name() == "" { // override type of anonymous structs
|
||||
nestedTypeName := modelName + "." + jsonName
|
||||
prop.Ref = &nestedTypeName
|
||||
b.addModel(fieldType, nestedTypeName)
|
||||
}
|
||||
return jsonName, modelDescription, prop
|
||||
}
|
||||
|
||||
func hasNamedJSONTag(field reflect.StructField) bool {
|
||||
parts := strings.Split(field.Tag.Get("json"), ",")
|
||||
if len(parts) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, s := range parts[1:] {
|
||||
if s == "inline" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return len(parts[0]) > 0
|
||||
}
|
||||
|
||||
func (b modelBuilder) buildStructTypeProperty(field reflect.StructField, jsonName string, model *Model) (nameJson string, prop ModelProperty) {
|
||||
prop.setPropertyMetadata(field)
|
||||
// Check for type override in tag
|
||||
if prop.Type != nil {
|
||||
return jsonName, prop
|
||||
}
|
||||
fieldType := field.Type
|
||||
// check for anonymous
|
||||
if len(fieldType.Name()) == 0 {
|
||||
// anonymous
|
||||
anonType := model.Id + "." + jsonName
|
||||
b.addModel(fieldType, anonType)
|
||||
prop.Ref = &anonType
|
||||
return jsonName, prop
|
||||
}
|
||||
|
||||
if field.Name == fieldType.Name() && field.Anonymous && !hasNamedJSONTag(field) {
|
||||
// embedded struct
|
||||
sub := modelBuilder{new(ModelList), b.Config}
|
||||
sub.addModel(fieldType, "")
|
||||
subKey := sub.keyFrom(fieldType)
|
||||
// merge properties from sub
|
||||
subModel, _ := sub.Models.At(subKey)
|
||||
subModel.Properties.Do(func(k string, v ModelProperty) {
|
||||
model.Properties.Put(k, v)
|
||||
// if subModel says this property is required then include it
|
||||
required := false
|
||||
for _, each := range subModel.Required {
|
||||
if k == each {
|
||||
required = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if required {
|
||||
model.Required = append(model.Required, k)
|
||||
}
|
||||
})
|
||||
// add all new referenced models
|
||||
sub.Models.Do(func(key string, sub Model) {
|
||||
if key != subKey {
|
||||
if _, ok := b.Models.At(key); !ok {
|
||||
b.Models.Put(key, sub)
|
||||
}
|
||||
}
|
||||
})
|
||||
// empty name signals skip property
|
||||
return "", prop
|
||||
}
|
||||
// simple struct
|
||||
b.addModel(fieldType, "")
|
||||
var pType = b.keyFrom(fieldType)
|
||||
prop.Ref = &pType
|
||||
return jsonName, prop
|
||||
}
|
||||
|
||||
func (b modelBuilder) buildArrayTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop ModelProperty) {
|
||||
// check for type override in tags
|
||||
prop.setPropertyMetadata(field)
|
||||
if prop.Type != nil {
|
||||
return jsonName, prop
|
||||
}
|
||||
fieldType := field.Type
|
||||
if fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
stringt := "string"
|
||||
prop.Type = &stringt
|
||||
return jsonName, prop
|
||||
}
|
||||
var pType = "array"
|
||||
prop.Type = &pType
|
||||
isPrimitive := b.isPrimitiveType(fieldType.Elem().Name())
|
||||
elemTypeName := b.getElementTypeName(modelName, jsonName, fieldType.Elem())
|
||||
prop.Items = new(Item)
|
||||
if isPrimitive {
|
||||
mapped := b.jsonSchemaType(elemTypeName)
|
||||
prop.Items.Type = &mapped
|
||||
} else {
|
||||
prop.Items.Ref = &elemTypeName
|
||||
}
|
||||
// add|overwrite model for element type
|
||||
if fieldType.Elem().Kind() == reflect.Ptr {
|
||||
fieldType = fieldType.Elem()
|
||||
}
|
||||
if !isPrimitive {
|
||||
b.addModel(fieldType.Elem(), elemTypeName)
|
||||
}
|
||||
return jsonName, prop
|
||||
}
|
||||
|
||||
func (b modelBuilder) buildPointerTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop ModelProperty) {
|
||||
prop.setPropertyMetadata(field)
|
||||
// Check for type override in tags
|
||||
if prop.Type != nil {
|
||||
return jsonName, prop
|
||||
}
|
||||
fieldType := field.Type
|
||||
|
||||
// override type of pointer to list-likes
|
||||
if fieldType.Elem().Kind() == reflect.Slice || fieldType.Elem().Kind() == reflect.Array {
|
||||
var pType = "array"
|
||||
prop.Type = &pType
|
||||
isPrimitive := b.isPrimitiveType(fieldType.Elem().Elem().Name())
|
||||
elemName := b.getElementTypeName(modelName, jsonName, fieldType.Elem().Elem())
|
||||
if isPrimitive {
|
||||
primName := b.jsonSchemaType(elemName)
|
||||
prop.Items = &Item{Ref: &primName}
|
||||
} else {
|
||||
prop.Items = &Item{Ref: &elemName}
|
||||
}
|
||||
if !isPrimitive {
|
||||
// add|overwrite model for element type
|
||||
b.addModel(fieldType.Elem().Elem(), elemName)
|
||||
}
|
||||
} else {
|
||||
// non-array, pointer type
|
||||
fieldTypeName := b.keyFrom(fieldType.Elem())
|
||||
var pType = b.jsonSchemaType(fieldTypeName) // no star, include pkg path
|
||||
if b.isPrimitiveType(fieldTypeName) {
|
||||
prop.Type = &pType
|
||||
prop.Format = b.jsonSchemaFormat(fieldTypeName)
|
||||
return jsonName, prop
|
||||
}
|
||||
prop.Ref = &pType
|
||||
elemName := ""
|
||||
if fieldType.Elem().Name() == "" {
|
||||
elemName = modelName + "." + jsonName
|
||||
prop.Ref = &elemName
|
||||
}
|
||||
b.addModel(fieldType.Elem(), elemName)
|
||||
}
|
||||
return jsonName, prop
|
||||
}
|
||||
|
||||
func (b modelBuilder) getElementTypeName(modelName, jsonName string, t reflect.Type) string {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Name() == "" {
|
||||
return modelName + "." + jsonName
|
||||
}
|
||||
return b.keyFrom(t)
|
||||
}
|
||||
|
||||
func (b modelBuilder) keyFrom(st reflect.Type) string {
|
||||
key := st.String()
|
||||
if b.Config != nil && b.Config.ModelTypeNameHandler != nil {
|
||||
if name, ok := b.Config.ModelTypeNameHandler(st); ok {
|
||||
key = name
|
||||
}
|
||||
}
|
||||
if len(st.Name()) == 0 { // unnamed type
|
||||
// Swagger UI has special meaning for [
|
||||
key = strings.Replace(key, "[]", "||", -1)
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// see also https://golang.org/ref/spec#Numeric_types
|
||||
func (b modelBuilder) isPrimitiveType(modelName string) bool {
|
||||
if len(modelName) == 0 {
|
||||
return false
|
||||
}
|
||||
return strings.Contains("uint uint8 uint16 uint32 uint64 int int8 int16 int32 int64 float32 float64 bool string byte rune time.Time", modelName)
|
||||
}
|
||||
|
||||
// jsonNameOfField returns the name of the field as it should appear in JSON format
|
||||
// An empty string indicates that this field is not part of the JSON representation
|
||||
func (b modelBuilder) jsonNameOfField(field reflect.StructField) string {
|
||||
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
|
||||
s := strings.Split(jsonTag, ",")
|
||||
if s[0] == "-" {
|
||||
// empty name signals skip property
|
||||
return ""
|
||||
} else if s[0] != "" {
|
||||
return s[0]
|
||||
}
|
||||
}
|
||||
return field.Name
|
||||
}
|
||||
|
||||
// see also http://json-schema.org/latest/json-schema-core.html#anchor8
|
||||
func (b modelBuilder) jsonSchemaType(modelName string) string {
|
||||
schemaMap := map[string]string{
|
||||
"uint": "integer",
|
||||
"uint8": "integer",
|
||||
"uint16": "integer",
|
||||
"uint32": "integer",
|
||||
"uint64": "integer",
|
||||
|
||||
"int": "integer",
|
||||
"int8": "integer",
|
||||
"int16": "integer",
|
||||
"int32": "integer",
|
||||
"int64": "integer",
|
||||
|
||||
"byte": "integer",
|
||||
"float64": "number",
|
||||
"float32": "number",
|
||||
"bool": "boolean",
|
||||
"time.Time": "string",
|
||||
}
|
||||
mapped, ok := schemaMap[modelName]
|
||||
if !ok {
|
||||
return modelName // use as is (custom or struct)
|
||||
}
|
||||
return mapped
|
||||
}
|
||||
|
||||
func (b modelBuilder) jsonSchemaFormat(modelName string) string {
|
||||
if b.Config != nil && b.Config.SchemaFormatHandler != nil {
|
||||
if mapped := b.Config.SchemaFormatHandler(modelName); mapped != "" {
|
||||
return mapped
|
||||
}
|
||||
}
|
||||
schemaMap := map[string]string{
|
||||
"int": "int32",
|
||||
"int32": "int32",
|
||||
"int64": "int64",
|
||||
"byte": "byte",
|
||||
"uint": "integer",
|
||||
"uint8": "byte",
|
||||
"float64": "double",
|
||||
"float32": "float",
|
||||
"time.Time": "date-time",
|
||||
"*time.Time": "date-time",
|
||||
}
|
||||
mapped, ok := schemaMap[modelName]
|
||||
if !ok {
|
||||
return "" // no format
|
||||
}
|
||||
return mapped
|
||||
}
|
1283
vendor/github.com/emicklei/go-restful-swagger12/model_builder_test.go
generated
vendored
1283
vendor/github.com/emicklei/go-restful-swagger12/model_builder_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
86
vendor/github.com/emicklei/go-restful-swagger12/model_list.go
generated
vendored
86
vendor/github.com/emicklei/go-restful-swagger12/model_list.go
generated
vendored
@ -1,86 +0,0 @@
|
||||
package swagger
|
||||
|
||||
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||
// Use of this source code is governed by a license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// NamedModel associates a name with a Model (not using its Id)
|
||||
type NamedModel struct {
|
||||
Name string
|
||||
Model Model
|
||||
}
|
||||
|
||||
// ModelList encapsulates a list of NamedModel (association)
|
||||
type ModelList struct {
|
||||
List []NamedModel
|
||||
}
|
||||
|
||||
// Put adds or replaces a Model by its name
|
||||
func (l *ModelList) Put(name string, model Model) {
|
||||
for i, each := range l.List {
|
||||
if each.Name == name {
|
||||
// replace
|
||||
l.List[i] = NamedModel{name, model}
|
||||
return
|
||||
}
|
||||
}
|
||||
// add
|
||||
l.List = append(l.List, NamedModel{name, model})
|
||||
}
|
||||
|
||||
// At returns a Model by its name, ok is false if absent
|
||||
func (l *ModelList) At(name string) (m Model, ok bool) {
|
||||
for _, each := range l.List {
|
||||
if each.Name == name {
|
||||
return each.Model, true
|
||||
}
|
||||
}
|
||||
return m, false
|
||||
}
|
||||
|
||||
// Do enumerates all the models, each with its assigned name
|
||||
func (l *ModelList) Do(block func(name string, value Model)) {
|
||||
for _, each := range l.List {
|
||||
block(each.Name, each.Model)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON writes the ModelList as if it was a map[string]Model
|
||||
func (l ModelList) MarshalJSON() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
encoder := json.NewEncoder(&buf)
|
||||
buf.WriteString("{\n")
|
||||
for i, each := range l.List {
|
||||
buf.WriteString("\"")
|
||||
buf.WriteString(each.Name)
|
||||
buf.WriteString("\": ")
|
||||
encoder.Encode(each.Model)
|
||||
if i < len(l.List)-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
buf.WriteString("}")
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON reads back a ModelList. This is an expensive operation.
|
||||
func (l *ModelList) UnmarshalJSON(data []byte) error {
|
||||
raw := map[string]interface{}{}
|
||||
json.NewDecoder(bytes.NewReader(data)).Decode(&raw)
|
||||
for k, v := range raw {
|
||||
// produces JSON bytes for each value
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var m Model
|
||||
json.NewDecoder(bytes.NewReader(data)).Decode(&m)
|
||||
l.Put(k, m)
|
||||
}
|
||||
return nil
|
||||
}
|
48
vendor/github.com/emicklei/go-restful-swagger12/model_list_test.go
generated
vendored
48
vendor/github.com/emicklei/go-restful-swagger12/model_list_test.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestModelList(t *testing.T) {
|
||||
m := Model{}
|
||||
m.Id = "m"
|
||||
l := ModelList{}
|
||||
l.Put("m", m)
|
||||
k, ok := l.At("m")
|
||||
if !ok {
|
||||
t.Error("want model back")
|
||||
}
|
||||
if got, want := k.Id, "m"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModelList_Marshal(t *testing.T) {
|
||||
l := ModelList{}
|
||||
m := Model{Id: "myid"}
|
||||
l.Put("myid", m)
|
||||
data, err := json.Marshal(l)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if got, want := string(data), `{"myid":{"id":"myid","properties":{}}}`; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModelList_Unmarshal(t *testing.T) {
|
||||
data := `{"myid":{"id":"myid","properties":{}}}`
|
||||
l := ModelList{}
|
||||
if err := json.Unmarshal([]byte(data), &l); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
m, ok := l.At("myid")
|
||||
if !ok {
|
||||
t.Error("expected myid")
|
||||
}
|
||||
if got, want := m.Id, "myid"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
81
vendor/github.com/emicklei/go-restful-swagger12/model_property_ext.go
generated
vendored
81
vendor/github.com/emicklei/go-restful-swagger12/model_property_ext.go
generated
vendored
@ -1,81 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (prop *ModelProperty) setDescription(field reflect.StructField) {
|
||||
if tag := field.Tag.Get("description"); tag != "" {
|
||||
prop.Description = tag
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setDefaultValue(field reflect.StructField) {
|
||||
if tag := field.Tag.Get("default"); tag != "" {
|
||||
prop.DefaultValue = Special(tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setEnumValues(field reflect.StructField) {
|
||||
// We use | to separate the enum values. This value is chosen
|
||||
// since its unlikely to be useful in actual enumeration values.
|
||||
if tag := field.Tag.Get("enum"); tag != "" {
|
||||
prop.Enum = strings.Split(tag, "|")
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setMaximum(field reflect.StructField) {
|
||||
if tag := field.Tag.Get("maximum"); tag != "" {
|
||||
prop.Maximum = tag
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setType(field reflect.StructField) {
|
||||
if tag := field.Tag.Get("type"); tag != "" {
|
||||
// Check if the first two characters of the type tag are
|
||||
// intended to emulate slice/array behaviour.
|
||||
//
|
||||
// If type is intended to be a slice/array then add the
|
||||
// overriden type to the array item instead of the main property
|
||||
if len(tag) > 2 && tag[0:2] == "[]" {
|
||||
pType := "array"
|
||||
prop.Type = &pType
|
||||
prop.Items = new(Item)
|
||||
|
||||
iType := tag[2:]
|
||||
prop.Items.Type = &iType
|
||||
return
|
||||
}
|
||||
|
||||
prop.Type = &tag
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setMinimum(field reflect.StructField) {
|
||||
if tag := field.Tag.Get("minimum"); tag != "" {
|
||||
prop.Minimum = tag
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setUniqueItems(field reflect.StructField) {
|
||||
tag := field.Tag.Get("unique")
|
||||
switch tag {
|
||||
case "true":
|
||||
v := true
|
||||
prop.UniqueItems = &v
|
||||
case "false":
|
||||
v := false
|
||||
prop.UniqueItems = &v
|
||||
}
|
||||
}
|
||||
|
||||
func (prop *ModelProperty) setPropertyMetadata(field reflect.StructField) {
|
||||
prop.setDescription(field)
|
||||
prop.setEnumValues(field)
|
||||
prop.setMinimum(field)
|
||||
prop.setMaximum(field)
|
||||
prop.setUniqueItems(field)
|
||||
prop.setDefaultValue(field)
|
||||
prop.setType(field)
|
||||
}
|
70
vendor/github.com/emicklei/go-restful-swagger12/model_property_ext_test.go
generated
vendored
70
vendor/github.com/emicklei/go-restful-swagger12/model_property_ext_test.go
generated
vendored
@ -1,70 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// clear && go test -v -test.run TestThatExtraTagsAreReadIntoModel ...swagger
|
||||
func TestThatExtraTagsAreReadIntoModel(t *testing.T) {
|
||||
type fakeint int
|
||||
type fakearray string
|
||||
type Anything struct {
|
||||
Name string `description:"name" modelDescription:"a test"`
|
||||
Size int `minimum:"0" maximum:"10"`
|
||||
Stati string `enum:"off|on" default:"on" modelDescription:"more description"`
|
||||
ID string `unique:"true"`
|
||||
FakeInt fakeint `type:"integer"`
|
||||
FakeArray fakearray `type:"[]string"`
|
||||
IP net.IP `type:"string"`
|
||||
Password string
|
||||
}
|
||||
m := modelsFromStruct(Anything{})
|
||||
props, _ := m.At("swagger.Anything")
|
||||
p1, _ := props.Properties.At("Name")
|
||||
if got, want := p1.Description, "name"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p2, _ := props.Properties.At("Size")
|
||||
if got, want := p2.Minimum, "0"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
if got, want := p2.Maximum, "10"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p3, _ := props.Properties.At("Stati")
|
||||
if got, want := p3.Enum[0], "off"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
if got, want := p3.Enum[1], "on"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p4, _ := props.Properties.At("ID")
|
||||
if got, want := *p4.UniqueItems, true; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p5, _ := props.Properties.At("Password")
|
||||
if got, want := *p5.Type, "string"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p6, _ := props.Properties.At("FakeInt")
|
||||
if got, want := *p6.Type, "integer"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p7, _ := props.Properties.At("FakeArray")
|
||||
if got, want := *p7.Type, "array"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p7p, _ := props.Properties.At("FakeArray")
|
||||
if got, want := *p7p.Items.Type, "string"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
p8, _ := props.Properties.At("IP")
|
||||
if got, want := *p8.Type, "string"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
|
||||
if got, want := props.Description, "a test\nmore description"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
87
vendor/github.com/emicklei/go-restful-swagger12/model_property_list.go
generated
vendored
87
vendor/github.com/emicklei/go-restful-swagger12/model_property_list.go
generated
vendored
@ -1,87 +0,0 @@
|
||||
package swagger
|
||||
|
||||
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||
// Use of this source code is governed by a license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// NamedModelProperty associates a name to a ModelProperty
|
||||
type NamedModelProperty struct {
|
||||
Name string
|
||||
Property ModelProperty
|
||||
}
|
||||
|
||||
// ModelPropertyList encapsulates a list of NamedModelProperty (association)
|
||||
type ModelPropertyList struct {
|
||||
List []NamedModelProperty
|
||||
}
|
||||
|
||||
// At returns the ModelPropety by its name unless absent, then ok is false
|
||||
func (l *ModelPropertyList) At(name string) (p ModelProperty, ok bool) {
|
||||
for _, each := range l.List {
|
||||
if each.Name == name {
|
||||
return each.Property, true
|
||||
}
|
||||
}
|
||||
return p, false
|
||||
}
|
||||
|
||||
// Put adds or replaces a ModelProperty with this name
|
||||
func (l *ModelPropertyList) Put(name string, prop ModelProperty) {
|
||||
// maybe replace existing
|
||||
for i, each := range l.List {
|
||||
if each.Name == name {
|
||||
// replace
|
||||
l.List[i] = NamedModelProperty{Name: name, Property: prop}
|
||||
return
|
||||
}
|
||||
}
|
||||
// add
|
||||
l.List = append(l.List, NamedModelProperty{Name: name, Property: prop})
|
||||
}
|
||||
|
||||
// Do enumerates all the properties, each with its assigned name
|
||||
func (l *ModelPropertyList) Do(block func(name string, value ModelProperty)) {
|
||||
for _, each := range l.List {
|
||||
block(each.Name, each.Property)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON writes the ModelPropertyList as if it was a map[string]ModelProperty
|
||||
func (l ModelPropertyList) MarshalJSON() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
encoder := json.NewEncoder(&buf)
|
||||
buf.WriteString("{\n")
|
||||
for i, each := range l.List {
|
||||
buf.WriteString("\"")
|
||||
buf.WriteString(each.Name)
|
||||
buf.WriteString("\": ")
|
||||
encoder.Encode(each.Property)
|
||||
if i < len(l.List)-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
buf.WriteString("}")
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON reads back a ModelPropertyList. This is an expensive operation.
|
||||
func (l *ModelPropertyList) UnmarshalJSON(data []byte) error {
|
||||
raw := map[string]interface{}{}
|
||||
json.NewDecoder(bytes.NewReader(data)).Decode(&raw)
|
||||
for k, v := range raw {
|
||||
// produces JSON bytes for each value
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var m ModelProperty
|
||||
json.NewDecoder(bytes.NewReader(data)).Decode(&m)
|
||||
l.Put(k, m)
|
||||
}
|
||||
return nil
|
||||
}
|
47
vendor/github.com/emicklei/go-restful-swagger12/model_property_list_test.go
generated
vendored
47
vendor/github.com/emicklei/go-restful-swagger12/model_property_list_test.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestModelPropertyList(t *testing.T) {
|
||||
l := ModelPropertyList{}
|
||||
p := ModelProperty{Description: "d"}
|
||||
l.Put("p", p)
|
||||
q, ok := l.At("p")
|
||||
if !ok {
|
||||
t.Error("expected p")
|
||||
}
|
||||
if got, want := q.Description, "d"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModelPropertyList_Marshal(t *testing.T) {
|
||||
l := ModelPropertyList{}
|
||||
p := ModelProperty{Description: "d"}
|
||||
l.Put("p", p)
|
||||
data, err := json.Marshal(l)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if got, want := string(data), `{"p":{"description":"d"}}`; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModelPropertyList_Unmarshal(t *testing.T) {
|
||||
data := `{"p":{"description":"d"}}`
|
||||
l := ModelPropertyList{}
|
||||
if err := json.Unmarshal([]byte(data), &l); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
m, ok := l.At("p")
|
||||
if !ok {
|
||||
t.Error("expected p")
|
||||
}
|
||||
if got, want := m.Description, "d"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
36
vendor/github.com/emicklei/go-restful-swagger12/ordered_route_map.go
generated
vendored
36
vendor/github.com/emicklei/go-restful-swagger12/ordered_route_map.go
generated
vendored
@ -1,36 +0,0 @@
|
||||
package swagger
|
||||
|
||||
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||
// Use of this source code is governed by a license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
import "github.com/emicklei/go-restful"
|
||||
|
||||
type orderedRouteMap struct {
|
||||
elements map[string][]restful.Route
|
||||
keys []string
|
||||
}
|
||||
|
||||
func newOrderedRouteMap() *orderedRouteMap {
|
||||
return &orderedRouteMap{
|
||||
elements: map[string][]restful.Route{},
|
||||
keys: []string{},
|
||||
}
|
||||
}
|
||||
|
||||
func (o *orderedRouteMap) Add(key string, route restful.Route) {
|
||||
routes, ok := o.elements[key]
|
||||
if ok {
|
||||
routes = append(routes, route)
|
||||
o.elements[key] = routes
|
||||
return
|
||||
}
|
||||
o.elements[key] = []restful.Route{route}
|
||||
o.keys = append(o.keys, key)
|
||||
}
|
||||
|
||||
func (o *orderedRouteMap) Do(block func(key string, routes []restful.Route)) {
|
||||
for _, k := range o.keys {
|
||||
block(k, o.elements[k])
|
||||
}
|
||||
}
|
29
vendor/github.com/emicklei/go-restful-swagger12/ordered_route_map_test.go
generated
vendored
29
vendor/github.com/emicklei/go-restful-swagger12/ordered_route_map_test.go
generated
vendored
@ -1,29 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// go test -v -test.run TestOrderedRouteMap ...swagger
|
||||
func TestOrderedRouteMap(t *testing.T) {
|
||||
m := newOrderedRouteMap()
|
||||
r1 := restful.Route{Path: "/r1"}
|
||||
r2 := restful.Route{Path: "/r2"}
|
||||
m.Add("a", r1)
|
||||
m.Add("b", r2)
|
||||
m.Add("b", r1)
|
||||
m.Add("d", r2)
|
||||
m.Add("c", r2)
|
||||
order := ""
|
||||
m.Do(func(k string, routes []restful.Route) {
|
||||
order += k
|
||||
if len(routes) == 0 {
|
||||
t.Fail()
|
||||
}
|
||||
})
|
||||
if order != "abdc" {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
42
vendor/github.com/emicklei/go-restful-swagger12/postbuild_model_test.go
generated
vendored
42
vendor/github.com/emicklei/go-restful-swagger12/postbuild_model_test.go
generated
vendored
@ -1,42 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import "testing"
|
||||
|
||||
type Boat struct {
|
||||
Length int `json:"-"` // on default, this makes the fields not required
|
||||
Weight int `json:"-"`
|
||||
}
|
||||
|
||||
// PostBuildModel is from swagger.ModelBuildable
|
||||
func (b Boat) PostBuildModel(m *Model) *Model {
|
||||
// override required
|
||||
m.Required = []string{"Length", "Weight"}
|
||||
|
||||
// add model property (just to test is can be added; is this a real usecase?)
|
||||
extraType := "string"
|
||||
m.Properties.Put("extra", ModelProperty{
|
||||
Description: "extra description",
|
||||
DataTypeFields: DataTypeFields{
|
||||
Type: &extraType,
|
||||
},
|
||||
})
|
||||
return m
|
||||
}
|
||||
|
||||
func TestCustomPostModelBuilde(t *testing.T) {
|
||||
testJsonFromStruct(t, Boat{}, `{
|
||||
"swagger.Boat": {
|
||||
"id": "swagger.Boat",
|
||||
"required": [
|
||||
"Length",
|
||||
"Weight"
|
||||
],
|
||||
"properties": {
|
||||
"extra": {
|
||||
"type": "string",
|
||||
"description": "extra description"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
}
|
185
vendor/github.com/emicklei/go-restful-swagger12/swagger.go
generated
vendored
185
vendor/github.com/emicklei/go-restful-swagger12/swagger.go
generated
vendored
@ -1,185 +0,0 @@
|
||||
// Package swagger implements the structures of the Swagger
|
||||
// https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md
|
||||
package swagger
|
||||
|
||||
const swaggerVersion = "1.2"
|
||||
|
||||
// 4.3.3 Data Type Fields
|
||||
type DataTypeFields struct {
|
||||
Type *string `json:"type,omitempty"` // if Ref not used
|
||||
Ref *string `json:"$ref,omitempty"` // if Type not used
|
||||
Format string `json:"format,omitempty"`
|
||||
DefaultValue Special `json:"defaultValue,omitempty"`
|
||||
Enum []string `json:"enum,omitempty"`
|
||||
Minimum string `json:"minimum,omitempty"`
|
||||
Maximum string `json:"maximum,omitempty"`
|
||||
Items *Item `json:"items,omitempty"`
|
||||
UniqueItems *bool `json:"uniqueItems,omitempty"`
|
||||
}
|
||||
|
||||
type Special string
|
||||
|
||||
// 4.3.4 Items Object
|
||||
type Item struct {
|
||||
Type *string `json:"type,omitempty"`
|
||||
Ref *string `json:"$ref,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
}
|
||||
|
||||
// 5.1 Resource Listing
|
||||
type ResourceListing struct {
|
||||
SwaggerVersion string `json:"swaggerVersion"` // e.g 1.2
|
||||
Apis []Resource `json:"apis"`
|
||||
ApiVersion string `json:"apiVersion"`
|
||||
Info Info `json:"info"`
|
||||
Authorizations []Authorization `json:"authorizations,omitempty"`
|
||||
}
|
||||
|
||||
// 5.1.2 Resource Object
|
||||
type Resource struct {
|
||||
Path string `json:"path"` // relative or absolute, must start with /
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// 5.1.3 Info Object
|
||||
type Info struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
TermsOfServiceUrl string `json:"termsOfServiceUrl,omitempty"`
|
||||
Contact string `json:"contact,omitempty"`
|
||||
License string `json:"license,omitempty"`
|
||||
LicenseUrl string `json:"licenseUrl,omitempty"`
|
||||
}
|
||||
|
||||
// 5.1.5
|
||||
type Authorization struct {
|
||||
Type string `json:"type"`
|
||||
PassAs string `json:"passAs"`
|
||||
Keyname string `json:"keyname"`
|
||||
Scopes []Scope `json:"scopes"`
|
||||
GrantTypes []GrantType `json:"grandTypes"`
|
||||
}
|
||||
|
||||
// 5.1.6, 5.2.11
|
||||
type Scope struct {
|
||||
// Required. The name of the scope.
|
||||
Scope string `json:"scope"`
|
||||
// Recommended. A short description of the scope.
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// 5.1.7
|
||||
type GrantType struct {
|
||||
Implicit Implicit `json:"implicit"`
|
||||
AuthorizationCode AuthorizationCode `json:"authorization_code"`
|
||||
}
|
||||
|
||||
// 5.1.8 Implicit Object
|
||||
type Implicit struct {
|
||||
// Required. The login endpoint definition.
|
||||
loginEndpoint LoginEndpoint `json:"loginEndpoint"`
|
||||
// An optional alternative name to standard "access_token" OAuth2 parameter.
|
||||
TokenName string `json:"tokenName"`
|
||||
}
|
||||
|
||||
// 5.1.9 Authorization Code Object
|
||||
type AuthorizationCode struct {
|
||||
TokenRequestEndpoint TokenRequestEndpoint `json:"tokenRequestEndpoint"`
|
||||
TokenEndpoint TokenEndpoint `json:"tokenEndpoint"`
|
||||
}
|
||||
|
||||
// 5.1.10 Login Endpoint Object
|
||||
type LoginEndpoint struct {
|
||||
// Required. The URL of the authorization endpoint for the implicit grant flow. The value SHOULD be in a URL format.
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
// 5.1.11 Token Request Endpoint Object
|
||||
type TokenRequestEndpoint struct {
|
||||
// Required. The URL of the authorization endpoint for the authentication code grant flow. The value SHOULD be in a URL format.
|
||||
Url string `json:"url"`
|
||||
// An optional alternative name to standard "client_id" OAuth2 parameter.
|
||||
ClientIdName string `json:"clientIdName"`
|
||||
// An optional alternative name to the standard "client_secret" OAuth2 parameter.
|
||||
ClientSecretName string `json:"clientSecretName"`
|
||||
}
|
||||
|
||||
// 5.1.12 Token Endpoint Object
|
||||
type TokenEndpoint struct {
|
||||
// Required. The URL of the token endpoint for the authentication code grant flow. The value SHOULD be in a URL format.
|
||||
Url string `json:"url"`
|
||||
// An optional alternative name to standard "access_token" OAuth2 parameter.
|
||||
TokenName string `json:"tokenName"`
|
||||
}
|
||||
|
||||
// 5.2 API Declaration
|
||||
type ApiDeclaration struct {
|
||||
SwaggerVersion string `json:"swaggerVersion"`
|
||||
ApiVersion string `json:"apiVersion"`
|
||||
BasePath string `json:"basePath"`
|
||||
ResourcePath string `json:"resourcePath"` // must start with /
|
||||
Info Info `json:"info"`
|
||||
Apis []Api `json:"apis,omitempty"`
|
||||
Models ModelList `json:"models,omitempty"`
|
||||
Produces []string `json:"produces,omitempty"`
|
||||
Consumes []string `json:"consumes,omitempty"`
|
||||
Authorizations []Authorization `json:"authorizations,omitempty"`
|
||||
}
|
||||
|
||||
// 5.2.2 API Object
|
||||
type Api struct {
|
||||
Path string `json:"path"` // relative or absolute, must start with /
|
||||
Description string `json:"description"`
|
||||
Operations []Operation `json:"operations,omitempty"`
|
||||
}
|
||||
|
||||
// 5.2.3 Operation Object
|
||||
type Operation struct {
|
||||
DataTypeFields
|
||||
Method string `json:"method"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
Nickname string `json:"nickname"`
|
||||
Authorizations []Authorization `json:"authorizations,omitempty"`
|
||||
Parameters []Parameter `json:"parameters"`
|
||||
ResponseMessages []ResponseMessage `json:"responseMessages,omitempty"` // optional
|
||||
Produces []string `json:"produces,omitempty"`
|
||||
Consumes []string `json:"consumes,omitempty"`
|
||||
Deprecated string `json:"deprecated,omitempty"`
|
||||
}
|
||||
|
||||
// 5.2.4 Parameter Object
|
||||
type Parameter struct {
|
||||
DataTypeFields
|
||||
ParamType string `json:"paramType"` // path,query,body,header,form
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Required bool `json:"required"`
|
||||
AllowMultiple bool `json:"allowMultiple"`
|
||||
}
|
||||
|
||||
// 5.2.5 Response Message Object
|
||||
type ResponseMessage struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
ResponseModel string `json:"responseModel,omitempty"`
|
||||
}
|
||||
|
||||
// 5.2.6, 5.2.7 Models Object
|
||||
type Model struct {
|
||||
Id string `json:"id"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Required []string `json:"required,omitempty"`
|
||||
Properties ModelPropertyList `json:"properties"`
|
||||
SubTypes []string `json:"subTypes,omitempty"`
|
||||
Discriminator string `json:"discriminator,omitempty"`
|
||||
}
|
||||
|
||||
// 5.2.8 Properties Object
|
||||
type ModelProperty struct {
|
||||
DataTypeFields
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// 5.2.10
|
||||
type Authorizations map[string]Authorization
|
21
vendor/github.com/emicklei/go-restful-swagger12/swagger_builder.go
generated
vendored
21
vendor/github.com/emicklei/go-restful-swagger12/swagger_builder.go
generated
vendored
@ -1,21 +0,0 @@
|
||||
package swagger
|
||||
|
||||
type SwaggerBuilder struct {
|
||||
SwaggerService
|
||||
}
|
||||
|
||||
func NewSwaggerBuilder(config Config) *SwaggerBuilder {
|
||||
return &SwaggerBuilder{*newSwaggerService(config)}
|
||||
}
|
||||
|
||||
func (sb SwaggerBuilder) ProduceListing() ResourceListing {
|
||||
return sb.SwaggerService.produceListing()
|
||||
}
|
||||
|
||||
func (sb SwaggerBuilder) ProduceAllDeclarations() map[string]ApiDeclaration {
|
||||
return sb.SwaggerService.produceAllDeclarations()
|
||||
}
|
||||
|
||||
func (sb SwaggerBuilder) ProduceDeclarations(route string) (*ApiDeclaration, bool) {
|
||||
return sb.SwaggerService.produceDeclarations(route)
|
||||
}
|
318
vendor/github.com/emicklei/go-restful-swagger12/swagger_test.go
generated
vendored
318
vendor/github.com/emicklei/go-restful-swagger12/swagger_test.go
generated
vendored
@ -1,318 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12/test_package"
|
||||
)
|
||||
|
||||
func TestInfoStruct_Issue231(t *testing.T) {
|
||||
config := Config{
|
||||
Info: Info{
|
||||
Title: "Title",
|
||||
Description: "Description",
|
||||
TermsOfServiceUrl: "http://example.com",
|
||||
Contact: "example@example.com",
|
||||
License: "License",
|
||||
LicenseUrl: "http://example.com/license.txt",
|
||||
},
|
||||
}
|
||||
sws := newSwaggerService(config)
|
||||
str, err := json.MarshalIndent(sws.produceListing(), "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
compareJson(t, string(str), `
|
||||
{
|
||||
"apiVersion": "",
|
||||
"swaggerVersion": "1.2",
|
||||
"apis": null,
|
||||
"info": {
|
||||
"title": "Title",
|
||||
"description": "Description",
|
||||
"termsOfServiceUrl": "http://example.com",
|
||||
"contact": "example@example.com",
|
||||
"license": "License",
|
||||
"licenseUrl": "http://example.com/license.txt"
|
||||
}
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
// go test -v -test.run TestThatMultiplePathsOnRootAreHandled ...swagger
|
||||
func TestThatMultiplePathsOnRootAreHandled(t *testing.T) {
|
||||
ws1 := new(restful.WebService)
|
||||
ws1.Route(ws1.GET("/_ping").To(dummy))
|
||||
ws1.Route(ws1.GET("/version").To(dummy))
|
||||
|
||||
cfg := Config{
|
||||
WebServicesUrl: "http://here.com",
|
||||
ApiPath: "/apipath",
|
||||
WebServices: []*restful.WebService{ws1},
|
||||
}
|
||||
sws := newSwaggerService(cfg)
|
||||
decl := sws.composeDeclaration(ws1, "/")
|
||||
if got, want := len(decl.Apis), 2; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteSamples(t *testing.T) {
|
||||
ws1 := new(restful.WebService)
|
||||
ws1.Route(ws1.GET("/object").To(dummy).Writes(test_package.TestStruct{}))
|
||||
ws1.Route(ws1.GET("/array").To(dummy).Writes([]test_package.TestStruct{}))
|
||||
ws1.Route(ws1.GET("/object_and_array").To(dummy).Writes(struct{ Abc test_package.TestStruct }{}))
|
||||
|
||||
cfg := Config{
|
||||
WebServicesUrl: "http://here.com",
|
||||
ApiPath: "/apipath",
|
||||
WebServices: []*restful.WebService{ws1},
|
||||
}
|
||||
sws := newSwaggerService(cfg)
|
||||
|
||||
decl := sws.composeDeclaration(ws1, "/")
|
||||
|
||||
str, err := json.MarshalIndent(decl.Apis, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
compareJson(t, string(str), `
|
||||
[
|
||||
{
|
||||
"path": "/object",
|
||||
"description": "",
|
||||
"operations": [
|
||||
{
|
||||
"type": "test_package.TestStruct",
|
||||
"method": "GET",
|
||||
"nickname": "dummy",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/array",
|
||||
"description": "",
|
||||
"operations": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "test_package.TestStruct"
|
||||
},
|
||||
"method": "GET",
|
||||
"nickname": "dummy",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/object_and_array",
|
||||
"description": "",
|
||||
"operations": [
|
||||
{
|
||||
"type": "struct { Abc test_package.TestStruct }",
|
||||
"method": "GET",
|
||||
"nickname": "dummy",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]`)
|
||||
|
||||
str, err = json.MarshalIndent(decl.Models, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
compareJson(t, string(str), `
|
||||
{
|
||||
"test_package.TestStruct": {
|
||||
"id": "test_package.TestStruct",
|
||||
"required": [
|
||||
"TestField"
|
||||
],
|
||||
"properties": {
|
||||
"TestField": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"||test_package.TestStruct": {
|
||||
"id": "||test_package.TestStruct",
|
||||
"properties": {}
|
||||
},
|
||||
"struct { Abc test_package.TestStruct }": {
|
||||
"id": "struct { Abc test_package.TestStruct }",
|
||||
"required": [
|
||||
"Abc"
|
||||
],
|
||||
"properties": {
|
||||
"Abc": {
|
||||
"$ref": "test_package.TestStruct"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
}
|
||||
|
||||
func TestRoutesWithCommonPart(t *testing.T) {
|
||||
ws1 := new(restful.WebService)
|
||||
ws1.Path("/")
|
||||
ws1.Route(ws1.GET("/foobar").To(dummy).Writes(test_package.TestStruct{}))
|
||||
ws1.Route(ws1.HEAD("/foobar").To(dummy).Writes(test_package.TestStruct{}))
|
||||
ws1.Route(ws1.GET("/foo").To(dummy).Writes([]test_package.TestStruct{}))
|
||||
ws1.Route(ws1.HEAD("/foo").To(dummy).Writes(test_package.TestStruct{}))
|
||||
|
||||
cfg := Config{
|
||||
WebServicesUrl: "http://here.com",
|
||||
ApiPath: "/apipath",
|
||||
WebServices: []*restful.WebService{ws1},
|
||||
}
|
||||
sws := newSwaggerService(cfg)
|
||||
|
||||
decl := sws.composeDeclaration(ws1, "/foo")
|
||||
|
||||
str, err := json.MarshalIndent(decl.Apis, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
compareJson(t, string(str), `[
|
||||
{
|
||||
"path": "/foo",
|
||||
"description": "",
|
||||
"operations": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "test_package.TestStruct"
|
||||
},
|
||||
"method": "GET",
|
||||
"nickname": "dummy",
|
||||
"parameters": []
|
||||
},
|
||||
{
|
||||
"type": "test_package.TestStruct",
|
||||
"method": "HEAD",
|
||||
"nickname": "dummy",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]`)
|
||||
}
|
||||
|
||||
// go test -v -test.run TestServiceToApi ...swagger
|
||||
func TestServiceToApi(t *testing.T) {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path("/tests")
|
||||
ws.Consumes(restful.MIME_JSON)
|
||||
ws.Produces(restful.MIME_XML)
|
||||
ws.Route(ws.GET("/a").To(dummy).Writes(sample{}))
|
||||
ws.Route(ws.PUT("/b").To(dummy).Writes(sample{}))
|
||||
ws.Route(ws.POST("/c").To(dummy).Writes(sample{}))
|
||||
ws.Route(ws.DELETE("/d").To(dummy).Writes(sample{}))
|
||||
|
||||
ws.Route(ws.GET("/d").To(dummy).Writes(sample{}))
|
||||
ws.Route(ws.PUT("/c").To(dummy).Writes(sample{}))
|
||||
ws.Route(ws.POST("/b").To(dummy).Writes(sample{}))
|
||||
ws.Route(ws.DELETE("/a").To(dummy).Writes(sample{}))
|
||||
ws.ApiVersion("1.2.3")
|
||||
cfg := Config{
|
||||
WebServicesUrl: "http://here.com",
|
||||
ApiPath: "/apipath",
|
||||
WebServices: []*restful.WebService{ws},
|
||||
PostBuildHandler: func(in *ApiDeclarationList) {},
|
||||
}
|
||||
sws := newSwaggerService(cfg)
|
||||
decl := sws.composeDeclaration(ws, "/tests")
|
||||
// checks
|
||||
if decl.ApiVersion != "1.2.3" {
|
||||
t.Errorf("got %v want %v", decl.ApiVersion, "1.2.3")
|
||||
}
|
||||
if decl.BasePath != "http://here.com" {
|
||||
t.Errorf("got %v want %v", decl.BasePath, "http://here.com")
|
||||
}
|
||||
if len(decl.Apis) != 4 {
|
||||
t.Errorf("got %v want %v", len(decl.Apis), 4)
|
||||
}
|
||||
pathOrder := ""
|
||||
for _, each := range decl.Apis {
|
||||
pathOrder += each.Path
|
||||
for _, other := range each.Operations {
|
||||
pathOrder += other.Method
|
||||
}
|
||||
}
|
||||
|
||||
if pathOrder != "/tests/aGETDELETE/tests/bPUTPOST/tests/cPOSTPUT/tests/dDELETEGET" {
|
||||
t.Errorf("got %v want %v", pathOrder, "see test source")
|
||||
}
|
||||
}
|
||||
|
||||
func dummy(i *restful.Request, o *restful.Response) {}
|
||||
|
||||
// go test -v -test.run TestIssue78 ...swagger
|
||||
type Response struct {
|
||||
Code int
|
||||
Users *[]User
|
||||
Items *[]TestItem
|
||||
}
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
type TestItem struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestComposeResponseMessages ...swagger
|
||||
func TestComposeResponseMessages(t *testing.T) {
|
||||
responseErrors := map[int]restful.ResponseError{}
|
||||
responseErrors[400] = restful.ResponseError{Code: 400, Message: "Bad Request", Model: TestItem{}}
|
||||
route := restful.Route{ResponseErrors: responseErrors}
|
||||
decl := new(ApiDeclaration)
|
||||
decl.Models = ModelList{}
|
||||
msgs := composeResponseMessages(route, decl, &Config{})
|
||||
if msgs[0].ResponseModel != "swagger.TestItem" {
|
||||
t.Errorf("got %s want swagger.TestItem", msgs[0].ResponseModel)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue78(t *testing.T) {
|
||||
sws := newSwaggerService(Config{})
|
||||
models := new(ModelList)
|
||||
sws.addModelFromSampleTo(&Operation{}, true, Response{Items: &[]TestItem{}}, models)
|
||||
model, ok := models.At("swagger.Response")
|
||||
if !ok {
|
||||
t.Fatal("missing response model")
|
||||
}
|
||||
if "swagger.Response" != model.Id {
|
||||
t.Fatal("wrong model id:" + model.Id)
|
||||
}
|
||||
code, ok := model.Properties.At("Code")
|
||||
if !ok {
|
||||
t.Fatal("missing code")
|
||||
}
|
||||
if "integer" != *code.Type {
|
||||
t.Fatal("wrong code type:" + *code.Type)
|
||||
}
|
||||
items, ok := model.Properties.At("Items")
|
||||
if !ok {
|
||||
t.Fatal("missing items")
|
||||
}
|
||||
if "array" != *items.Type {
|
||||
t.Fatal("wrong items type:" + *items.Type)
|
||||
}
|
||||
items_items := items.Items
|
||||
if items_items == nil {
|
||||
t.Fatal("missing items->items")
|
||||
}
|
||||
ref := items_items.Ref
|
||||
if ref == nil {
|
||||
t.Fatal("missing $ref")
|
||||
}
|
||||
if *ref != "swagger.TestItem" {
|
||||
t.Fatal("wrong $ref:" + *ref)
|
||||
}
|
||||
}
|
443
vendor/github.com/emicklei/go-restful-swagger12/swagger_webservice.go
generated
vendored
443
vendor/github.com/emicklei/go-restful-swagger12/swagger_webservice.go
generated
vendored
@ -1,443 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
// "github.com/emicklei/hopwatch"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/emicklei/go-restful/log"
|
||||
)
|
||||
|
||||
type SwaggerService struct {
|
||||
config Config
|
||||
apiDeclarationMap *ApiDeclarationList
|
||||
}
|
||||
|
||||
func newSwaggerService(config Config) *SwaggerService {
|
||||
sws := &SwaggerService{
|
||||
config: config,
|
||||
apiDeclarationMap: new(ApiDeclarationList)}
|
||||
|
||||
// Build all ApiDeclarations
|
||||
for _, each := range config.WebServices {
|
||||
rootPath := each.RootPath()
|
||||
// skip the api service itself
|
||||
if rootPath != config.ApiPath {
|
||||
if rootPath == "" || rootPath == "/" {
|
||||
// use routes
|
||||
for _, route := range each.Routes() {
|
||||
entry := staticPathFromRoute(route)
|
||||
_, exists := sws.apiDeclarationMap.At(entry)
|
||||
if !exists {
|
||||
sws.apiDeclarationMap.Put(entry, sws.composeDeclaration(each, entry))
|
||||
}
|
||||
}
|
||||
} else { // use root path
|
||||
sws.apiDeclarationMap.Put(each.RootPath(), sws.composeDeclaration(each, each.RootPath()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if specified then call the PostBuilderHandler
|
||||
if config.PostBuildHandler != nil {
|
||||
config.PostBuildHandler(sws.apiDeclarationMap)
|
||||
}
|
||||
return sws
|
||||
}
|
||||
|
||||
// LogInfo is the function that is called when this package needs to log. It defaults to log.Printf
|
||||
var LogInfo = func(format string, v ...interface{}) {
|
||||
// use the restful package-wide logger
|
||||
log.Printf(format, v...)
|
||||
}
|
||||
|
||||
// InstallSwaggerService add the WebService that provides the API documentation of all services
|
||||
// conform the Swagger documentation specifcation. (https://github.com/wordnik/swagger-core/wiki).
|
||||
func InstallSwaggerService(aSwaggerConfig Config) {
|
||||
RegisterSwaggerService(aSwaggerConfig, restful.DefaultContainer)
|
||||
}
|
||||
|
||||
// RegisterSwaggerService add the WebService that provides the API documentation of all services
|
||||
// conform the Swagger documentation specifcation. (https://github.com/wordnik/swagger-core/wiki).
|
||||
func RegisterSwaggerService(config Config, wsContainer *restful.Container) {
|
||||
sws := newSwaggerService(config)
|
||||
ws := new(restful.WebService)
|
||||
ws.Path(config.ApiPath)
|
||||
ws.Produces(restful.MIME_JSON)
|
||||
if config.DisableCORS {
|
||||
ws.Filter(enableCORS)
|
||||
}
|
||||
ws.Route(ws.GET("/").To(sws.getListing))
|
||||
ws.Route(ws.GET("/{a}").To(sws.getDeclarations))
|
||||
ws.Route(ws.GET("/{a}/{b}").To(sws.getDeclarations))
|
||||
ws.Route(ws.GET("/{a}/{b}/{c}").To(sws.getDeclarations))
|
||||
ws.Route(ws.GET("/{a}/{b}/{c}/{d}").To(sws.getDeclarations))
|
||||
ws.Route(ws.GET("/{a}/{b}/{c}/{d}/{e}").To(sws.getDeclarations))
|
||||
ws.Route(ws.GET("/{a}/{b}/{c}/{d}/{e}/{f}").To(sws.getDeclarations))
|
||||
ws.Route(ws.GET("/{a}/{b}/{c}/{d}/{e}/{f}/{g}").To(sws.getDeclarations))
|
||||
LogInfo("[restful/swagger] listing is available at %v%v", config.WebServicesUrl, config.ApiPath)
|
||||
wsContainer.Add(ws)
|
||||
|
||||
// Check paths for UI serving
|
||||
if config.StaticHandler == nil && config.SwaggerFilePath != "" && config.SwaggerPath != "" {
|
||||
swaggerPathSlash := config.SwaggerPath
|
||||
// path must end with slash /
|
||||
if "/" != config.SwaggerPath[len(config.SwaggerPath)-1:] {
|
||||
LogInfo("[restful/swagger] use corrected SwaggerPath ; must end with slash (/)")
|
||||
swaggerPathSlash += "/"
|
||||
}
|
||||
|
||||
LogInfo("[restful/swagger] %v%v is mapped to folder %v", config.WebServicesUrl, swaggerPathSlash, config.SwaggerFilePath)
|
||||
wsContainer.Handle(swaggerPathSlash, http.StripPrefix(swaggerPathSlash, http.FileServer(http.Dir(config.SwaggerFilePath))))
|
||||
|
||||
//if we define a custom static handler use it
|
||||
} else if config.StaticHandler != nil && config.SwaggerPath != "" {
|
||||
swaggerPathSlash := config.SwaggerPath
|
||||
// path must end with slash /
|
||||
if "/" != config.SwaggerPath[len(config.SwaggerPath)-1:] {
|
||||
LogInfo("[restful/swagger] use corrected SwaggerFilePath ; must end with slash (/)")
|
||||
swaggerPathSlash += "/"
|
||||
|
||||
}
|
||||
LogInfo("[restful/swagger] %v%v is mapped to custom Handler %T", config.WebServicesUrl, swaggerPathSlash, config.StaticHandler)
|
||||
wsContainer.Handle(swaggerPathSlash, config.StaticHandler)
|
||||
|
||||
} else {
|
||||
LogInfo("[restful/swagger] Swagger(File)Path is empty ; no UI is served")
|
||||
}
|
||||
}
|
||||
|
||||
func staticPathFromRoute(r restful.Route) string {
|
||||
static := r.Path
|
||||
bracket := strings.Index(static, "{")
|
||||
if bracket <= 1 { // result cannot be empty
|
||||
return static
|
||||
}
|
||||
if bracket != -1 {
|
||||
static = r.Path[:bracket]
|
||||
}
|
||||
if strings.HasSuffix(static, "/") {
|
||||
return static[:len(static)-1]
|
||||
} else {
|
||||
return static
|
||||
}
|
||||
}
|
||||
|
||||
func enableCORS(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
if origin := req.HeaderParameter(restful.HEADER_Origin); origin != "" {
|
||||
// prevent duplicate header
|
||||
if len(resp.Header().Get(restful.HEADER_AccessControlAllowOrigin)) == 0 {
|
||||
resp.AddHeader(restful.HEADER_AccessControlAllowOrigin, origin)
|
||||
}
|
||||
}
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
func (sws SwaggerService) getListing(req *restful.Request, resp *restful.Response) {
|
||||
listing := sws.produceListing()
|
||||
resp.WriteAsJson(listing)
|
||||
}
|
||||
|
||||
func (sws SwaggerService) produceListing() ResourceListing {
|
||||
listing := ResourceListing{SwaggerVersion: swaggerVersion, ApiVersion: sws.config.ApiVersion, Info: sws.config.Info}
|
||||
sws.apiDeclarationMap.Do(func(k string, v ApiDeclaration) {
|
||||
ref := Resource{Path: k}
|
||||
if len(v.Apis) > 0 { // use description of first (could still be empty)
|
||||
ref.Description = v.Apis[0].Description
|
||||
}
|
||||
listing.Apis = append(listing.Apis, ref)
|
||||
})
|
||||
return listing
|
||||
}
|
||||
|
||||
func (sws SwaggerService) getDeclarations(req *restful.Request, resp *restful.Response) {
|
||||
decl, ok := sws.produceDeclarations(composeRootPath(req))
|
||||
if !ok {
|
||||
resp.WriteErrorString(http.StatusNotFound, "ApiDeclaration not found")
|
||||
return
|
||||
}
|
||||
// unless WebServicesUrl is given
|
||||
if len(sws.config.WebServicesUrl) == 0 {
|
||||
// update base path from the actual request
|
||||
// TODO how to detect https? assume http for now
|
||||
var host string
|
||||
// X-Forwarded-Host or Host or Request.Host
|
||||
hostvalues, ok := req.Request.Header["X-Forwarded-Host"] // apache specific?
|
||||
if !ok || len(hostvalues) == 0 {
|
||||
forwarded, ok := req.Request.Header["Host"] // without reverse-proxy
|
||||
if !ok || len(forwarded) == 0 {
|
||||
// fallback to Host field
|
||||
host = req.Request.Host
|
||||
} else {
|
||||
host = forwarded[0]
|
||||
}
|
||||
} else {
|
||||
host = hostvalues[0]
|
||||
}
|
||||
// inspect Referer for the scheme (http vs https)
|
||||
scheme := "http"
|
||||
if referer := req.Request.Header["Referer"]; len(referer) > 0 {
|
||||
if strings.HasPrefix(referer[0], "https") {
|
||||
scheme = "https"
|
||||
}
|
||||
}
|
||||
decl.BasePath = fmt.Sprintf("%s://%s", scheme, host)
|
||||
}
|
||||
resp.WriteAsJson(decl)
|
||||
}
|
||||
|
||||
func (sws SwaggerService) produceAllDeclarations() map[string]ApiDeclaration {
|
||||
decls := map[string]ApiDeclaration{}
|
||||
sws.apiDeclarationMap.Do(func(k string, v ApiDeclaration) {
|
||||
decls[k] = v
|
||||
})
|
||||
return decls
|
||||
}
|
||||
|
||||
func (sws SwaggerService) produceDeclarations(route string) (*ApiDeclaration, bool) {
|
||||
decl, ok := sws.apiDeclarationMap.At(route)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
decl.BasePath = sws.config.WebServicesUrl
|
||||
return &decl, true
|
||||
}
|
||||
|
||||
// composeDeclaration uses all routes and parameters to create a ApiDeclaration
|
||||
func (sws SwaggerService) composeDeclaration(ws *restful.WebService, pathPrefix string) ApiDeclaration {
|
||||
decl := ApiDeclaration{
|
||||
SwaggerVersion: swaggerVersion,
|
||||
BasePath: sws.config.WebServicesUrl,
|
||||
ResourcePath: pathPrefix,
|
||||
Models: ModelList{},
|
||||
ApiVersion: ws.Version()}
|
||||
|
||||
// collect any path parameters
|
||||
rootParams := []Parameter{}
|
||||
for _, param := range ws.PathParameters() {
|
||||
rootParams = append(rootParams, asSwaggerParameter(param.Data()))
|
||||
}
|
||||
// aggregate by path
|
||||
pathToRoutes := newOrderedRouteMap()
|
||||
for _, other := range ws.Routes() {
|
||||
if strings.HasPrefix(other.Path, pathPrefix) {
|
||||
if len(pathPrefix) > 1 && len(other.Path) > len(pathPrefix) && other.Path[len(pathPrefix)] != '/' {
|
||||
continue
|
||||
}
|
||||
pathToRoutes.Add(other.Path, other)
|
||||
}
|
||||
}
|
||||
pathToRoutes.Do(func(path string, routes []restful.Route) {
|
||||
api := Api{Path: strings.TrimSuffix(withoutWildcard(path), "/"), Description: ws.Documentation()}
|
||||
voidString := "void"
|
||||
for _, route := range routes {
|
||||
operation := Operation{
|
||||
Method: route.Method,
|
||||
Summary: route.Doc,
|
||||
Notes: route.Notes,
|
||||
// Type gets overwritten if there is a write sample
|
||||
DataTypeFields: DataTypeFields{Type: &voidString},
|
||||
Parameters: []Parameter{},
|
||||
Nickname: route.Operation,
|
||||
ResponseMessages: composeResponseMessages(route, &decl, &sws.config)}
|
||||
|
||||
operation.Consumes = route.Consumes
|
||||
operation.Produces = route.Produces
|
||||
|
||||
// share root params if any
|
||||
for _, swparam := range rootParams {
|
||||
operation.Parameters = append(operation.Parameters, swparam)
|
||||
}
|
||||
// route specific params
|
||||
for _, param := range route.ParameterDocs {
|
||||
operation.Parameters = append(operation.Parameters, asSwaggerParameter(param.Data()))
|
||||
}
|
||||
|
||||
sws.addModelsFromRouteTo(&operation, route, &decl)
|
||||
api.Operations = append(api.Operations, operation)
|
||||
}
|
||||
decl.Apis = append(decl.Apis, api)
|
||||
})
|
||||
return decl
|
||||
}
|
||||
|
||||
func withoutWildcard(path string) string {
|
||||
if strings.HasSuffix(path, ":*}") {
|
||||
return path[0:len(path)-3] + "}"
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// composeResponseMessages takes the ResponseErrors (if any) and creates ResponseMessages from them.
|
||||
func composeResponseMessages(route restful.Route, decl *ApiDeclaration, config *Config) (messages []ResponseMessage) {
|
||||
if route.ResponseErrors == nil {
|
||||
return messages
|
||||
}
|
||||
// sort by code
|
||||
codes := sort.IntSlice{}
|
||||
for code := range route.ResponseErrors {
|
||||
codes = append(codes, code)
|
||||
}
|
||||
codes.Sort()
|
||||
for _, code := range codes {
|
||||
each := route.ResponseErrors[code]
|
||||
message := ResponseMessage{
|
||||
Code: code,
|
||||
Message: each.Message,
|
||||
}
|
||||
if each.Model != nil {
|
||||
st := reflect.TypeOf(each.Model)
|
||||
isCollection, st := detectCollectionType(st)
|
||||
// collection cannot be in responsemodel
|
||||
if !isCollection {
|
||||
modelName := modelBuilder{}.keyFrom(st)
|
||||
modelBuilder{Models: &decl.Models, Config: config}.addModel(st, "")
|
||||
message.ResponseModel = modelName
|
||||
}
|
||||
}
|
||||
messages = append(messages, message)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// addModelsFromRoute takes any read or write sample from the Route and creates a Swagger model from it.
|
||||
func (sws SwaggerService) addModelsFromRouteTo(operation *Operation, route restful.Route, decl *ApiDeclaration) {
|
||||
if route.ReadSample != nil {
|
||||
sws.addModelFromSampleTo(operation, false, route.ReadSample, &decl.Models)
|
||||
}
|
||||
if route.WriteSample != nil {
|
||||
sws.addModelFromSampleTo(operation, true, route.WriteSample, &decl.Models)
|
||||
}
|
||||
}
|
||||
|
||||
func detectCollectionType(st reflect.Type) (bool, reflect.Type) {
|
||||
isCollection := false
|
||||
if st.Kind() == reflect.Slice || st.Kind() == reflect.Array {
|
||||
st = st.Elem()
|
||||
isCollection = true
|
||||
} else {
|
||||
if st.Kind() == reflect.Ptr {
|
||||
if st.Elem().Kind() == reflect.Slice || st.Elem().Kind() == reflect.Array {
|
||||
st = st.Elem().Elem()
|
||||
isCollection = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return isCollection, st
|
||||
}
|
||||
|
||||
// addModelFromSample creates and adds (or overwrites) a Model from a sample resource
|
||||
func (sws SwaggerService) addModelFromSampleTo(operation *Operation, isResponse bool, sample interface{}, models *ModelList) {
|
||||
mb := modelBuilder{Models: models, Config: &sws.config}
|
||||
if isResponse {
|
||||
sampleType, items := asDataType(sample, &sws.config)
|
||||
operation.Type = sampleType
|
||||
operation.Items = items
|
||||
}
|
||||
mb.addModelFrom(sample)
|
||||
}
|
||||
|
||||
func asSwaggerParameter(param restful.ParameterData) Parameter {
|
||||
return Parameter{
|
||||
DataTypeFields: DataTypeFields{
|
||||
Type: ¶m.DataType,
|
||||
Format: asFormat(param.DataType, param.DataFormat),
|
||||
DefaultValue: Special(param.DefaultValue),
|
||||
},
|
||||
Name: param.Name,
|
||||
Description: param.Description,
|
||||
ParamType: asParamType(param.Kind),
|
||||
|
||||
Required: param.Required}
|
||||
}
|
||||
|
||||
// Between 1..7 path parameters is supported
|
||||
func composeRootPath(req *restful.Request) string {
|
||||
path := "/" + req.PathParameter("a")
|
||||
b := req.PathParameter("b")
|
||||
if b == "" {
|
||||
return path
|
||||
}
|
||||
path = path + "/" + b
|
||||
c := req.PathParameter("c")
|
||||
if c == "" {
|
||||
return path
|
||||
}
|
||||
path = path + "/" + c
|
||||
d := req.PathParameter("d")
|
||||
if d == "" {
|
||||
return path
|
||||
}
|
||||
path = path + "/" + d
|
||||
e := req.PathParameter("e")
|
||||
if e == "" {
|
||||
return path
|
||||
}
|
||||
path = path + "/" + e
|
||||
f := req.PathParameter("f")
|
||||
if f == "" {
|
||||
return path
|
||||
}
|
||||
path = path + "/" + f
|
||||
g := req.PathParameter("g")
|
||||
if g == "" {
|
||||
return path
|
||||
}
|
||||
return path + "/" + g
|
||||
}
|
||||
|
||||
func asFormat(dataType string, dataFormat string) string {
|
||||
if dataFormat != "" {
|
||||
return dataFormat
|
||||
}
|
||||
return "" // TODO
|
||||
}
|
||||
|
||||
func asParamType(kind int) string {
|
||||
switch {
|
||||
case kind == restful.PathParameterKind:
|
||||
return "path"
|
||||
case kind == restful.QueryParameterKind:
|
||||
return "query"
|
||||
case kind == restful.BodyParameterKind:
|
||||
return "body"
|
||||
case kind == restful.HeaderParameterKind:
|
||||
return "header"
|
||||
case kind == restful.FormParameterKind:
|
||||
return "form"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func asDataType(any interface{}, config *Config) (*string, *Item) {
|
||||
// If it's not a collection, return the suggested model name
|
||||
st := reflect.TypeOf(any)
|
||||
isCollection, st := detectCollectionType(st)
|
||||
modelName := modelBuilder{}.keyFrom(st)
|
||||
// if it's not a collection we are done
|
||||
if !isCollection {
|
||||
return &modelName, nil
|
||||
}
|
||||
|
||||
// XXX: This is not very elegant
|
||||
// We create an Item object referring to the given model
|
||||
models := ModelList{}
|
||||
mb := modelBuilder{Models: &models, Config: config}
|
||||
mb.addModelFrom(any)
|
||||
|
||||
elemTypeName := mb.getElementTypeName(modelName, "", st)
|
||||
item := new(Item)
|
||||
if mb.isPrimitiveType(elemTypeName) {
|
||||
mapped := mb.jsonSchemaType(elemTypeName)
|
||||
item.Type = &mapped
|
||||
} else {
|
||||
item.Ref = &elemTypeName
|
||||
}
|
||||
tmp := "array"
|
||||
return &tmp, item
|
||||
}
|
5
vendor/github.com/emicklei/go-restful-swagger12/test_package/struct.go
generated
vendored
5
vendor/github.com/emicklei/go-restful-swagger12/test_package/struct.go
generated
vendored
@ -1,5 +0,0 @@
|
||||
package test_package
|
||||
|
||||
type TestStruct struct {
|
||||
TestField string
|
||||
}
|
86
vendor/github.com/emicklei/go-restful-swagger12/utils_test.go
generated
vendored
86
vendor/github.com/emicklei/go-restful-swagger12/utils_test.go
generated
vendored
@ -1,86 +0,0 @@
|
||||
package swagger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testJsonFromStructWithConfig(t *testing.T, sample interface{}, expectedJson string, config *Config) bool {
|
||||
m := modelsFromStructWithConfig(sample, config)
|
||||
data, _ := json.MarshalIndent(m, " ", " ")
|
||||
return compareJson(t, string(data), expectedJson)
|
||||
}
|
||||
|
||||
func modelsFromStructWithConfig(sample interface{}, config *Config) *ModelList {
|
||||
models := new(ModelList)
|
||||
builder := modelBuilder{Models: models, Config: config}
|
||||
builder.addModelFrom(sample)
|
||||
return models
|
||||
}
|
||||
|
||||
func testJsonFromStruct(t *testing.T, sample interface{}, expectedJson string) bool {
|
||||
return testJsonFromStructWithConfig(t, sample, expectedJson, &Config{})
|
||||
}
|
||||
|
||||
func modelsFromStruct(sample interface{}) *ModelList {
|
||||
return modelsFromStructWithConfig(sample, &Config{})
|
||||
}
|
||||
|
||||
func compareJson(t *testing.T, actualJsonAsString string, expectedJsonAsString string) bool {
|
||||
success := false
|
||||
var actualMap map[string]interface{}
|
||||
json.Unmarshal([]byte(actualJsonAsString), &actualMap)
|
||||
var expectedMap map[string]interface{}
|
||||
err := json.Unmarshal([]byte(expectedJsonAsString), &expectedMap)
|
||||
if err != nil {
|
||||
var actualArray []interface{}
|
||||
json.Unmarshal([]byte(actualJsonAsString), &actualArray)
|
||||
var expectedArray []interface{}
|
||||
err := json.Unmarshal([]byte(expectedJsonAsString), &expectedArray)
|
||||
success = reflect.DeepEqual(actualArray, expectedArray)
|
||||
if err != nil {
|
||||
t.Fatalf("Unparsable expected JSON: %s, actual: %v, expected: %v", err, actualJsonAsString, expectedJsonAsString)
|
||||
}
|
||||
} else {
|
||||
success = reflect.DeepEqual(actualMap, expectedMap)
|
||||
}
|
||||
if !success {
|
||||
t.Log("---- expected -----")
|
||||
t.Log(withLineNumbers(expectedJsonAsString))
|
||||
t.Log("---- actual -----")
|
||||
t.Log(withLineNumbers(actualJsonAsString))
|
||||
t.Log("---- raw -----")
|
||||
t.Log(actualJsonAsString)
|
||||
t.Error("there are differences")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func indexOfNonMatchingLine(actual, expected string) int {
|
||||
a := strings.Split(actual, "\n")
|
||||
e := strings.Split(expected, "\n")
|
||||
size := len(a)
|
||||
if len(e) < len(a) {
|
||||
size = len(e)
|
||||
}
|
||||
for i := 0; i < size; i++ {
|
||||
if a[i] != e[i] {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func withLineNumbers(content string) string {
|
||||
var buffer bytes.Buffer
|
||||
lines := strings.Split(content, "\n")
|
||||
for i, each := range lines {
|
||||
buffer.WriteString(fmt.Sprintf("%d:%s\n", i, each))
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
51
vendor/github.com/emicklei/go-restful/bench_curly_test.go
generated
vendored
51
vendor/github.com/emicklei/go-restful/bench_curly_test.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setupCurly(container *Container) []string {
|
||||
wsCount := 26
|
||||
rtCount := 26
|
||||
urisCurly := []string{}
|
||||
|
||||
container.Router(CurlyRouter{})
|
||||
for i := 0; i < wsCount; i++ {
|
||||
root := fmt.Sprintf("/%s/{%s}/", string(i+97), string(i+97))
|
||||
ws := new(WebService).Path(root)
|
||||
for j := 0; j < rtCount; j++ {
|
||||
sub := fmt.Sprintf("/%s2/{%s2}", string(j+97), string(j+97))
|
||||
ws.Route(ws.GET(sub).Consumes("application/xml").Produces("application/xml").To(echoCurly))
|
||||
}
|
||||
container.Add(ws)
|
||||
for _, each := range ws.Routes() {
|
||||
urisCurly = append(urisCurly, "http://bench.com"+each.Path)
|
||||
}
|
||||
}
|
||||
return urisCurly
|
||||
}
|
||||
|
||||
func echoCurly(req *Request, resp *Response) {}
|
||||
|
||||
func BenchmarkManyCurly(b *testing.B) {
|
||||
container := NewContainer()
|
||||
urisCurly := setupCurly(container)
|
||||
b.ResetTimer()
|
||||
for t := 0; t < b.N; t++ {
|
||||
for r := 0; r < 1000; r++ {
|
||||
for _, each := range urisCurly {
|
||||
sendNoReturnTo(each, container, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendNoReturnTo(address string, container *Container, t int) {
|
||||
httpRequest, _ := http.NewRequest("GET", address, nil)
|
||||
httpRequest.Header.Set("Accept", "application/xml")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
container.dispatch(httpWriter, httpRequest)
|
||||
}
|
43
vendor/github.com/emicklei/go-restful/bench_test.go
generated
vendored
43
vendor/github.com/emicklei/go-restful/bench_test.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var uris = []string{}
|
||||
|
||||
func setup(container *Container) {
|
||||
wsCount := 26
|
||||
rtCount := 26
|
||||
|
||||
for i := 0; i < wsCount; i++ {
|
||||
root := fmt.Sprintf("/%s/{%s}/", string(i+97), string(i+97))
|
||||
ws := new(WebService).Path(root)
|
||||
for j := 0; j < rtCount; j++ {
|
||||
sub := fmt.Sprintf("/%s2/{%s2}", string(j+97), string(j+97))
|
||||
ws.Route(ws.GET(sub).To(echo))
|
||||
}
|
||||
container.Add(ws)
|
||||
for _, each := range ws.Routes() {
|
||||
uris = append(uris, "http://bench.com"+each.Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func echo(req *Request, resp *Response) {
|
||||
io.WriteString(resp.ResponseWriter, "echo")
|
||||
}
|
||||
|
||||
func BenchmarkMany(b *testing.B) {
|
||||
container := NewContainer()
|
||||
setup(container)
|
||||
b.ResetTimer()
|
||||
for t := 0; t < b.N; t++ {
|
||||
for _, each := range uris {
|
||||
// println(each)
|
||||
sendItTo(each, container)
|
||||
}
|
||||
}
|
||||
}
|
125
vendor/github.com/emicklei/go-restful/compress_test.go
generated
vendored
125
vendor/github.com/emicklei/go-restful/compress_test.go
generated
vendored
@ -1,125 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"compress/zlib"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test -v -test.run TestGzip ...restful
|
||||
func TestGzip(t *testing.T) {
|
||||
EnableContentEncoding = true
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", nil)
|
||||
httpRequest.Header.Set("Accept-Encoding", "gzip,deflate")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
wanted, encoding := wantsCompressedResponse(httpRequest)
|
||||
if !wanted {
|
||||
t.Fatal("should accept gzip")
|
||||
}
|
||||
if encoding != "gzip" {
|
||||
t.Fatal("expected gzip")
|
||||
}
|
||||
c, err := NewCompressingResponseWriter(httpWriter, encoding)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
c.Write([]byte("Hello World"))
|
||||
c.Close()
|
||||
if httpWriter.Header().Get("Content-Encoding") != "gzip" {
|
||||
t.Fatal("Missing gzip header")
|
||||
}
|
||||
reader, err := gzip.NewReader(httpWriter.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
if got, want := string(data), "Hello World"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeflate(t *testing.T) {
|
||||
EnableContentEncoding = true
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", nil)
|
||||
httpRequest.Header.Set("Accept-Encoding", "deflate,gzip")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
wanted, encoding := wantsCompressedResponse(httpRequest)
|
||||
if !wanted {
|
||||
t.Fatal("should accept deflate")
|
||||
}
|
||||
if encoding != "deflate" {
|
||||
t.Fatal("expected deflate")
|
||||
}
|
||||
c, err := NewCompressingResponseWriter(httpWriter, encoding)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
c.Write([]byte("Hello World"))
|
||||
c.Close()
|
||||
if httpWriter.Header().Get("Content-Encoding") != "deflate" {
|
||||
t.Fatal("Missing deflate header")
|
||||
}
|
||||
reader, err := zlib.NewReader(httpWriter.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
if got, want := string(data), "Hello World"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGzipDecompressRequestBody(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
w := newGzipWriter()
|
||||
w.Reset(b)
|
||||
io.WriteString(w, `{"msg":"hi"}`)
|
||||
w.Flush()
|
||||
w.Close()
|
||||
|
||||
req := new(Request)
|
||||
httpRequest, _ := http.NewRequest("GET", "/", bytes.NewReader(b.Bytes()))
|
||||
httpRequest.Header.Set("Content-Type", "application/json")
|
||||
httpRequest.Header.Set("Content-Encoding", "gzip")
|
||||
req.Request = httpRequest
|
||||
|
||||
doc := make(map[string]interface{})
|
||||
req.ReadEntity(&doc)
|
||||
|
||||
if got, want := doc["msg"], "hi"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestZlibDecompressRequestBody(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
w := newZlibWriter()
|
||||
w.Reset(b)
|
||||
io.WriteString(w, `{"msg":"hi"}`)
|
||||
w.Flush()
|
||||
w.Close()
|
||||
|
||||
req := new(Request)
|
||||
httpRequest, _ := http.NewRequest("GET", "/", bytes.NewReader(b.Bytes()))
|
||||
httpRequest.Header.Set("Content-Type", "application/json")
|
||||
httpRequest.Header.Set("Content-Encoding", "deflate")
|
||||
req.Request = httpRequest
|
||||
|
||||
doc := make(map[string]interface{})
|
||||
req.ReadEntity(&doc)
|
||||
|
||||
if got, want := doc["msg"], "hi"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
83
vendor/github.com/emicklei/go-restful/container_test.go
generated
vendored
83
vendor/github.com/emicklei/go-restful/container_test.go
generated
vendored
@ -1,83 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test -v -test.run TestContainer_computeAllowedMethods ...restful
|
||||
func TestContainer_computeAllowedMethods(t *testing.T) {
|
||||
wc := NewContainer()
|
||||
ws1 := new(WebService).Path("/users")
|
||||
ws1.Route(ws1.GET("{i}").To(dummy))
|
||||
ws1.Route(ws1.POST("{i}").To(dummy))
|
||||
wc.Add(ws1)
|
||||
httpRequest, _ := http.NewRequest("GET", "http://api.his.com/users/1", nil)
|
||||
rreq := Request{Request: httpRequest}
|
||||
m := wc.computeAllowedMethods(&rreq)
|
||||
if len(m) != 2 {
|
||||
t.Errorf("got %d expected 2 methods, %v", len(m), m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainer_HandleWithFilter(t *testing.T) {
|
||||
prefilterCalled := false
|
||||
postfilterCalled := false
|
||||
httpHandlerCalled := false
|
||||
|
||||
wc := NewContainer()
|
||||
wc.Filter(func(request *Request, response *Response, chain *FilterChain) {
|
||||
prefilterCalled = true
|
||||
chain.ProcessFilter(request, response)
|
||||
})
|
||||
wc.HandleWithFilter("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
httpHandlerCalled = true
|
||||
w.Write([]byte("ok"))
|
||||
}))
|
||||
wc.Filter(func(request *Request, response *Response, chain *FilterChain) {
|
||||
postfilterCalled = true
|
||||
chain.ProcessFilter(request, response)
|
||||
})
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/", nil)
|
||||
wc.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Errorf("unexpected code %d", recorder.Code)
|
||||
}
|
||||
if recorder.Body.String() != "ok" {
|
||||
t.Errorf("unexpected body %s", recorder.Body.String())
|
||||
}
|
||||
if !prefilterCalled {
|
||||
t.Errorf("filter added before calling HandleWithFilter wasn't called")
|
||||
}
|
||||
if !postfilterCalled {
|
||||
t.Errorf("filter added after calling HandleWithFilter wasn't called")
|
||||
}
|
||||
if !httpHandlerCalled {
|
||||
t.Errorf("handler added by calling HandleWithFilter wasn't called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerAddAndRemove(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws2 := new(WebService).Path("/users")
|
||||
wc := NewContainer()
|
||||
wc.Add(ws1)
|
||||
wc.Add(ws2)
|
||||
wc.Remove(ws2)
|
||||
if len(wc.webServices) != 1 {
|
||||
t.Errorf("expected one webservices")
|
||||
}
|
||||
if !wc.isRegisteredOnRoot {
|
||||
t.Errorf("expected on root registered")
|
||||
}
|
||||
wc.Remove(ws1)
|
||||
if len(wc.webServices) > 0 {
|
||||
t.Errorf("expected zero webservices")
|
||||
}
|
||||
if wc.isRegisteredOnRoot {
|
||||
t.Errorf("expected not on root registered")
|
||||
}
|
||||
}
|
129
vendor/github.com/emicklei/go-restful/cors_filter_test.go
generated
vendored
129
vendor/github.com/emicklei/go-restful/cors_filter_test.go
generated
vendored
@ -1,129 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test -v -test.run TestCORSFilter_Preflight ...restful
|
||||
// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request
|
||||
func TestCORSFilter_Preflight(t *testing.T) {
|
||||
tearDown()
|
||||
ws := new(WebService)
|
||||
ws.Route(ws.PUT("/cors").To(dummy))
|
||||
Add(ws)
|
||||
|
||||
cors := CrossOriginResourceSharing{
|
||||
ExposeHeaders: []string{"X-Custom-Header"},
|
||||
AllowedHeaders: []string{"X-Custom-Header", "X-Additional-Header"},
|
||||
CookiesAllowed: true,
|
||||
Container: DefaultContainer}
|
||||
Filter(cors.Filter)
|
||||
|
||||
// Preflight
|
||||
httpRequest, _ := http.NewRequest("OPTIONS", "http://api.alice.com/cors", nil)
|
||||
httpRequest.Method = "OPTIONS"
|
||||
httpRequest.Header.Set(HEADER_Origin, "http://api.bob.com")
|
||||
httpRequest.Header.Set(HEADER_AccessControlRequestMethod, "PUT")
|
||||
httpRequest.Header.Set(HEADER_AccessControlRequestHeaders, "X-Custom-Header, X-Additional-Header")
|
||||
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.Dispatch(httpWriter, httpRequest)
|
||||
|
||||
actual := httpWriter.Header().Get(HEADER_AccessControlAllowOrigin)
|
||||
if "http://api.bob.com" != actual {
|
||||
t.Fatal("expected: http://api.bob.com but got:" + actual)
|
||||
}
|
||||
actual = httpWriter.Header().Get(HEADER_AccessControlAllowMethods)
|
||||
if "PUT" != actual {
|
||||
t.Fatal("expected: PUT but got:" + actual)
|
||||
}
|
||||
actual = httpWriter.Header().Get(HEADER_AccessControlAllowHeaders)
|
||||
if "X-Custom-Header, X-Additional-Header" != actual {
|
||||
t.Fatal("expected: X-Custom-Header, X-Additional-Header but got:" + actual)
|
||||
}
|
||||
|
||||
if !cors.isOriginAllowed("somewhere") {
|
||||
t.Fatal("origin expected to be allowed")
|
||||
}
|
||||
cors.AllowedDomains = []string{"overthere.com"}
|
||||
if cors.isOriginAllowed("somewhere") {
|
||||
t.Fatal("origin [somewhere] expected NOT to be allowed")
|
||||
}
|
||||
if !cors.isOriginAllowed("overthere.com") {
|
||||
t.Fatal("origin [overthere] expected to be allowed")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// go test -v -test.run TestCORSFilter_Actual ...restful
|
||||
// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request
|
||||
func TestCORSFilter_Actual(t *testing.T) {
|
||||
tearDown()
|
||||
ws := new(WebService)
|
||||
ws.Route(ws.PUT("/cors").To(dummy))
|
||||
Add(ws)
|
||||
|
||||
cors := CrossOriginResourceSharing{
|
||||
ExposeHeaders: []string{"X-Custom-Header"},
|
||||
AllowedHeaders: []string{"X-Custom-Header", "X-Additional-Header"},
|
||||
CookiesAllowed: true,
|
||||
Container: DefaultContainer}
|
||||
Filter(cors.Filter)
|
||||
|
||||
// Actual
|
||||
httpRequest, _ := http.NewRequest("PUT", "http://api.alice.com/cors", nil)
|
||||
httpRequest.Header.Set(HEADER_Origin, "http://api.bob.com")
|
||||
httpRequest.Header.Set("X-Custom-Header", "value")
|
||||
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.Dispatch(httpWriter, httpRequest)
|
||||
actual := httpWriter.Header().Get(HEADER_AccessControlAllowOrigin)
|
||||
if "http://api.bob.com" != actual {
|
||||
t.Fatal("expected: http://api.bob.com but got:" + actual)
|
||||
}
|
||||
if httpWriter.Body.String() != "dummy" {
|
||||
t.Fatal("expected: dummy but got:" + httpWriter.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
var allowedDomainInput = []struct {
|
||||
domains []string
|
||||
origin string
|
||||
allowed bool
|
||||
}{
|
||||
{[]string{}, "http://anything.com", true},
|
||||
{[]string{"example.com"}, "example.com", true},
|
||||
{[]string{"example.com"}, "not-allowed", false},
|
||||
{[]string{"not-matching.com", "example.com"}, "example.com", true},
|
||||
{[]string{".*"}, "example.com", true},
|
||||
}
|
||||
|
||||
// go test -v -test.run TestCORSFilter_AllowedDomains ...restful
|
||||
func TestCORSFilter_AllowedDomains(t *testing.T) {
|
||||
for _, each := range allowedDomainInput {
|
||||
tearDown()
|
||||
ws := new(WebService)
|
||||
ws.Route(ws.PUT("/cors").To(dummy))
|
||||
Add(ws)
|
||||
|
||||
cors := CrossOriginResourceSharing{
|
||||
AllowedDomains: each.domains,
|
||||
CookiesAllowed: true,
|
||||
Container: DefaultContainer}
|
||||
Filter(cors.Filter)
|
||||
|
||||
httpRequest, _ := http.NewRequest("PUT", "http://api.his.com/cors", nil)
|
||||
httpRequest.Header.Set(HEADER_Origin, each.origin)
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.Dispatch(httpWriter, httpRequest)
|
||||
actual := httpWriter.Header().Get(HEADER_AccessControlAllowOrigin)
|
||||
if actual != each.origin && each.allowed {
|
||||
t.Fatal("expected to be accepted")
|
||||
}
|
||||
if actual == each.origin && !each.allowed {
|
||||
t.Fatal("did not expect to be accepted")
|
||||
}
|
||||
}
|
||||
}
|
231
vendor/github.com/emicklei/go-restful/curly_test.go
generated
vendored
231
vendor/github.com/emicklei/go-restful/curly_test.go
generated
vendored
@ -1,231 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var requestPaths = []struct {
|
||||
// url with path (1) is handled by service with root (2) and remainder has value final (3)
|
||||
path, root string
|
||||
}{
|
||||
{"/", "/"},
|
||||
{"/p", "/p"},
|
||||
{"/p/x", "/p/{q}"},
|
||||
{"/q/x", "/q"},
|
||||
{"/p/x/", "/p/{q}"},
|
||||
{"/p/x/y", "/p/{q}"},
|
||||
{"/q/x/y", "/q"},
|
||||
{"/z/q", "/{p}/q"},
|
||||
{"/a/b/c/q", "/"},
|
||||
}
|
||||
|
||||
// go test -v -test.run TestCurlyDetectWebService ...restful
|
||||
func TestCurlyDetectWebService(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws2 := new(WebService).Path("/p")
|
||||
ws3 := new(WebService).Path("/q")
|
||||
ws4 := new(WebService).Path("/p/q")
|
||||
ws5 := new(WebService).Path("/p/{q}")
|
||||
ws7 := new(WebService).Path("/{p}/q")
|
||||
var wss = []*WebService{ws1, ws2, ws3, ws4, ws5, ws7}
|
||||
|
||||
for _, each := range wss {
|
||||
t.Logf("path=%s,toks=%v\n", each.pathExpr.Source, each.pathExpr.tokens)
|
||||
}
|
||||
|
||||
router := CurlyRouter{}
|
||||
|
||||
ok := true
|
||||
for i, fixture := range requestPaths {
|
||||
requestTokens := tokenizePath(fixture.path)
|
||||
who := router.detectWebService(requestTokens, wss)
|
||||
if who != nil && who.RootPath() != fixture.root {
|
||||
t.Logf("[line:%v] Unexpected dispatcher, expected:%v, actual:%v", i, fixture.root, who.RootPath())
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
var serviceDetects = []struct {
|
||||
path string
|
||||
found bool
|
||||
root string
|
||||
}{
|
||||
{"/a/b", true, "/{p}/{q}/{r}"},
|
||||
{"/p/q", true, "/p/q"},
|
||||
{"/q/p", true, "/q"},
|
||||
{"/", true, "/"},
|
||||
{"/p/q/r", true, "/p/q"},
|
||||
}
|
||||
|
||||
// go test -v -test.run Test_detectWebService ...restful
|
||||
func Test_detectWebService(t *testing.T) {
|
||||
router := CurlyRouter{}
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws2 := new(WebService).Path("/p")
|
||||
ws3 := new(WebService).Path("/q")
|
||||
ws4 := new(WebService).Path("/p/q")
|
||||
ws5 := new(WebService).Path("/p/{q}")
|
||||
ws6 := new(WebService).Path("/p/{q}/")
|
||||
ws7 := new(WebService).Path("/{p}/q")
|
||||
ws8 := new(WebService).Path("/{p}/{q}/{r}")
|
||||
var wss = []*WebService{ws8, ws7, ws6, ws5, ws4, ws3, ws2, ws1}
|
||||
for _, fix := range serviceDetects {
|
||||
requestPath := fix.path
|
||||
requestTokens := tokenizePath(requestPath)
|
||||
for _, ws := range wss {
|
||||
serviceTokens := ws.pathExpr.tokens
|
||||
matches, score := router.computeWebserviceScore(requestTokens, serviceTokens)
|
||||
t.Logf("req=%s,toks:%v,ws=%s,toks:%v,score=%d,matches=%v", requestPath, requestTokens, ws.RootPath(), serviceTokens, score, matches)
|
||||
}
|
||||
best := router.detectWebService(requestTokens, wss)
|
||||
if best != nil {
|
||||
if fix.found {
|
||||
t.Logf("best=%s", best.RootPath())
|
||||
} else {
|
||||
t.Fatalf("should have found:%s", fix.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var routeMatchers = []struct {
|
||||
route string
|
||||
path string
|
||||
matches bool
|
||||
paramCount int
|
||||
staticCount int
|
||||
}{
|
||||
// route, request-path
|
||||
{"/a", "/a", true, 0, 1},
|
||||
{"/a", "/b", false, 0, 0},
|
||||
{"/a", "/b", false, 0, 0},
|
||||
{"/a/{b}/c/", "/a/2/c", true, 1, 2},
|
||||
{"/{a}/{b}/{c}/", "/a/b", false, 0, 0},
|
||||
{"/{x:*}", "/", false, 0, 0},
|
||||
{"/{x:*}", "/a", true, 1, 0},
|
||||
{"/{x:*}", "/a/b", true, 1, 0},
|
||||
{"/a/{x:*}", "/a/b", true, 1, 1},
|
||||
{"/a/{x:[A-Z][A-Z]}", "/a/ZX", true, 1, 1},
|
||||
{"/basepath/{resource:*}", "/basepath/some/other/location/test.xml", true, 1, 1},
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run Test_matchesRouteByPathTokens ...restful
|
||||
func Test_matchesRouteByPathTokens(t *testing.T) {
|
||||
router := CurlyRouter{}
|
||||
for i, each := range routeMatchers {
|
||||
routeToks := tokenizePath(each.route)
|
||||
reqToks := tokenizePath(each.path)
|
||||
matches, pCount, sCount := router.matchesRouteByPathTokens(routeToks, reqToks)
|
||||
if matches != each.matches {
|
||||
t.Fatalf("[%d] unexpected matches outcome route:%s, path:%s, matches:%v", i, each.route, each.path, matches)
|
||||
}
|
||||
if pCount != each.paramCount {
|
||||
t.Fatalf("[%d] unexpected paramCount got:%d want:%d ", i, pCount, each.paramCount)
|
||||
}
|
||||
if sCount != each.staticCount {
|
||||
t.Fatalf("[%d] unexpected staticCount got:%d want:%d ", i, sCount, each.staticCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestExtractParameters_Wildcard1 ...restful
|
||||
func TestExtractParameters_Wildcard1(t *testing.T) {
|
||||
params := doExtractParams("/fixed/{var:*}", 2, "/fixed/remainder", t)
|
||||
if params["var"] != "remainder" {
|
||||
t.Errorf("parameter mismatch var: %s", params["var"])
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestExtractParameters_Wildcard2 ...restful
|
||||
func TestExtractParameters_Wildcard2(t *testing.T) {
|
||||
params := doExtractParams("/fixed/{var:*}", 2, "/fixed/remain/der", t)
|
||||
if params["var"] != "remain/der" {
|
||||
t.Errorf("parameter mismatch var: %s", params["var"])
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestExtractParameters_Wildcard3 ...restful
|
||||
func TestExtractParameters_Wildcard3(t *testing.T) {
|
||||
params := doExtractParams("/static/{var:*}", 2, "/static/test/sub/hi.html", t)
|
||||
if params["var"] != "test/sub/hi.html" {
|
||||
t.Errorf("parameter mismatch var: %s", params["var"])
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestCurly_ISSUE_34 ...restful
|
||||
func TestCurly_ISSUE_34(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws1.Route(ws1.GET("/{type}/{id}").To(curlyDummy))
|
||||
ws1.Route(ws1.GET("/network/{id}").To(curlyDummy))
|
||||
croutes := CurlyRouter{}.selectRoutes(ws1, tokenizePath("/network/12"))
|
||||
if len(croutes) != 2 {
|
||||
t.Fatal("expected 2 routes")
|
||||
}
|
||||
if got, want := croutes[0].route.Path, "/network/{id}"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestCurly_ISSUE_34_2 ...restful
|
||||
func TestCurly_ISSUE_34_2(t *testing.T) {
|
||||
ws1 := new(WebService)
|
||||
ws1.Route(ws1.GET("/network/{id}").To(curlyDummy))
|
||||
ws1.Route(ws1.GET("/{type}/{id}").To(curlyDummy))
|
||||
croutes := CurlyRouter{}.selectRoutes(ws1, tokenizePath("/network/12"))
|
||||
if len(croutes) != 2 {
|
||||
t.Fatal("expected 2 routes")
|
||||
}
|
||||
if got, want := croutes[0].route.Path, "/network/{id}"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestCurly_JsonHtml ...restful
|
||||
func TestCurly_JsonHtml(t *testing.T) {
|
||||
ws1 := new(WebService)
|
||||
ws1.Path("/")
|
||||
ws1.Route(ws1.GET("/some.html").To(curlyDummy).Consumes("*/*").Produces("text/html"))
|
||||
req, _ := http.NewRequest("GET", "/some.html", nil)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
_, route, err := CurlyRouter{}.SelectRoute([]*WebService{ws1}, req)
|
||||
if err == nil {
|
||||
t.Error("error expected")
|
||||
}
|
||||
if route != nil {
|
||||
t.Error("no route expected")
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestCurly_ISSUE_137 ...restful
|
||||
func TestCurly_ISSUE_137(t *testing.T) {
|
||||
ws1 := new(WebService)
|
||||
ws1.Route(ws1.GET("/hello").To(curlyDummy))
|
||||
ws1.Path("/")
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
_, route, _ := CurlyRouter{}.SelectRoute([]*WebService{ws1}, req)
|
||||
t.Log(route)
|
||||
if route != nil {
|
||||
t.Error("no route expected")
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestCurly_ISSUE_137_2 ...restful
|
||||
func TestCurly_ISSUE_137_2(t *testing.T) {
|
||||
ws1 := new(WebService)
|
||||
ws1.Route(ws1.GET("/hello").To(curlyDummy))
|
||||
ws1.Path("/")
|
||||
req, _ := http.NewRequest("GET", "/hello/bob", nil)
|
||||
_, route, _ := CurlyRouter{}.SelectRoute([]*WebService{ws1}, req)
|
||||
t.Log(route)
|
||||
if route != nil {
|
||||
t.Errorf("no route expected, got %v", route)
|
||||
}
|
||||
}
|
||||
|
||||
func curlyDummy(req *Request, resp *Response) { io.WriteString(resp.ResponseWriter, "curlyDummy") }
|
41
vendor/github.com/emicklei/go-restful/doc_examples_test.go
generated
vendored
41
vendor/github.com/emicklei/go-restful/doc_examples_test.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
package restful
|
||||
|
||||
import "net/http"
|
||||
|
||||
func ExampleOPTIONSFilter() {
|
||||
// Install the OPTIONS filter on the default Container
|
||||
Filter(OPTIONSFilter())
|
||||
}
|
||||
func ExampleContainer_OPTIONSFilter() {
|
||||
// Install the OPTIONS filter on a Container
|
||||
myContainer := new(Container)
|
||||
myContainer.Filter(myContainer.OPTIONSFilter)
|
||||
}
|
||||
|
||||
func ExampleContainer() {
|
||||
// The Default container of go-restful uses the http.DefaultServeMux.
|
||||
// You can create your own Container using restful.NewContainer() and create a new http.Server for that particular container
|
||||
|
||||
ws := new(WebService)
|
||||
wsContainer := NewContainer()
|
||||
wsContainer.Add(ws)
|
||||
server := &http.Server{Addr: ":8080", Handler: wsContainer}
|
||||
server.ListenAndServe()
|
||||
}
|
||||
|
||||
func ExampleCrossOriginResourceSharing() {
|
||||
// To install this filter on the Default Container use:
|
||||
cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer}
|
||||
Filter(cors.Filter)
|
||||
}
|
||||
|
||||
func ExampleServiceError() {
|
||||
resp := new(Response)
|
||||
resp.WriteEntity(NewError(http.StatusBadRequest, "Non-integer {id} path parameter"))
|
||||
}
|
||||
|
||||
func ExampleBoundedCachedCompressors() {
|
||||
// Register a compressor provider (gzip/deflate read/write) that uses
|
||||
// a bounded cache with a maximum of 20 writers and 20 readers.
|
||||
SetCompressorProvider(NewBoundedCachedCompressors(20, 20))
|
||||
}
|
69
vendor/github.com/emicklei/go-restful/entity_accessors_test.go
generated
vendored
69
vendor/github.com/emicklei/go-restful/entity_accessors_test.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type keyvalue struct {
|
||||
readCalled bool
|
||||
writeCalled bool
|
||||
}
|
||||
|
||||
func (kv *keyvalue) Read(req *Request, v interface{}) error {
|
||||
//t := reflect.TypeOf(v)
|
||||
//rv := reflect.ValueOf(v)
|
||||
kv.readCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (kv *keyvalue) Write(resp *Response, status int, v interface{}) error {
|
||||
t := reflect.TypeOf(v)
|
||||
rv := reflect.ValueOf(v)
|
||||
for ix := 0; ix < t.NumField(); ix++ {
|
||||
sf := t.Field(ix)
|
||||
io.WriteString(resp, sf.Name)
|
||||
io.WriteString(resp, "=")
|
||||
io.WriteString(resp, fmt.Sprintf("%v\n", rv.Field(ix).Interface()))
|
||||
}
|
||||
kv.writeCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// go test -v -test.run TestKeyValueEncoding ...restful
|
||||
func TestKeyValueEncoding(t *testing.T) {
|
||||
type Book struct {
|
||||
Title string
|
||||
Author string
|
||||
PublishedYear int
|
||||
}
|
||||
kv := new(keyvalue)
|
||||
RegisterEntityAccessor("application/kv", kv)
|
||||
b := Book{"Singing for Dummies", "john doe", 2015}
|
||||
|
||||
// Write
|
||||
httpWriter := httptest.NewRecorder()
|
||||
// Accept Produces
|
||||
resp := Response{httpWriter, "application/kv,*/*;q=0.8", []string{"application/kv"}, 0, 0, true, nil}
|
||||
resp.WriteEntity(b)
|
||||
t.Log(string(httpWriter.Body.Bytes()))
|
||||
if !kv.writeCalled {
|
||||
t.Error("Write never called")
|
||||
}
|
||||
|
||||
// Read
|
||||
bodyReader := bytes.NewReader(httpWriter.Body.Bytes())
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/kv; charset=UTF-8")
|
||||
request := NewRequest(httpRequest)
|
||||
var bb Book
|
||||
request.ReadEntity(&bb)
|
||||
if !kv.readCalled {
|
||||
t.Error("Read never called")
|
||||
}
|
||||
}
|
1
vendor/github.com/emicklei/go-restful/examples/.goconvey
generated
vendored
1
vendor/github.com/emicklei/go-restful/examples/.goconvey
generated
vendored
@ -1 +0,0 @@
|
||||
ignore
|
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/.goconvey
generated
vendored
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/.goconvey
generated
vendored
@ -1 +0,0 @@
|
||||
ignore
|
20
vendor/github.com/emicklei/go-restful/examples/google_app_engine/app.yaml
generated
vendored
20
vendor/github.com/emicklei/go-restful/examples/google_app_engine/app.yaml
generated
vendored
@ -1,20 +0,0 @@
|
||||
#
|
||||
# Include your application ID here
|
||||
#
|
||||
application: <your_app_id>
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
|
||||
handlers:
|
||||
#
|
||||
# Regex for all swagger files to make as static content.
|
||||
# You should create the folder static/swagger and copy
|
||||
# swagger-ui into it.
|
||||
#
|
||||
- url: /apidocs/(.*?)/(.*\.(js|html|css))
|
||||
static_files: static/swagger/\1/\2
|
||||
upload: static/swagger/(.*?)/(.*\.(js|html|css))
|
||||
|
||||
- url: /.*
|
||||
script: _go_app
|
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/.goconvey
generated
vendored
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/.goconvey
generated
vendored
@ -1 +0,0 @@
|
||||
ignore
|
18
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/app.yaml
generated
vendored
18
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/app.yaml
generated
vendored
@ -1,18 +0,0 @@
|
||||
application: <your_app_id>
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
|
||||
handlers:
|
||||
# Regex for all swagger files to make as static content.
|
||||
# You should create the folder static/swagger and copy
|
||||
# swagger-ui into it.
|
||||
#
|
||||
- url: /apidocs/(.*?)/(.*\.(js|html|css))
|
||||
static_files: static/swagger/\1/\2
|
||||
upload: static/swagger/(.*?)/(.*\.(js|html|css))
|
||||
|
||||
# Catch all.
|
||||
- url: /.*
|
||||
script: _go_app
|
||||
login: required
|
267
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/main.go
generated
vendored
267
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/main.go
generated
vendored
@ -1,267 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/datastore"
|
||||
"google.golang.org/appengine/user"
|
||||
)
|
||||
|
||||
// This example demonstrates a reasonably complete suite of RESTful operations backed
|
||||
// by DataStore on Google App Engine.
|
||||
|
||||
// Our simple example struct.
|
||||
type Profile struct {
|
||||
LastModified time.Time `json:"-" xml:"-"`
|
||||
Email string `json:"-" xml:"-"`
|
||||
FirstName string `json:"first_name" xml:"first-name"`
|
||||
NickName string `json:"nick_name" xml:"nick-name"`
|
||||
LastName string `json:"last_name" xml:"last-name"`
|
||||
}
|
||||
|
||||
type ProfileApi struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func gaeUrl() string {
|
||||
if appengine.IsDevAppServer() {
|
||||
return "http://localhost:8080"
|
||||
} else {
|
||||
// Include your URL on App Engine here.
|
||||
// I found no way to get AppID without appengine.Context and this always
|
||||
// based on a http.Request.
|
||||
return "http://federatedservices.appspot.com"
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
u := ProfileApi{Path: "/profiles"}
|
||||
u.register()
|
||||
|
||||
// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open <your_app_id>.appspot.com/apidocs and enter
|
||||
// Place the Swagger UI files into a folder called static/swagger if you wish to use Swagger
|
||||
// http://<your_app_id>.appspot.com/apidocs.json in the api input field.
|
||||
// For testing, you can use http://localhost:8080/apidocs.json
|
||||
config := swagger.Config{
|
||||
// You control what services are visible
|
||||
WebServices: restful.RegisteredWebServices(),
|
||||
WebServicesUrl: gaeUrl(),
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specifiy where the UI is located
|
||||
SwaggerPath: "/apidocs/",
|
||||
|
||||
// GAE support static content which is configured in your app.yaml.
|
||||
// This example expect the swagger-ui in static/swagger so you should place it there :)
|
||||
SwaggerFilePath: "static/swagger"}
|
||||
swagger.InstallSwaggerService(config)
|
||||
}
|
||||
|
||||
func (u ProfileApi) register() {
|
||||
ws := new(restful.WebService)
|
||||
|
||||
ws.
|
||||
Path(u.Path).
|
||||
// You can specify consumes and produces per route as well.
|
||||
Consumes(restful.MIME_JSON, restful.MIME_XML).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||
|
||||
ws.Route(ws.POST("").To(u.insert).
|
||||
// Swagger documentation.
|
||||
Doc("insert a new profile").
|
||||
Param(ws.BodyParameter("Profile", "representation of a profile").DataType("main.Profile")).
|
||||
Reads(Profile{}))
|
||||
|
||||
ws.Route(ws.GET("/{profile-id}").To(u.read).
|
||||
// Swagger documentation.
|
||||
Doc("read a profile").
|
||||
Param(ws.PathParameter("profile-id", "identifier for a profile").DataType("string")).
|
||||
Writes(Profile{}))
|
||||
|
||||
ws.Route(ws.PUT("/{profile-id}").To(u.update).
|
||||
// Swagger documentation.
|
||||
Doc("update an existing profile").
|
||||
Param(ws.PathParameter("profile-id", "identifier for a profile").DataType("string")).
|
||||
Param(ws.BodyParameter("Profile", "representation of a profile").DataType("main.Profile")).
|
||||
Reads(Profile{}))
|
||||
|
||||
ws.Route(ws.DELETE("/{profile-id}").To(u.remove).
|
||||
// Swagger documentation.
|
||||
Doc("remove a profile").
|
||||
Param(ws.PathParameter("profile-id", "identifier for a profile").DataType("string")))
|
||||
|
||||
restful.Add(ws)
|
||||
}
|
||||
|
||||
// POST http://localhost:8080/profiles
|
||||
// {"first_name": "Ivan", "nick_name": "Socks", "last_name": "Hawkes"}
|
||||
//
|
||||
func (u *ProfileApi) insert(r *restful.Request, w *restful.Response) {
|
||||
c := appengine.NewContext(r.Request)
|
||||
|
||||
// Marshall the entity from the request into a struct.
|
||||
p := new(Profile)
|
||||
err := r.ReadEntity(&p)
|
||||
if err != nil {
|
||||
w.WriteError(http.StatusNotAcceptable, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure we start with a sensible value for this field.
|
||||
p.LastModified = time.Now()
|
||||
|
||||
// The profile belongs to this user.
|
||||
p.Email = user.Current(c).String()
|
||||
|
||||
k, err := datastore.Put(c, datastore.NewIncompleteKey(c, "profiles", nil), p)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Let them know the location of the newly created resource.
|
||||
// TODO: Use a safe Url path append function.
|
||||
w.AddHeader("Location", u.Path+"/"+k.Encode())
|
||||
|
||||
// Return the resultant entity.
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.WriteEntity(p)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/profiles/ahdkZXZ-ZmVkZXJhdGlvbi1zZXJ2aWNlc3IVCxIIcHJvZmlsZXMYgICAgICAgAoM
|
||||
//
|
||||
func (u ProfileApi) read(r *restful.Request, w *restful.Response) {
|
||||
c := appengine.NewContext(r.Request)
|
||||
|
||||
// Decode the request parameter to determine the key for the entity.
|
||||
k, err := datastore.DecodeKey(r.PathParameter("profile-id"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the entity from the datastore.
|
||||
p := Profile{}
|
||||
if err := datastore.Get(c, k, &p); err != nil {
|
||||
if err.Error() == "datastore: no such entity" {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check we own the profile before allowing them to view it.
|
||||
// Optionally, return a 404 instead to help prevent guessing ids.
|
||||
// TODO: Allow admins access.
|
||||
if p.Email != user.Current(c).String() {
|
||||
http.Error(w, "You do not have access to this resource", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteEntity(p)
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/profiles/ahdkZXZ-ZmVkZXJhdGlvbi1zZXJ2aWNlc3IVCxIIcHJvZmlsZXMYgICAgICAgAoM
|
||||
// {"first_name": "Ivan", "nick_name": "Socks", "last_name": "Hawkes"}
|
||||
//
|
||||
func (u *ProfileApi) update(r *restful.Request, w *restful.Response) {
|
||||
c := appengine.NewContext(r.Request)
|
||||
|
||||
// Decode the request parameter to determine the key for the entity.
|
||||
k, err := datastore.DecodeKey(r.PathParameter("profile-id"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Marshall the entity from the request into a struct.
|
||||
p := new(Profile)
|
||||
err = r.ReadEntity(&p)
|
||||
if err != nil {
|
||||
w.WriteError(http.StatusNotAcceptable, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the old entity from the datastore.
|
||||
old := Profile{}
|
||||
if err := datastore.Get(c, k, &old); err != nil {
|
||||
if err.Error() == "datastore: no such entity" {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check we own the profile before allowing them to update it.
|
||||
// Optionally, return a 404 instead to help prevent guessing ids.
|
||||
// TODO: Allow admins access.
|
||||
if old.Email != user.Current(c).String() {
|
||||
http.Error(w, "You do not have access to this resource", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Since the whole entity is re-written, we need to assign any invariant fields again
|
||||
// e.g. the owner of the entity.
|
||||
p.Email = user.Current(c).String()
|
||||
|
||||
// Keep track of the last modification date.
|
||||
p.LastModified = time.Now()
|
||||
|
||||
// Attempt to overwrite the old entity.
|
||||
_, err = datastore.Put(c, k, p)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Let them know it succeeded.
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8080/profiles/ahdkZXZ-ZmVkZXJhdGlvbi1zZXJ2aWNlc3IVCxIIcHJvZmlsZXMYgICAgICAgAoM
|
||||
//
|
||||
func (u *ProfileApi) remove(r *restful.Request, w *restful.Response) {
|
||||
c := appengine.NewContext(r.Request)
|
||||
|
||||
// Decode the request parameter to determine the key for the entity.
|
||||
k, err := datastore.DecodeKey(r.PathParameter("profile-id"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the old entity from the datastore.
|
||||
old := Profile{}
|
||||
if err := datastore.Get(c, k, &old); err != nil {
|
||||
if err.Error() == "datastore: no such entity" {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check we own the profile before allowing them to delete it.
|
||||
// Optionally, return a 404 instead to help prevent guessing ids.
|
||||
// TODO: Allow admins access.
|
||||
if old.Email != user.Current(c).String() {
|
||||
http.Error(w, "You do not have access to this resource", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete the entity.
|
||||
if err := datastore.Delete(c, k); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Success notification.
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mjibson/appstats"
|
||||
)
|
||||
|
||||
func stats(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
c := appstats.NewContext(req.Request)
|
||||
chain.ProcessFilter(req, resp)
|
||||
c.Stats.Status = resp.StatusCode()
|
||||
c.Save()
|
||||
}
|
162
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-user-service.go
generated
vendored
162
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-user-service.go
generated
vendored
@ -1,162 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/memcache"
|
||||
)
|
||||
|
||||
// This example is functionally the same as ../restful-user-service.go
|
||||
// but it`s supposed to run on Goole App Engine (GAE)
|
||||
//
|
||||
// contributed by ivanhawkes
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserService struct {
|
||||
// normally one would use DAO (data access object)
|
||||
// but in this example we simple use memcache.
|
||||
}
|
||||
|
||||
func (u UserService) Register() {
|
||||
ws := new(restful.WebService)
|
||||
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser).
|
||||
// docs
|
||||
Doc("get a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Writes(User{})) // on the response
|
||||
|
||||
ws.Route(ws.PATCH("").To(u.updateUser).
|
||||
// docs
|
||||
Doc("update a user").
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.createUser).
|
||||
// docs
|
||||
Doc("create a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser).
|
||||
// docs
|
||||
Doc("delete a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")))
|
||||
|
||||
restful.Add(ws)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
func (u UserService) findUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
id := request.PathParameter("user-id")
|
||||
usr := new(User)
|
||||
_, err := memcache.Gob.Get(c, id, &usr)
|
||||
if err != nil || len(usr.Id) == 0 {
|
||||
response.WriteErrorString(http.StatusNotFound, "User could not be found.")
|
||||
} else {
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH http://localhost:8080/users
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
func (u *UserService) updateUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
item := &memcache.Item{
|
||||
Key: usr.Id,
|
||||
Object: &usr,
|
||||
}
|
||||
err = memcache.Gob.Set(c, item)
|
||||
if err != nil {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
func (u *UserService) createUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
usr := User{Id: request.PathParameter("user-id")}
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
item := &memcache.Item{
|
||||
Key: usr.Id,
|
||||
Object: &usr,
|
||||
}
|
||||
err = memcache.Gob.Add(c, item)
|
||||
if err != nil {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusCreated)
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
func (u *UserService) removeUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
id := request.PathParameter("user-id")
|
||||
err := memcache.Delete(c, id)
|
||||
if err != nil {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
func getGaeURL() string {
|
||||
if appengine.IsDevAppServer() {
|
||||
return "http://localhost:8080"
|
||||
} else {
|
||||
/**
|
||||
* Include your URL on App Engine here.
|
||||
* I found no way to get AppID without appengine.Context and this always
|
||||
* based on a http.Request.
|
||||
*/
|
||||
return "http://<your_app_id>.appspot.com"
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
u := UserService{}
|
||||
u.Register()
|
||||
|
||||
// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open <your_app_id>.appspot.com/apidocs and enter http://<your_app_id>.appspot.com/apidocs.json in the api input field.
|
||||
config := swagger.Config{
|
||||
WebServices: restful.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesUrl: getGaeURL(),
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specifiy where the UI is located
|
||||
SwaggerPath: "/apidocs/",
|
||||
// GAE support static content which is configured in your app.yaml.
|
||||
// This example expect the swagger-ui in static/swagger so you should place it there :)
|
||||
SwaggerFilePath: "static/swagger"}
|
||||
swagger.InstallSwaggerService(config)
|
||||
}
|
7
vendor/github.com/emicklei/go-restful/examples/home.html
generated
vendored
7
vendor/github.com/emicklei/go-restful/examples/home.html
generated
vendored
@ -1,7 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<h1>{{.Text}}</h1>
|
||||
</body>
|
||||
</html>
|
34
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity.go
generated
vendored
34
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity.go
generated
vendored
@ -1,34 +0,0 @@
|
||||
package restPack
|
||||
|
||||
import (
|
||||
restful "github.com/emicklei/go-restful"
|
||||
"gopkg.in/vmihailenco/msgpack.v2"
|
||||
)
|
||||
|
||||
const MIME_MSGPACK = "application/x-msgpack" // Accept or Content-Type used in Consumes() and/or Produces()
|
||||
|
||||
// NewEntityAccessorMPack returns a new EntityReaderWriter for accessing MessagePack content.
|
||||
// This package is not initialized with such an accessor using the MIME_MSGPACK contentType.
|
||||
func NewEntityAccessorMsgPack() restful.EntityReaderWriter {
|
||||
return entityMsgPackAccess{}
|
||||
}
|
||||
|
||||
// entityOctetAccess is a EntityReaderWriter for Octet encoding
|
||||
type entityMsgPackAccess struct {
|
||||
}
|
||||
|
||||
// Read unmarshalls the value from byte slice and using msgpack to unmarshal
|
||||
func (e entityMsgPackAccess) Read(req *restful.Request, v interface{}) error {
|
||||
return msgpack.NewDecoder(req.Request.Body).Decode(v)
|
||||
}
|
||||
|
||||
// Write marshals the value to byte slice and set the Content-Type Header.
|
||||
func (e entityMsgPackAccess) Write(resp *restful.Response, status int, v interface{}) error {
|
||||
if v == nil {
|
||||
resp.WriteHeader(status)
|
||||
// do not write a nil representation
|
||||
return nil
|
||||
}
|
||||
resp.WriteHeader(status)
|
||||
return msgpack.NewEncoder(resp).Encode(v)
|
||||
}
|
160
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity_test.go
generated
vendored
160
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity_test.go
generated
vendored
@ -1,160 +0,0 @@
|
||||
package restPack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
restful "github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
func TestMsgPack(t *testing.T) {
|
||||
|
||||
// register msg pack entity
|
||||
restful.RegisterEntityAccessor(MIME_MSGPACK, NewEntityAccessorMsgPack())
|
||||
type Tool struct {
|
||||
Name string
|
||||
Vendor string
|
||||
}
|
||||
|
||||
// Write
|
||||
httpWriter := httptest.NewRecorder()
|
||||
mpack := &Tool{Name: "json", Vendor: "apple"}
|
||||
resp := restful.NewResponse(httpWriter)
|
||||
resp.SetRequestAccepts("application/x-msgpack,*/*;q=0.8")
|
||||
|
||||
err := resp.WriteEntity(mpack)
|
||||
if err != nil {
|
||||
t.Errorf("err %v", err)
|
||||
}
|
||||
|
||||
// Read
|
||||
bodyReader := bytes.NewReader(httpWriter.Body.Bytes())
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", MIME_MSGPACK)
|
||||
request := restful.NewRequest(httpRequest)
|
||||
readMsgPack := new(Tool)
|
||||
err = request.ReadEntity(&readMsgPack)
|
||||
if err != nil {
|
||||
t.Errorf("err %v", err)
|
||||
}
|
||||
if equal := reflect.DeepEqual(mpack, readMsgPack); !equal {
|
||||
t.Fatalf("should not be error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithWebService(t *testing.T) {
|
||||
serverURL := "http://127.0.0.1:8090"
|
||||
go func() {
|
||||
runRestfulMsgPackRouterServer()
|
||||
}()
|
||||
if err := waitForServerUp(serverURL); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
// send a post request
|
||||
userData := user{Id: "0001", Name: "Tony"}
|
||||
msgPackData, err := msgpack.Marshal(userData)
|
||||
req, err := http.NewRequest("POST", serverURL+"/test/msgpack", bytes.NewBuffer(msgPackData))
|
||||
req.Header.Set("Content-Type", MIME_MSGPACK)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error in sending req: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("unexpected response: %v, expected: %v", resp.StatusCode, http.StatusOK)
|
||||
}
|
||||
|
||||
ur := &userResponse{}
|
||||
expectMsgPackDocument(t, resp, ur)
|
||||
if ur.Status != statusActive {
|
||||
t.Fatalf("should not error")
|
||||
}
|
||||
log.Printf("user response:%v", ur)
|
||||
}
|
||||
|
||||
func expectMsgPackDocument(t *testing.T, r *http.Response, doc interface{}) {
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
defer r.Body.Close()
|
||||
if err != nil {
|
||||
t.Errorf("ExpectMsgPackDocument: unable to read response body :%v", err)
|
||||
return
|
||||
}
|
||||
// put the body back for re-reads
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(data))
|
||||
|
||||
err = msgpack.Unmarshal(data, doc)
|
||||
if err != nil {
|
||||
t.Errorf("ExpectMsgPackDocument: unable to unmarshal MsgPack:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runRestfulMsgPackRouterServer() {
|
||||
|
||||
container := restful.NewContainer()
|
||||
register(container)
|
||||
|
||||
log.Printf("start listening on localhost:8090")
|
||||
server := &http.Server{Addr: ":8090", Handler: container}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func waitForServerUp(serverURL string) error {
|
||||
for start := time.Now(); time.Since(start) < time.Minute; time.Sleep(5 * time.Second) {
|
||||
_, err := http.Get(serverURL + "/")
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.New("waiting for server timed out")
|
||||
}
|
||||
|
||||
var (
|
||||
statusActive = "active"
|
||||
)
|
||||
|
||||
type user struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type userResponse struct {
|
||||
Status string
|
||||
}
|
||||
|
||||
func register(container *restful.Container) {
|
||||
restful.RegisterEntityAccessor(MIME_MSGPACK, NewEntityAccessorMsgPack())
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/test").
|
||||
Consumes(restful.MIME_JSON, MIME_MSGPACK).
|
||||
Produces(restful.MIME_JSON, MIME_MSGPACK)
|
||||
// route user api
|
||||
ws.Route(ws.POST("/msgpack").
|
||||
To(do).
|
||||
Reads(user{}).
|
||||
Writes(userResponse{}))
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
func do(request *restful.Request, response *restful.Response) {
|
||||
u := &user{}
|
||||
err := request.ReadEntity(u)
|
||||
if err != nil {
|
||||
log.Printf("should be no error, got:%v", err)
|
||||
}
|
||||
log.Printf("got:%v", u)
|
||||
|
||||
ur := &userResponse{Status: statusActive}
|
||||
|
||||
response.SetRequestAccepts(MIME_MSGPACK)
|
||||
response.WriteEntity(ur)
|
||||
}
|
68
vendor/github.com/emicklei/go-restful/examples/restful-CORS-filter.go
generated
vendored
68
vendor/github.com/emicklei/go-restful/examples/restful-CORS-filter.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// Cross-origin resource sharing (CORS) is a mechanism that allows JavaScript on a web page
|
||||
// to make XMLHttpRequests to another domain, not the domain the JavaScript originated from.
|
||||
//
|
||||
// http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
|
||||
// http://enable-cors.org/server.html
|
||||
//
|
||||
// GET http://localhost:8080/users
|
||||
//
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
// PUT http://localhost:8080/users/1
|
||||
//
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
// OPTIONS http://localhost:8080/users/1 with Header "Origin" set to some domain and
|
||||
|
||||
type UserResource struct{}
|
||||
|
||||
func (u UserResource) RegisterTo(container *restful.Container) {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes("*/*").
|
||||
Produces("*/*")
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.nop))
|
||||
ws.Route(ws.POST("").To(u.nop))
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.nop))
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.nop))
|
||||
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
func (u UserResource) nop(request *restful.Request, response *restful.Response) {
|
||||
io.WriteString(response.ResponseWriter, "this would be a normal response")
|
||||
}
|
||||
|
||||
func main() {
|
||||
wsContainer := restful.NewContainer()
|
||||
u := UserResource{}
|
||||
u.RegisterTo(wsContainer)
|
||||
|
||||
// Add container filter to enable CORS
|
||||
cors := restful.CrossOriginResourceSharing{
|
||||
ExposeHeaders: []string{"X-My-Header"},
|
||||
AllowedHeaders: []string{"Content-Type", "Accept"},
|
||||
AllowedMethods: []string{"GET", "POST"},
|
||||
CookiesAllowed: false,
|
||||
Container: wsContainer}
|
||||
wsContainer.Filter(cors.Filter)
|
||||
|
||||
// Add container filter to respond to OPTIONS
|
||||
wsContainer.Filter(wsContainer.OPTIONSFilter)
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
server := &http.Server{Addr: ":8080", Handler: wsContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
54
vendor/github.com/emicklei/go-restful/examples/restful-NCSA-logging.go
generated
vendored
54
vendor/github.com/emicklei/go-restful/examples/restful-NCSA-logging.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// This example shows how to create a filter that produces log lines
|
||||
// according to the Common Log Format, also known as the NCSA standard.
|
||||
//
|
||||
// kindly contributed by leehambley
|
||||
//
|
||||
// GET http://localhost:8080/ping
|
||||
|
||||
var logger *log.Logger = log.New(os.Stdout, "", 0)
|
||||
|
||||
func NCSACommonLogFormatLogger() restful.FilterFunction {
|
||||
return func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
var username = "-"
|
||||
if req.Request.URL.User != nil {
|
||||
if name := req.Request.URL.User.Username(); name != "" {
|
||||
username = name
|
||||
}
|
||||
}
|
||||
chain.ProcessFilter(req, resp)
|
||||
logger.Printf("%s - %s [%s] \"%s %s %s\" %d %d",
|
||||
strings.Split(req.Request.RemoteAddr, ":")[0],
|
||||
username,
|
||||
time.Now().Format("02/Jan/2006:15:04:05 -0700"),
|
||||
req.Request.Method,
|
||||
req.Request.URL.RequestURI(),
|
||||
req.Request.Proto,
|
||||
resp.StatusCode(),
|
||||
resp.ContentLength(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Filter(NCSACommonLogFormatLogger())
|
||||
ws.Route(ws.GET("/ping").To(hello))
|
||||
restful.Add(ws)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func hello(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "pong")
|
||||
}
|
35
vendor/github.com/emicklei/go-restful/examples/restful-basic-authentication.go
generated
vendored
35
vendor/github.com/emicklei/go-restful/examples/restful-basic-authentication.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to create a (Route) Filter that performs Basic Authentication on the Http request.
|
||||
//
|
||||
// GET http://localhost:8080/secret
|
||||
// and use admin,admin for the credentials
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Route(ws.GET("/secret").Filter(basicAuthenticate).To(secret))
|
||||
restful.Add(ws)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func basicAuthenticate(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
encoded := req.Request.Header.Get("Authorization")
|
||||
// usr/pwd = admin/admin
|
||||
// real code does some decoding
|
||||
if len(encoded) == 0 || "Basic YWRtaW46YWRtaW4=" != encoded {
|
||||
resp.AddHeader("WWW-Authenticate", "Basic realm=Protected Area")
|
||||
resp.WriteErrorString(401, "401: Not Authorized")
|
||||
return
|
||||
}
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
func secret(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "42")
|
||||
}
|
65
vendor/github.com/emicklei/go-restful/examples/restful-cpuprofiler-service.go
generated
vendored
65
vendor/github.com/emicklei/go-restful/examples/restful-cpuprofiler-service.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
)
|
||||
|
||||
// ProfilingService is a WebService that can start/stop a CPU profile and write results to a file
|
||||
// GET /{rootPath}/start will activate CPU profiling
|
||||
// GET /{rootPath}/stop will stop profiling
|
||||
//
|
||||
// NewProfileService("/profiler", "ace.prof").AddWebServiceTo(restful.DefaultContainer)
|
||||
//
|
||||
type ProfilingService struct {
|
||||
rootPath string // the base (root) of the service, e.g. /profiler
|
||||
cpuprofile string // the output filename to write profile results, e.g. myservice.prof
|
||||
cpufile *os.File // if not nil, then profiling is active
|
||||
}
|
||||
|
||||
func NewProfileService(rootPath string, outputFilename string) *ProfilingService {
|
||||
ps := new(ProfilingService)
|
||||
ps.rootPath = rootPath
|
||||
ps.cpuprofile = outputFilename
|
||||
return ps
|
||||
}
|
||||
|
||||
// Add this ProfileService to a restful Container
|
||||
func (p ProfilingService) AddWebServiceTo(container *restful.Container) {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path(p.rootPath).Consumes("*/*").Produces(restful.MIME_JSON)
|
||||
ws.Route(ws.GET("/start").To(p.startProfiler))
|
||||
ws.Route(ws.GET("/stop").To(p.stopProfiler))
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
func (p *ProfilingService) startProfiler(req *restful.Request, resp *restful.Response) {
|
||||
if p.cpufile != nil {
|
||||
io.WriteString(resp.ResponseWriter, "[restful] CPU profiling already running")
|
||||
return // error?
|
||||
}
|
||||
cpufile, err := os.Create(p.cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// remember for close
|
||||
p.cpufile = cpufile
|
||||
pprof.StartCPUProfile(cpufile)
|
||||
io.WriteString(resp.ResponseWriter, "[restful] CPU profiling started, writing on:"+p.cpuprofile)
|
||||
}
|
||||
|
||||
func (p *ProfilingService) stopProfiler(req *restful.Request, resp *restful.Response) {
|
||||
if p.cpufile == nil {
|
||||
io.WriteString(resp.ResponseWriter, "[restful] CPU profiling not active")
|
||||
return // error?
|
||||
}
|
||||
pprof.StopCPUProfile()
|
||||
p.cpufile.Close()
|
||||
p.cpufile = nil
|
||||
io.WriteString(resp.ResponseWriter, "[restful] CPU profiling stopped, closing:"+p.cpuprofile)
|
||||
}
|
||||
|
||||
func main() {} // exists for example compilation only
|
107
vendor/github.com/emicklei/go-restful/examples/restful-curly-router.go
generated
vendored
107
vendor/github.com/emicklei/go-restful/examples/restful-curly-router.go
generated
vendored
@ -1,107 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// This example has the same service definition as restful-user-resource
|
||||
// but uses a different router (CurlyRouter) that does not use regular expressions
|
||||
//
|
||||
// POST http://localhost:8080/users
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserResource struct {
|
||||
// normally one would use DAO (data access object)
|
||||
users map[string]User
|
||||
}
|
||||
|
||||
func (u UserResource) Register(container *restful.Container) {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser))
|
||||
ws.Route(ws.POST("").To(u.updateUser))
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.createUser))
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser))
|
||||
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
func (u UserResource) findUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
usr := u.users[id]
|
||||
if len(usr.Id) == 0 {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusNotFound, "User could not be found.")
|
||||
} else {
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
}
|
||||
|
||||
// POST http://localhost:8080/users
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
func (u *UserResource) updateUser(request *restful.Request, response *restful.Response) {
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
u.users[usr.Id] = *usr
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
func (u *UserResource) createUser(request *restful.Request, response *restful.Response) {
|
||||
usr := User{Id: request.PathParameter("user-id")}
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
u.users[usr.Id] = usr
|
||||
response.WriteHeaderAndEntity(http.StatusCreated, usr)
|
||||
} else {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
func (u *UserResource) removeUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
delete(u.users, id)
|
||||
}
|
||||
|
||||
func main() {
|
||||
wsContainer := restful.NewContainer()
|
||||
wsContainer.Router(restful.CurlyRouter{})
|
||||
u := UserResource{map[string]User{}}
|
||||
u.Register(wsContainer)
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
server := &http.Server{Addr: ":8080", Handler: wsContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
149
vendor/github.com/emicklei/go-restful/examples/restful-curly-router_test.go
generated
vendored
149
vendor/github.com/emicklei/go-restful/examples/restful-curly-router_test.go
generated
vendored
@ -1,149 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserResource struct {
|
||||
users map[string]User
|
||||
}
|
||||
|
||||
func (u UserResource) Register(container *restful.Container) {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser))
|
||||
ws.Route(ws.POST("").To(u.updateUser))
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.createUser))
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser))
|
||||
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
// GET http://localhost:8090/users/1
|
||||
//
|
||||
func (u UserResource) findUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
usr := u.users[id]
|
||||
if len(usr.Id) == 0 {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusNotFound, "User could not be found.")
|
||||
} else {
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
}
|
||||
|
||||
// POST http://localhost:8090/users
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
func (u *UserResource) updateUser(request *restful.Request, response *restful.Response) {
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
u.users[usr.Id] = *usr
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// PUT http://localhost:8090/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
func (u *UserResource) createUser(request *restful.Request, response *restful.Response) {
|
||||
usr := User{Id: request.PathParameter("user-id")}
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
u.users[usr.Id] = usr
|
||||
response.WriteHeader(http.StatusCreated)
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8090/users/1
|
||||
//
|
||||
func (u *UserResource) removeUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
delete(u.users, id)
|
||||
}
|
||||
|
||||
func RunRestfulCurlyRouterServer() {
|
||||
wsContainer := restful.NewContainer()
|
||||
wsContainer.Router(restful.CurlyRouter{})
|
||||
u := UserResource{map[string]User{}}
|
||||
u.Register(wsContainer)
|
||||
|
||||
log.Printf("start listening on localhost:8090")
|
||||
server := &http.Server{Addr: ":8090", Handler: wsContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func waitForServerUp(serverURL string) error {
|
||||
for start := time.Now(); time.Since(start) < time.Minute; time.Sleep(5 * time.Second) {
|
||||
_, err := http.Get(serverURL + "/")
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.New("waiting for server timed out")
|
||||
}
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
serverURL := "http://localhost:8090"
|
||||
go func() {
|
||||
RunRestfulCurlyRouterServer()
|
||||
}()
|
||||
if err := waitForServerUp(serverURL); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
// GET should give a 405
|
||||
resp, err := http.Get(serverURL + "/users/")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error in GET /users/: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusMethodNotAllowed {
|
||||
t.Errorf("unexpected response: %v, expected: %v", resp.StatusCode, http.StatusOK)
|
||||
}
|
||||
|
||||
// Send a POST request.
|
||||
var jsonStr = []byte(`{"id":"1","name":"user1"}`)
|
||||
req, err := http.NewRequest("POST", serverURL+"/users/", bytes.NewBuffer(jsonStr))
|
||||
req.Header.Set("Content-Type", restful.MIME_JSON)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error in sending req: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("unexpected response: %v, expected: %v", resp.StatusCode, http.StatusOK)
|
||||
}
|
||||
|
||||
// Test that GET works.
|
||||
resp, err = http.Get(serverURL + "/users/1")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error in GET /users/1: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("unexpected response: %v, expected: %v", resp.StatusCode, http.StatusOK)
|
||||
}
|
||||
}
|
61
vendor/github.com/emicklei/go-restful/examples/restful-encoding-filter.go
generated
vendored
61
vendor/github.com/emicklei/go-restful/examples/restful-encoding-filter.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserList struct {
|
||||
Users []User
|
||||
}
|
||||
|
||||
//
|
||||
// This example shows how to use the CompressingResponseWriter by a Filter
|
||||
// such that encoding can be enabled per WebService or per Route (instead of per container)
|
||||
// Using restful.DefaultContainer.EnableContentEncoding(true) will encode all responses served by WebServices in the DefaultContainer.
|
||||
//
|
||||
// Set Accept-Encoding to gzip or deflate
|
||||
// GET http://localhost:8080/users/42
|
||||
// and look at the response headers
|
||||
|
||||
func main() {
|
||||
restful.Add(NewUserService())
|
||||
log.Printf("start listening on localhost:8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
func NewUserService() *restful.WebService {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||
|
||||
// install a response encoding filter
|
||||
ws.Route(ws.GET("/{user-id}").Filter(encodingFilter).To(findUser))
|
||||
return ws
|
||||
}
|
||||
|
||||
// Route Filter (defines FilterFunction)
|
||||
func encodingFilter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
log.Printf("[encoding-filter] %s,%s\n", req.Request.Method, req.Request.URL)
|
||||
// wrap responseWriter into a compressing one
|
||||
compress, _ := restful.NewCompressingResponseWriter(resp.ResponseWriter, restful.ENCODING_GZIP)
|
||||
resp.ResponseWriter = compress
|
||||
defer func() {
|
||||
compress.Close()
|
||||
}()
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/42
|
||||
//
|
||||
func findUser(request *restful.Request, response *restful.Response) {
|
||||
log.Printf("findUser")
|
||||
response.WriteEntity(User{"42", "Gandalf"})
|
||||
}
|
114
vendor/github.com/emicklei/go-restful/examples/restful-filters.go
generated
vendored
114
vendor/github.com/emicklei/go-restful/examples/restful-filters.go
generated
vendored
@ -1,114 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserList struct {
|
||||
Users []User
|
||||
}
|
||||
|
||||
// This example show how to create and use the three different Filters (Container,WebService and Route)
|
||||
// When applied to the restful.DefaultContainer, we refer to them as a global filter.
|
||||
//
|
||||
// GET http://locahost:8080/users/42
|
||||
// and see the logging per filter (try repeating this request)
|
||||
|
||||
func main() {
|
||||
// install a global (=DefaultContainer) filter (processed before any webservice in the DefaultContainer)
|
||||
restful.Filter(globalLogging)
|
||||
|
||||
restful.Add(NewUserService())
|
||||
log.Printf("start listening on localhost:8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
func NewUserService() *restful.WebService {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||
|
||||
// install a webservice filter (processed before any route)
|
||||
ws.Filter(webserviceLogging).Filter(measureTime)
|
||||
|
||||
// install a counter filter
|
||||
ws.Route(ws.GET("").Filter(NewCountFilter().routeCounter).To(getAllUsers))
|
||||
|
||||
// install 2 chained route filters (processed before calling findUser)
|
||||
ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser))
|
||||
return ws
|
||||
}
|
||||
|
||||
// Global Filter
|
||||
func globalLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
log.Printf("[global-filter (logger)] %s,%s\n", req.Request.Method, req.Request.URL)
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
// WebService Filter
|
||||
func webserviceLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
log.Printf("[webservice-filter (logger)] %s,%s\n", req.Request.Method, req.Request.URL)
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
// WebService (post-process) Filter (as a struct that defines a FilterFunction)
|
||||
func measureTime(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
now := time.Now()
|
||||
chain.ProcessFilter(req, resp)
|
||||
log.Printf("[webservice-filter (timer)] %v\n", time.Now().Sub(now))
|
||||
}
|
||||
|
||||
// Route Filter (defines FilterFunction)
|
||||
func routeLogging(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
log.Printf("[route-filter (logger)] %s,%s\n", req.Request.Method, req.Request.URL)
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
// Route Filter (as a struct that defines a FilterFunction)
|
||||
// CountFilter implements a FilterFunction for counting requests.
|
||||
type CountFilter struct {
|
||||
count int
|
||||
counter chan int // for go-routine safe count increments
|
||||
}
|
||||
|
||||
// NewCountFilter creates and initializes a new CountFilter.
|
||||
func NewCountFilter() *CountFilter {
|
||||
c := new(CountFilter)
|
||||
c.counter = make(chan int)
|
||||
go func() {
|
||||
for {
|
||||
c.count += <-c.counter
|
||||
}
|
||||
}()
|
||||
return c
|
||||
}
|
||||
|
||||
// routeCounter increments the count of the filter (through a channel)
|
||||
func (c *CountFilter) routeCounter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
c.counter <- 1
|
||||
log.Printf("[route-filter (counter)] count:%d", c.count)
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users
|
||||
//
|
||||
func getAllUsers(request *restful.Request, response *restful.Response) {
|
||||
log.Printf("getAllUsers")
|
||||
response.WriteEntity(UserList{[]User{{"42", "Gandalf"}, {"3.14", "Pi"}}})
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/42
|
||||
//
|
||||
func findUser(request *restful.Request, response *restful.Response) {
|
||||
log.Printf("findUser")
|
||||
response.WriteEntity(User{"42", "Gandalf"})
|
||||
}
|
62
vendor/github.com/emicklei/go-restful/examples/restful-form-handling.go
generated
vendored
62
vendor/github.com/emicklei/go-restful/examples/restful-form-handling.go
generated
vendored
@ -1,62 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/gorilla/schema"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to handle a POST of a HTML form that uses the standard x-www-form-urlencoded content-type.
|
||||
// It uses the gorilla web tool kit schema package to decode the form data into a struct.
|
||||
//
|
||||
// GET http://localhost:8080/profiles
|
||||
//
|
||||
|
||||
type Profile struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
var decoder *schema.Decoder
|
||||
|
||||
func main() {
|
||||
decoder = schema.NewDecoder()
|
||||
ws := new(restful.WebService)
|
||||
ws.Route(ws.POST("/profiles").Consumes("application/x-www-form-urlencoded").To(postAdddress))
|
||||
ws.Route(ws.GET("/profiles").To(addresssForm))
|
||||
restful.Add(ws)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func postAdddress(req *restful.Request, resp *restful.Response) {
|
||||
err := req.Request.ParseForm()
|
||||
if err != nil {
|
||||
resp.WriteErrorString(http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
p := new(Profile)
|
||||
err = decoder.Decode(p, req.Request.PostForm)
|
||||
if err != nil {
|
||||
resp.WriteErrorString(http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
io.WriteString(resp.ResponseWriter, fmt.Sprintf("<html><body>Name=%s, Age=%d</body></html>", p.Name, p.Age))
|
||||
}
|
||||
|
||||
func addresssForm(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp.ResponseWriter,
|
||||
`<html>
|
||||
<body>
|
||||
<h1>Enter Profile</h1>
|
||||
<form method="post">
|
||||
<label>Name:</label>
|
||||
<input type="text" name="Name"/>
|
||||
<label>Age:</label>
|
||||
<input type="text" name="Age"/>
|
||||
<input type="Submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>`)
|
||||
}
|
22
vendor/github.com/emicklei/go-restful/examples/restful-hello-world.go
generated
vendored
22
vendor/github.com/emicklei/go-restful/examples/restful-hello-world.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows the minimal code needed to get a restful.WebService working.
|
||||
//
|
||||
// GET http://localhost:8080/hello
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Route(ws.GET("/hello").To(hello))
|
||||
restful.Add(ws)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func hello(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "world")
|
||||
}
|
35
vendor/github.com/emicklei/go-restful/examples/restful-html-template.go
generated
vendored
35
vendor/github.com/emicklei/go-restful/examples/restful-html-template.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"text/template"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// This example shows how to serve a HTML page using the standard Go template engine.
|
||||
//
|
||||
// GET http://localhost:8080/
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Route(ws.GET("/").To(home))
|
||||
restful.Add(ws)
|
||||
print("open browser on http://localhost:8080/\n")
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Text string
|
||||
}
|
||||
|
||||
func home(req *restful.Request, resp *restful.Response) {
|
||||
p := &Message{"restful-html-template demo"}
|
||||
// you might want to cache compiled templates
|
||||
t, err := template.ParseFiles("home.html")
|
||||
if err != nil {
|
||||
log.Fatalf("Template gave: %s", err)
|
||||
}
|
||||
t.Execute(resp.ResponseWriter, p)
|
||||
}
|
43
vendor/github.com/emicklei/go-restful/examples/restful-multi-containers.go
generated
vendored
43
vendor/github.com/emicklei/go-restful/examples/restful-multi-containers.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to have a program with 2 WebServices containers
|
||||
// each having a http server listening on its own port.
|
||||
//
|
||||
// The first "hello" is added to the restful.DefaultContainer (and uses DefaultServeMux)
|
||||
// For the second "hello", a new container and ServeMux is created
|
||||
// and requires a new http.Server with the container being the Handler.
|
||||
// This first server is spawn in its own go-routine such that the program proceeds to create the second.
|
||||
//
|
||||
// GET http://localhost:8080/hello
|
||||
// GET http://localhost:8081/hello
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Route(ws.GET("/hello").To(hello))
|
||||
restful.Add(ws)
|
||||
go func() {
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}()
|
||||
|
||||
container2 := restful.NewContainer()
|
||||
ws2 := new(restful.WebService)
|
||||
ws2.Route(ws2.GET("/hello").To(hello2))
|
||||
container2.Add(ws2)
|
||||
server := &http.Server{Addr: ":8081", Handler: container2}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func hello(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "default world")
|
||||
}
|
||||
|
||||
func hello2(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "second world")
|
||||
}
|
24
vendor/github.com/emicklei/go-restful/examples/restful-no-cache-filter.go
generated
vendored
24
vendor/github.com/emicklei/go-restful/examples/restful-no-cache-filter.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// This example shows how to use a WebService filter that passed the Http headers to disable browser cacheing.
|
||||
//
|
||||
// GET http://localhost:8080/hello
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Filter(restful.NoBrowserCacheFilter)
|
||||
ws.Route(ws.GET("/hello").To(hello))
|
||||
restful.Add(ws)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func hello(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "world")
|
||||
}
|
51
vendor/github.com/emicklei/go-restful/examples/restful-options-filter.go
generated
vendored
51
vendor/github.com/emicklei/go-restful/examples/restful-options-filter.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to use the OPTIONSFilter on a Container
|
||||
//
|
||||
// OPTIONS http://localhost:8080/users
|
||||
//
|
||||
// OPTIONS http://localhost:8080/users/1
|
||||
|
||||
type UserResource struct{}
|
||||
|
||||
func (u UserResource) RegisterTo(container *restful.Container) {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes("*/*").
|
||||
Produces("*/*")
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.nop))
|
||||
ws.Route(ws.POST("").To(u.nop))
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.nop))
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.nop))
|
||||
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
func (u UserResource) nop(request *restful.Request, response *restful.Response) {
|
||||
io.WriteString(response.ResponseWriter, "this would be a normal response")
|
||||
}
|
||||
|
||||
func main() {
|
||||
wsContainer := restful.NewContainer()
|
||||
u := UserResource{}
|
||||
u.RegisterTo(wsContainer)
|
||||
|
||||
// Add container filter to respond to OPTIONS
|
||||
wsContainer.Filter(wsContainer.OPTIONSFilter)
|
||||
|
||||
// For use on the default container, you can write
|
||||
// restful.Filter(restful.OPTIONSFilter())
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
server := &http.Server{Addr: ":8080", Handler: wsContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
26
vendor/github.com/emicklei/go-restful/examples/restful-path-tail.go
generated
vendored
26
vendor/github.com/emicklei/go-restful/examples/restful-path-tail.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
. "github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to a Route that matches the "tail" of a path.
|
||||
// Requires the use of a CurlyRouter and the star "*" path parameter pattern.
|
||||
//
|
||||
// GET http://localhost:8080/basepath/some/other/location/test.xml
|
||||
|
||||
func main() {
|
||||
DefaultContainer.Router(CurlyRouter{})
|
||||
ws := new(WebService)
|
||||
ws.Route(ws.GET("/basepath/{resource:*}").To(staticFromPathParam))
|
||||
Add(ws)
|
||||
|
||||
println("[go-restful] serve path tails from http://localhost:8080/basepath")
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func staticFromPathParam(req *Request, resp *Response) {
|
||||
io.WriteString(resp, "Tail="+req.PathParameter("resource"))
|
||||
}
|
98
vendor/github.com/emicklei/go-restful/examples/restful-pre-post-filters.go
generated
vendored
98
vendor/github.com/emicklei/go-restful/examples/restful-pre-post-filters.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how the different types of filters are called in the request-response flow.
|
||||
// The call chain is logged on the console when sending an http request.
|
||||
//
|
||||
// GET http://localhost:8080/1
|
||||
// GET http://localhost:8080/2
|
||||
|
||||
var indentLevel int
|
||||
|
||||
func container_filter_A(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
log.Printf("url path:%v\n", req.Request.URL)
|
||||
trace("container_filter_A: before", 1)
|
||||
chain.ProcessFilter(req, resp)
|
||||
trace("container_filter_A: after", -1)
|
||||
}
|
||||
|
||||
func container_filter_B(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
trace("container_filter_B: before", 1)
|
||||
chain.ProcessFilter(req, resp)
|
||||
trace("container_filter_B: after", -1)
|
||||
}
|
||||
|
||||
func service_filter_A(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
trace("service_filter_A: before", 1)
|
||||
chain.ProcessFilter(req, resp)
|
||||
trace("service_filter_A: after", -1)
|
||||
}
|
||||
|
||||
func service_filter_B(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
trace("service_filter_B: before", 1)
|
||||
chain.ProcessFilter(req, resp)
|
||||
trace("service_filter_B: after", -1)
|
||||
}
|
||||
|
||||
func route_filter_A(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
trace("route_filter_A: before", 1)
|
||||
chain.ProcessFilter(req, resp)
|
||||
trace("route_filter_A: after", -1)
|
||||
}
|
||||
|
||||
func route_filter_B(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
trace("route_filter_B: before", 1)
|
||||
chain.ProcessFilter(req, resp)
|
||||
trace("route_filter_B: after", -1)
|
||||
}
|
||||
|
||||
func trace(what string, delta int) {
|
||||
indented := what
|
||||
if delta < 0 {
|
||||
indentLevel += delta
|
||||
}
|
||||
for t := 0; t < indentLevel; t++ {
|
||||
indented = "." + indented
|
||||
}
|
||||
log.Printf("%s", indented)
|
||||
if delta > 0 {
|
||||
indentLevel += delta
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
restful.Filter(container_filter_A)
|
||||
restful.Filter(container_filter_B)
|
||||
|
||||
ws1 := new(restful.WebService)
|
||||
ws1.Path("/1")
|
||||
ws1.Filter(service_filter_A)
|
||||
ws1.Filter(service_filter_B)
|
||||
ws1.Route(ws1.GET("").To(doit1).Filter(route_filter_A).Filter(route_filter_B))
|
||||
|
||||
ws2 := new(restful.WebService)
|
||||
ws2.Path("/2")
|
||||
ws2.Filter(service_filter_A)
|
||||
ws2.Filter(service_filter_B)
|
||||
ws2.Route(ws2.GET("").To(doit2).Filter(route_filter_A).Filter(route_filter_B))
|
||||
|
||||
restful.Add(ws1)
|
||||
restful.Add(ws2)
|
||||
|
||||
log.Print("go-restful example listing on http://localhost:8080/1 and http://localhost:8080/2")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
func doit1(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "nothing to see in 1")
|
||||
}
|
||||
|
||||
func doit2(req *restful.Request, resp *restful.Response) {
|
||||
io.WriteString(resp, "nothing to see in 2")
|
||||
}
|
63
vendor/github.com/emicklei/go-restful/examples/restful-resource-functions.go
generated
vendored
63
vendor/github.com/emicklei/go-restful/examples/restful-resource-functions.go
generated
vendored
@ -1,63 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to use methods as RouteFunctions for WebServices.
|
||||
// The ProductResource has a Register() method that creates and initializes
|
||||
// a WebService to expose its methods as REST operations.
|
||||
// The WebService is added to the restful.DefaultContainer.
|
||||
// A ProductResource is typically created using some data access object.
|
||||
//
|
||||
// GET http://localhost:8080/products/1
|
||||
// POST http://localhost:8080/products
|
||||
// <Product><Id>1</Id><Title>The First</Title></Product>
|
||||
|
||||
type Product struct {
|
||||
Id, Title string
|
||||
}
|
||||
|
||||
type ProductResource struct {
|
||||
// typically reference a DAO (data-access-object)
|
||||
}
|
||||
|
||||
func (p ProductResource) getOne(req *restful.Request, resp *restful.Response) {
|
||||
id := req.PathParameter("id")
|
||||
log.Println("getting product with id:" + id)
|
||||
resp.WriteEntity(Product{Id: id, Title: "test"})
|
||||
}
|
||||
|
||||
func (p ProductResource) postOne(req *restful.Request, resp *restful.Response) {
|
||||
updatedProduct := new(Product)
|
||||
err := req.ReadEntity(updatedProduct)
|
||||
if err != nil { // bad request
|
||||
resp.WriteErrorString(http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
log.Println("updating product with id:" + updatedProduct.Id)
|
||||
}
|
||||
|
||||
func (p ProductResource) Register() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path("/products")
|
||||
ws.Consumes(restful.MIME_XML)
|
||||
ws.Produces(restful.MIME_XML)
|
||||
|
||||
ws.Route(ws.GET("/{id}").To(p.getOne).
|
||||
Doc("get the product by its id").
|
||||
Param(ws.PathParameter("id", "identifier of the product").DataType("string")))
|
||||
|
||||
ws.Route(ws.POST("").To(p.postOne).
|
||||
Doc("update or create a product").
|
||||
Param(ws.BodyParameter("Product", "a Product (XML)").DataType("main.Product")))
|
||||
|
||||
restful.Add(ws)
|
||||
}
|
||||
|
||||
func main() {
|
||||
ProductResource{}.Register()
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
39
vendor/github.com/emicklei/go-restful/examples/restful-route_test.go
generated
vendored
39
vendor/github.com/emicklei/go-restful/examples/restful-route_test.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
var (
|
||||
Result string
|
||||
)
|
||||
|
||||
func TestRouteExtractParameter(t *testing.T) {
|
||||
// setup service
|
||||
ws := new(restful.WebService)
|
||||
ws.Consumes(restful.MIME_XML)
|
||||
ws.Route(ws.GET("/test/{param}").To(DummyHandler))
|
||||
restful.Add(ws)
|
||||
|
||||
// setup request + writer
|
||||
bodyReader := strings.NewReader("<Sample><Value>42</Value></Sample>")
|
||||
httpRequest, _ := http.NewRequest("GET", "/test/THIS", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", restful.MIME_XML)
|
||||
httpWriter := httptest.NewRecorder()
|
||||
|
||||
// run
|
||||
restful.DefaultContainer.ServeHTTP(httpWriter, httpRequest)
|
||||
|
||||
if Result != "THIS" {
|
||||
t.Fatalf("Result is actually: %s", Result)
|
||||
}
|
||||
}
|
||||
|
||||
func DummyHandler(rq *restful.Request, rp *restful.Response) {
|
||||
Result = rq.PathParameter("param")
|
||||
}
|
29
vendor/github.com/emicklei/go-restful/examples/restful-routefunction_test.go
generated
vendored
29
vendor/github.com/emicklei/go-restful/examples/restful-routefunction_test.go
generated
vendored
@ -1,29 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// This example show how to test one particular RouteFunction (getIt)
|
||||
// It uses the httptest.ResponseRecorder to capture output
|
||||
|
||||
func getIt(req *restful.Request, resp *restful.Response) {
|
||||
resp.WriteHeader(204)
|
||||
}
|
||||
|
||||
func TestCallFunction(t *testing.T) {
|
||||
httpReq, _ := http.NewRequest("GET", "/", nil)
|
||||
req := restful.NewRequest(httpReq)
|
||||
|
||||
recorder := new(httptest.ResponseRecorder)
|
||||
resp := restful.NewResponse(recorder)
|
||||
|
||||
getIt(req, resp)
|
||||
if recorder.Code != 204 {
|
||||
t.Fatalf("Missing or wrong status code:%d", recorder.Code)
|
||||
}
|
||||
}
|
47
vendor/github.com/emicklei/go-restful/examples/restful-serve-static.go
generated
vendored
47
vendor/github.com/emicklei/go-restful/examples/restful-serve-static.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
// This example shows how to define methods that serve static files
|
||||
// It uses the standard http.ServeFile method
|
||||
//
|
||||
// GET http://localhost:8080/static/test.xml
|
||||
// GET http://localhost:8080/static/
|
||||
//
|
||||
// GET http://localhost:8080/static?resource=subdir/test.xml
|
||||
|
||||
var rootdir = "/tmp"
|
||||
|
||||
func main() {
|
||||
restful.DefaultContainer.Router(restful.CurlyRouter{})
|
||||
|
||||
ws := new(restful.WebService)
|
||||
ws.Route(ws.GET("/static/{subpath:*}").To(staticFromPathParam))
|
||||
ws.Route(ws.GET("/static").To(staticFromQueryParam))
|
||||
restful.Add(ws)
|
||||
|
||||
println("[go-restful] serving files on http://localhost:8080/static from local /tmp")
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
func staticFromPathParam(req *restful.Request, resp *restful.Response) {
|
||||
actual := path.Join(rootdir, req.PathParameter("subpath"))
|
||||
fmt.Printf("serving %s ... (from %s)\n", actual, req.PathParameter("subpath"))
|
||||
http.ServeFile(
|
||||
resp.ResponseWriter,
|
||||
req.Request,
|
||||
actual)
|
||||
}
|
||||
|
||||
func staticFromQueryParam(req *restful.Request, resp *restful.Response) {
|
||||
http.ServeFile(
|
||||
resp.ResponseWriter,
|
||||
req.Request,
|
||||
path.Join(rootdir, req.QueryParameter("resource")))
|
||||
}
|
61
vendor/github.com/emicklei/go-restful/examples/restful-swagger.go
generated
vendored
61
vendor/github.com/emicklei/go-restful/examples/restful-swagger.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
)
|
||||
|
||||
type Book struct {
|
||||
Title string
|
||||
Author string
|
||||
}
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path("/books")
|
||||
ws.Consumes(restful.MIME_JSON, restful.MIME_XML)
|
||||
ws.Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||
restful.Add(ws)
|
||||
|
||||
ws.Route(ws.GET("/{medium}").To(noop).
|
||||
Doc("Search all books").
|
||||
Param(ws.PathParameter("medium", "digital or paperback").DataType("string")).
|
||||
Param(ws.QueryParameter("language", "en,nl,de").DataType("string")).
|
||||
Param(ws.HeaderParameter("If-Modified-Since", "last known timestamp").DataType("datetime")).
|
||||
Do(returns200, returns500))
|
||||
|
||||
ws.Route(ws.PUT("/{medium}").To(noop).
|
||||
Doc("Add a new book").
|
||||
Param(ws.PathParameter("medium", "digital or paperback").DataType("string")).
|
||||
Reads(Book{}))
|
||||
|
||||
// You can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open http://localhost:8080/apidocs and enter http://localhost:8080/apidocs.json in the api input field.
|
||||
config := swagger.Config{
|
||||
WebServices: restful.DefaultContainer.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesUrl: "http://localhost:8080",
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specifiy where the UI is located
|
||||
SwaggerPath: "/apidocs/",
|
||||
SwaggerFilePath: "/Users/emicklei/xProjects/swagger-ui/dist"}
|
||||
swagger.RegisterSwaggerService(config, restful.DefaultContainer)
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
server := &http.Server{Addr: ":8080", Handler: restful.DefaultContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
func noop(req *restful.Request, resp *restful.Response) {}
|
||||
|
||||
func returns200(b *restful.RouteBuilder) {
|
||||
b.Returns(http.StatusOK, "OK", Book{})
|
||||
}
|
||||
|
||||
func returns500(b *restful.RouteBuilder) {
|
||||
b.Returns(http.StatusInternalServerError, "Bummer, something went wrong", nil)
|
||||
}
|
152
vendor/github.com/emicklei/go-restful/examples/restful-user-resource.go
generated
vendored
152
vendor/github.com/emicklei/go-restful/examples/restful-user-resource.go
generated
vendored
@ -1,152 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
)
|
||||
|
||||
// This example show a complete (GET,PUT,POST,DELETE) conventional example of
|
||||
// a REST Resource including documentation to be served by e.g. a Swagger UI
|
||||
// It is recommended to create a Resource struct (UserResource) that can encapsulate
|
||||
// an object that provide domain access (a DAO)
|
||||
// It has a Register method including the complete Route mapping to methods together
|
||||
// with all the appropriate documentation
|
||||
//
|
||||
// POST http://localhost:8080/users
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserResource struct {
|
||||
// normally one would use DAO (data access object)
|
||||
users map[string]User
|
||||
}
|
||||
|
||||
func (u UserResource) Register(container *restful.Container) {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Doc("Manage Users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser).
|
||||
// docs
|
||||
Doc("get a user").
|
||||
Operation("findUser").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Writes(User{})) // on the response
|
||||
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.updateUser).
|
||||
// docs
|
||||
Doc("update a user").
|
||||
Operation("updateUser").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
ReturnsError(409, "duplicate user-id", nil).
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.POST("").To(u.createUser).
|
||||
// docs
|
||||
Doc("create a user").
|
||||
Operation("createUser").
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser).
|
||||
// docs
|
||||
Doc("delete a user").
|
||||
Operation("removeUser").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")))
|
||||
|
||||
container.Add(ws)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
func (u UserResource) findUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
usr := u.users[id]
|
||||
if len(usr.Id) == 0 {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusNotFound, "404: User could not be found.")
|
||||
return
|
||||
}
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
|
||||
// POST http://localhost:8080/users
|
||||
// <User><Name>Melissa</Name></User>
|
||||
//
|
||||
func (u *UserResource) createUser(request *restful.Request, response *restful.Response) {
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(usr)
|
||||
if err != nil {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
usr.Id = strconv.Itoa(len(u.users) + 1) // simple id generation
|
||||
u.users[usr.Id] = *usr
|
||||
response.WriteHeaderAndEntity(http.StatusCreated, usr)
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
func (u *UserResource) updateUser(request *restful.Request, response *restful.Response) {
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(&usr)
|
||||
if err != nil {
|
||||
response.AddHeader("Content-Type", "text/plain")
|
||||
response.WriteErrorString(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
u.users[usr.Id] = *usr
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
func (u *UserResource) removeUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
delete(u.users, id)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// to see what happens in the package, uncomment the following
|
||||
//restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile))
|
||||
|
||||
wsContainer := restful.NewContainer()
|
||||
u := UserResource{map[string]User{}}
|
||||
u.Register(wsContainer)
|
||||
|
||||
// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open http://localhost:8080/apidocs and enter http://localhost:8080/apidocs.json in the api input field.
|
||||
config := swagger.Config{
|
||||
WebServices: wsContainer.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesUrl: "http://localhost:8080",
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specifiy where the UI is located
|
||||
SwaggerPath: "/apidocs/",
|
||||
SwaggerFilePath: "/Users/emicklei/xProjects/swagger-ui/dist"}
|
||||
swagger.RegisterSwaggerService(config, wsContainer)
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
server := &http.Server{Addr: ":8080", Handler: wsContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
143
vendor/github.com/emicklei/go-restful/examples/restful-user-service.go
generated
vendored
143
vendor/github.com/emicklei/go-restful/examples/restful-user-service.go
generated
vendored
@ -1,143 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
)
|
||||
|
||||
// This example is functionally the same as the example in restful-user-resource.go
|
||||
// with the only difference that is served using the restful.DefaultContainer
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserService struct {
|
||||
// normally one would use DAO (data access object)
|
||||
users map[string]User
|
||||
}
|
||||
|
||||
func (u UserService) Register() {
|
||||
ws := new(restful.WebService)
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well
|
||||
|
||||
ws.Route(ws.GET("/").To(u.findAllUsers).
|
||||
// docs
|
||||
Doc("get all users").
|
||||
Operation("findAllUsers").
|
||||
Writes([]User{}).
|
||||
Returns(200, "OK", nil))
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser).
|
||||
// docs
|
||||
Doc("get a user").
|
||||
Operation("findUser").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Writes(User{}). // on the response
|
||||
Returns(404, "Not Found", nil))
|
||||
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.updateUser).
|
||||
// docs
|
||||
Doc("update a user").
|
||||
Operation("updateUser").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.PUT("").To(u.createUser).
|
||||
// docs
|
||||
Doc("create a user").
|
||||
Operation("createUser").
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser).
|
||||
// docs
|
||||
Doc("delete a user").
|
||||
Operation("removeUser").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")))
|
||||
|
||||
restful.Add(ws)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users
|
||||
//
|
||||
func (u UserService) findAllUsers(request *restful.Request, response *restful.Response) {
|
||||
list := []User{}
|
||||
for _, each := range u.users {
|
||||
list = append(list, each)
|
||||
}
|
||||
response.WriteEntity(list)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
func (u UserService) findUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
usr := u.users[id]
|
||||
if len(usr.Id) == 0 {
|
||||
response.WriteErrorString(http.StatusNotFound, "User could not be found.")
|
||||
} else {
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
func (u *UserService) updateUser(request *restful.Request, response *restful.Response) {
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
u.users[usr.Id] = *usr
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
func (u *UserService) createUser(request *restful.Request, response *restful.Response) {
|
||||
usr := User{Id: request.PathParameter("user-id")}
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
u.users[usr.Id] = usr
|
||||
response.WriteHeaderAndEntity(http.StatusCreated, usr)
|
||||
} else {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
func (u *UserService) removeUser(request *restful.Request, response *restful.Response) {
|
||||
id := request.PathParameter("user-id")
|
||||
delete(u.users, id)
|
||||
}
|
||||
|
||||
func main() {
|
||||
u := UserService{map[string]User{}}
|
||||
u.Register()
|
||||
|
||||
// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open http://localhost:8080/apidocs and enter http://localhost:8080/apidocs.json in the api input field.
|
||||
config := swagger.Config{
|
||||
WebServices: restful.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesUrl: "http://localhost:8080",
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specifiy where the UI is located
|
||||
SwaggerPath: "/apidocs/",
|
||||
SwaggerFilePath: "/Users/emicklei/Projects/swagger-ui/dist"}
|
||||
swagger.InstallSwaggerService(config)
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
141
vendor/github.com/emicklei/go-restful/filter_test.go
generated
vendored
141
vendor/github.com/emicklei/go-restful/filter_test.go
generated
vendored
@ -1,141 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setupServices(addGlobalFilter bool, addServiceFilter bool, addRouteFilter bool) {
|
||||
if addGlobalFilter {
|
||||
Filter(globalFilter)
|
||||
}
|
||||
Add(newTestService(addServiceFilter, addRouteFilter))
|
||||
}
|
||||
|
||||
func tearDown() {
|
||||
DefaultContainer.webServices = []*WebService{}
|
||||
DefaultContainer.isRegisteredOnRoot = true // this allows for setupServices multiple times
|
||||
DefaultContainer.containerFilters = []FilterFunction{}
|
||||
}
|
||||
|
||||
func newTestService(addServiceFilter bool, addRouteFilter bool) *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
if addServiceFilter {
|
||||
ws.Filter(serviceFilter)
|
||||
}
|
||||
rb := ws.GET("/foo").To(foo)
|
||||
if addRouteFilter {
|
||||
rb.Filter(routeFilter)
|
||||
}
|
||||
ws.Route(rb)
|
||||
ws.Route(ws.GET("/bar").To(bar))
|
||||
return ws
|
||||
}
|
||||
|
||||
func foo(req *Request, resp *Response) {
|
||||
io.WriteString(resp.ResponseWriter, "foo")
|
||||
}
|
||||
|
||||
func bar(req *Request, resp *Response) {
|
||||
io.WriteString(resp.ResponseWriter, "bar")
|
||||
}
|
||||
|
||||
func fail(req *Request, resp *Response) {
|
||||
http.Error(resp.ResponseWriter, "something failed", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
func globalFilter(req *Request, resp *Response, chain *FilterChain) {
|
||||
io.WriteString(resp.ResponseWriter, "global-")
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
func serviceFilter(req *Request, resp *Response, chain *FilterChain) {
|
||||
io.WriteString(resp.ResponseWriter, "service-")
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
func routeFilter(req *Request, resp *Response, chain *FilterChain) {
|
||||
io.WriteString(resp.ResponseWriter, "route-")
|
||||
chain.ProcessFilter(req, resp)
|
||||
}
|
||||
|
||||
func TestNoFilter(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(false, false, false)
|
||||
actual := sendIt("http://example.com/foo")
|
||||
if "foo" != actual {
|
||||
t.Fatal("expected: foo but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalFilter(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(true, false, false)
|
||||
actual := sendIt("http://example.com/foo")
|
||||
if "global-foo" != actual {
|
||||
t.Fatal("expected: global-foo but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWebServiceFilter(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(true, true, false)
|
||||
actual := sendIt("http://example.com/foo")
|
||||
if "global-service-foo" != actual {
|
||||
t.Fatal("expected: global-service-foo but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteFilter(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(true, true, true)
|
||||
actual := sendIt("http://example.com/foo")
|
||||
if "global-service-route-foo" != actual {
|
||||
t.Fatal("expected: global-service-route-foo but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteFilterOnly(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(false, false, true)
|
||||
actual := sendIt("http://example.com/foo")
|
||||
if "route-foo" != actual {
|
||||
t.Fatal("expected: route-foo but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBar(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(false, true, false)
|
||||
actual := sendIt("http://example.com/bar")
|
||||
if "service-bar" != actual {
|
||||
t.Fatal("expected: service-bar but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllFiltersBar(t *testing.T) {
|
||||
tearDown()
|
||||
setupServices(true, true, true)
|
||||
actual := sendIt("http://example.com/bar")
|
||||
if "global-service-bar" != actual {
|
||||
t.Fatal("expected: global-service-bar but got:" + actual)
|
||||
}
|
||||
}
|
||||
|
||||
func sendIt(address string) string {
|
||||
httpRequest, _ := http.NewRequest("GET", address, nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
return httpWriter.Body.String()
|
||||
}
|
||||
|
||||
func sendItTo(address string, container *Container) string {
|
||||
httpRequest, _ := http.NewRequest("GET", address, nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
container.dispatch(httpWriter, httpRequest)
|
||||
return httpWriter.Body.String()
|
||||
}
|
212
vendor/github.com/emicklei/go-restful/jsr311_test.go
generated
vendored
212
vendor/github.com/emicklei/go-restful/jsr311_test.go
generated
vendored
@ -1,212 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//
|
||||
// Step 1 tests
|
||||
//
|
||||
var paths = []struct {
|
||||
// url with path (1) is handled by service with root (2) and last capturing group has value final (3)
|
||||
path, root, final string
|
||||
}{
|
||||
{"/", "/", "/"},
|
||||
{"/p", "/p", ""},
|
||||
{"/p/x", "/p/{q}", ""},
|
||||
{"/q/x", "/q", "/x"},
|
||||
{"/p/x/", "/p/{q}", "/"},
|
||||
{"/p/x/y", "/p/{q}", "/y"},
|
||||
{"/q/x/y", "/q", "/x/y"},
|
||||
{"/z/q", "/{p}/q", ""},
|
||||
{"/a/b/c/q", "/", "/a/b/c/q"},
|
||||
}
|
||||
|
||||
func TestDetectDispatcher(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws2 := new(WebService).Path("/p")
|
||||
ws3 := new(WebService).Path("/q")
|
||||
ws4 := new(WebService).Path("/p/q")
|
||||
ws5 := new(WebService).Path("/p/{q}")
|
||||
ws6 := new(WebService).Path("/p/{q}/")
|
||||
ws7 := new(WebService).Path("/{p}/q")
|
||||
var dispatchers = []*WebService{ws1, ws2, ws3, ws4, ws5, ws6, ws7}
|
||||
|
||||
wc := NewContainer()
|
||||
for _, each := range dispatchers {
|
||||
wc.Add(each)
|
||||
}
|
||||
|
||||
router := RouterJSR311{}
|
||||
|
||||
ok := true
|
||||
for i, fixture := range paths {
|
||||
who, final, err := router.detectDispatcher(fixture.path, dispatchers)
|
||||
if err != nil {
|
||||
t.Logf("error in detection:%v", err)
|
||||
ok = false
|
||||
}
|
||||
if who.RootPath() != fixture.root {
|
||||
t.Logf("[line:%v] Unexpected dispatcher, expected:%v, actual:%v", i, fixture.root, who.RootPath())
|
||||
ok = false
|
||||
}
|
||||
if final != fixture.final {
|
||||
t.Logf("[line:%v] Unexpected final, expected:%v, actual:%v", i, fixture.final, final)
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Step 2 tests
|
||||
//
|
||||
|
||||
// go test -v -test.run TestISSUE_179 ...restful
|
||||
func TestISSUE_179(t *testing.T) {
|
||||
ws1 := new(WebService)
|
||||
ws1.Route(ws1.GET("/v1/category/{param:*}").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/v1/category/sub/sub")
|
||||
t.Logf("%v", routes)
|
||||
}
|
||||
|
||||
// go test -v -test.run TestISSUE_30 ...restful
|
||||
func TestISSUE_30(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/users")
|
||||
ws1.Route(ws1.GET("/{id}").To(dummy))
|
||||
ws1.Route(ws1.POST("/login").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/login")
|
||||
if len(routes) != 2 {
|
||||
t.Fatal("expected 2 routes")
|
||||
}
|
||||
if routes[0].Path != "/users/login" {
|
||||
t.Error("first is", routes[0].Path)
|
||||
t.Logf("routes:%v", routes)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestISSUE_34 ...restful
|
||||
func TestISSUE_34(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws1.Route(ws1.GET("/{type}/{id}").To(dummy))
|
||||
ws1.Route(ws1.GET("/network/{id}").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/network/12")
|
||||
if len(routes) != 2 {
|
||||
t.Fatal("expected 2 routes")
|
||||
}
|
||||
if routes[0].Path != "/network/{id}" {
|
||||
t.Error("first is", routes[0].Path)
|
||||
t.Logf("routes:%v", routes)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestISSUE_34_2 ...restful
|
||||
func TestISSUE_34_2(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
// change the registration order
|
||||
ws1.Route(ws1.GET("/network/{id}").To(dummy))
|
||||
ws1.Route(ws1.GET("/{type}/{id}").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/network/12")
|
||||
if len(routes) != 2 {
|
||||
t.Fatal("expected 2 routes")
|
||||
}
|
||||
if routes[0].Path != "/network/{id}" {
|
||||
t.Error("first is", routes[0].Path)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestISSUE_137 ...restful
|
||||
func TestISSUE_137(t *testing.T) {
|
||||
ws1 := new(WebService)
|
||||
ws1.Route(ws1.GET("/hello").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/")
|
||||
t.Log(routes)
|
||||
if len(routes) > 0 {
|
||||
t.Error("no route expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectRoutesSlash(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/")
|
||||
ws1.Route(ws1.GET("").To(dummy))
|
||||
ws1.Route(ws1.GET("/").To(dummy))
|
||||
ws1.Route(ws1.GET("/u").To(dummy))
|
||||
ws1.Route(ws1.POST("/u").To(dummy))
|
||||
ws1.Route(ws1.POST("/u/v").To(dummy))
|
||||
ws1.Route(ws1.POST("/u/{w}").To(dummy))
|
||||
ws1.Route(ws1.POST("/u/{w}/z").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/u")
|
||||
checkRoutesContains(routes, "/u", t)
|
||||
checkRoutesContainsNo(routes, "/u/v", t)
|
||||
checkRoutesContainsNo(routes, "/", t)
|
||||
checkRoutesContainsNo(routes, "/u/{w}/z", t)
|
||||
}
|
||||
func TestSelectRoutesU(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/u")
|
||||
ws1.Route(ws1.GET("").To(dummy))
|
||||
ws1.Route(ws1.GET("/").To(dummy))
|
||||
ws1.Route(ws1.GET("/v").To(dummy))
|
||||
ws1.Route(ws1.POST("/{w}").To(dummy))
|
||||
ws1.Route(ws1.POST("/{w}/z").To(dummy)) // so full path = /u/{w}/z
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/v") // test against /u/v
|
||||
checkRoutesContains(routes, "/u/{w}", t)
|
||||
}
|
||||
|
||||
func TestSelectRoutesUsers1(t *testing.T) {
|
||||
ws1 := new(WebService).Path("/users")
|
||||
ws1.Route(ws1.POST("").To(dummy))
|
||||
ws1.Route(ws1.POST("/").To(dummy))
|
||||
ws1.Route(ws1.PUT("/{id}").To(dummy))
|
||||
routes := RouterJSR311{}.selectRoutes(ws1, "/1")
|
||||
checkRoutesContains(routes, "/users/{id}", t)
|
||||
}
|
||||
func checkRoutesContains(routes []Route, path string, t *testing.T) {
|
||||
if !containsRoutePath(routes, path, t) {
|
||||
for _, r := range routes {
|
||||
t.Logf("route %v %v", r.Method, r.Path)
|
||||
}
|
||||
t.Fatalf("routes should include [%v]:", path)
|
||||
}
|
||||
}
|
||||
func checkRoutesContainsNo(routes []Route, path string, t *testing.T) {
|
||||
if containsRoutePath(routes, path, t) {
|
||||
for _, r := range routes {
|
||||
t.Logf("route %v %v", r.Method, r.Path)
|
||||
}
|
||||
t.Fatalf("routes should not include [%v]:", path)
|
||||
}
|
||||
}
|
||||
func containsRoutePath(routes []Route, path string, t *testing.T) bool {
|
||||
for _, each := range routes {
|
||||
if each.Path == path {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// go test -v -test.run TestSortableRouteCandidates ...restful
|
||||
func TestSortableRouteCandidates(t *testing.T) {
|
||||
fixture := &sortableRouteCandidates{}
|
||||
r1 := routeCandidate{matchesCount: 0, literalCount: 0, nonDefaultCount: 0}
|
||||
r2 := routeCandidate{matchesCount: 0, literalCount: 0, nonDefaultCount: 1}
|
||||
r3 := routeCandidate{matchesCount: 0, literalCount: 1, nonDefaultCount: 1}
|
||||
r4 := routeCandidate{matchesCount: 1, literalCount: 1, nonDefaultCount: 0}
|
||||
r5 := routeCandidate{matchesCount: 1, literalCount: 0, nonDefaultCount: 0}
|
||||
fixture.candidates = append(fixture.candidates, r5, r4, r3, r2, r1)
|
||||
sort.Sort(sort.Reverse(fixture))
|
||||
first := fixture.candidates[0]
|
||||
if first.matchesCount != 1 && first.literalCount != 1 && first.nonDefaultCount != 0 {
|
||||
t.Fatal("expected r4")
|
||||
}
|
||||
last := fixture.candidates[len(fixture.candidates)-1]
|
||||
if last.matchesCount != 0 && last.literalCount != 0 && last.nonDefaultCount != 0 {
|
||||
t.Fatal("expected r1")
|
||||
}
|
||||
}
|
||||
|
||||
func dummy(req *Request, resp *Response) { io.WriteString(resp.ResponseWriter, "dummy") }
|
17
vendor/github.com/emicklei/go-restful/mime_test.go
generated
vendored
17
vendor/github.com/emicklei/go-restful/mime_test.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test -v -test.run TestSortMimes ...restful
|
||||
func TestSortMimes(t *testing.T) {
|
||||
accept := "text/html; q=0.8, text/plain, image/gif, */*; q=0.01, image/jpeg"
|
||||
result := sortedMimes(accept)
|
||||
got := fmt.Sprintf("%v", result)
|
||||
want := "[{text/plain 1} {image/gif 1} {image/jpeg 1} {text/html 0.8} {*/* 0.01}]"
|
||||
if got != want {
|
||||
t.Errorf("bad sort order of mime types:%s", got)
|
||||
}
|
||||
}
|
34
vendor/github.com/emicklei/go-restful/options_filter_test.go
generated
vendored
34
vendor/github.com/emicklei/go-restful/options_filter_test.go
generated
vendored
@ -1,34 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test -v -test.run TestOptionsFilter ...restful
|
||||
func TestOptionsFilter(t *testing.T) {
|
||||
tearDown()
|
||||
ws := new(WebService)
|
||||
ws.Route(ws.GET("/candy/{kind}").To(dummy))
|
||||
ws.Route(ws.DELETE("/candy/{kind}").To(dummy))
|
||||
ws.Route(ws.POST("/candies").To(dummy))
|
||||
Add(ws)
|
||||
Filter(OPTIONSFilter())
|
||||
|
||||
httpRequest, _ := http.NewRequest("OPTIONS", "http://here.io/candy/gum", nil)
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
actual := httpWriter.Header().Get(HEADER_Allow)
|
||||
if "GET,DELETE" != actual {
|
||||
t.Fatal("expected: GET,DELETE but got:" + actual)
|
||||
}
|
||||
|
||||
httpRequest, _ = http.NewRequest("OPTIONS", "http://here.io/candies", nil)
|
||||
httpWriter = httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
actual = httpWriter.Header().Get(HEADER_Allow)
|
||||
if "POST" != actual {
|
||||
t.Fatal("expected: POST but got:" + actual)
|
||||
}
|
||||
}
|
37
vendor/github.com/emicklei/go-restful/path_expression_test.go
generated
vendored
37
vendor/github.com/emicklei/go-restful/path_expression_test.go
generated
vendored
@ -1,37 +0,0 @@
|
||||
package restful
|
||||
|
||||
import "testing"
|
||||
|
||||
var tempregexs = []struct {
|
||||
template, regex string
|
||||
literalCount, varCount int
|
||||
}{
|
||||
{"", "^(/.*)?$", 0, 0},
|
||||
{"/a/{b}/c/", "^/a/([^/]+?)/c(/.*)?$", 2, 1},
|
||||
{"/{a}/{b}/{c-d-e}/", "^/([^/]+?)/([^/]+?)/([^/]+?)(/.*)?$", 0, 3},
|
||||
{"/{p}/abcde", "^/([^/]+?)/abcde(/.*)?$", 5, 1},
|
||||
{"/a/{b:*}", "^/a/(.*)(/.*)?$", 1, 1},
|
||||
{"/a/{b:[a-z]+}", "^/a/([a-z]+)(/.*)?$", 1, 1},
|
||||
}
|
||||
|
||||
func TestTemplateToRegularExpression(t *testing.T) {
|
||||
ok := true
|
||||
for i, fixture := range tempregexs {
|
||||
actual, lCount, vCount, _ := templateToRegularExpression(fixture.template)
|
||||
if actual != fixture.regex {
|
||||
t.Logf("regex mismatch, expected:%v , actual:%v, line:%v\n", fixture.regex, actual, i) // 11 = where the data starts
|
||||
ok = false
|
||||
}
|
||||
if lCount != fixture.literalCount {
|
||||
t.Logf("literal count mismatch, expected:%v , actual:%v, line:%v\n", fixture.literalCount, lCount, i)
|
||||
ok = false
|
||||
}
|
||||
if vCount != fixture.varCount {
|
||||
t.Logf("variable count mismatch, expected:%v , actual:%v, line:%v\n", fixture.varCount, vCount, i)
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Fatal("one or more expression did not match")
|
||||
}
|
||||
}
|
141
vendor/github.com/emicklei/go-restful/request_test.go
generated
vendored
141
vendor/github.com/emicklei/go-restful/request_test.go
generated
vendored
@ -1,141 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestQueryParameter(t *testing.T) {
|
||||
hreq := http.Request{Method: "GET"}
|
||||
hreq.URL, _ = url.Parse("http://www.google.com/search?q=foo&q=bar")
|
||||
rreq := Request{Request: &hreq}
|
||||
if rreq.QueryParameter("q") != "foo" {
|
||||
t.Errorf("q!=foo %#v", rreq)
|
||||
}
|
||||
}
|
||||
|
||||
type Anything map[string]interface{}
|
||||
|
||||
type Number struct {
|
||||
ValueFloat float64
|
||||
ValueInt int64
|
||||
}
|
||||
|
||||
type Sample struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
func TestReadEntityJson(t *testing.T) {
|
||||
bodyReader := strings.NewReader(`{"Value" : "42"}`)
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/json")
|
||||
request := &Request{Request: httpRequest}
|
||||
sam := new(Sample)
|
||||
request.ReadEntity(sam)
|
||||
if sam.Value != "42" {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadEntityJsonCharset(t *testing.T) {
|
||||
bodyReader := strings.NewReader(`{"Value" : "42"}`)
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/json; charset=UTF-8")
|
||||
request := NewRequest(httpRequest)
|
||||
sam := new(Sample)
|
||||
request.ReadEntity(sam)
|
||||
if sam.Value != "42" {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadEntityJsonNumber(t *testing.T) {
|
||||
bodyReader := strings.NewReader(`{"Value" : 4899710515899924123}`)
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/json")
|
||||
request := &Request{Request: httpRequest}
|
||||
any := make(Anything)
|
||||
request.ReadEntity(&any)
|
||||
number, ok := any["Value"].(json.Number)
|
||||
if !ok {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
vint, err := number.Int64()
|
||||
if err != nil {
|
||||
t.Fatal("convert failed")
|
||||
}
|
||||
if vint != 4899710515899924123 {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
vfloat, err := number.Float64()
|
||||
if err != nil {
|
||||
t.Fatal("convert failed")
|
||||
}
|
||||
// match the default behaviour
|
||||
vstring := strconv.FormatFloat(vfloat, 'e', 15, 64)
|
||||
if vstring != "4.899710515899924e+18" {
|
||||
t.Fatal("convert float64 failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadEntityJsonLong(t *testing.T) {
|
||||
bodyReader := strings.NewReader(`{"ValueFloat" : 4899710515899924123, "ValueInt": 4899710515899924123}`)
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/json")
|
||||
request := &Request{Request: httpRequest}
|
||||
number := new(Number)
|
||||
request.ReadEntity(&number)
|
||||
if number.ValueInt != 4899710515899924123 {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
// match the default behaviour
|
||||
vstring := strconv.FormatFloat(number.ValueFloat, 'e', 15, 64)
|
||||
if vstring != "4.899710515899924e+18" {
|
||||
t.Fatal("convert float64 failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBodyParameter(t *testing.T) {
|
||||
bodyReader := strings.NewReader(`value1=42&value2=43`)
|
||||
httpRequest, _ := http.NewRequest("POST", "/test?value1=44", bodyReader) // POST and PUT body parameters take precedence over URL query string
|
||||
httpRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||
request := NewRequest(httpRequest)
|
||||
v1, err := request.BodyParameter("value1")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
v2, err := request.BodyParameter("value2")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if v1 != "42" || v2 != "43" {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadEntityUnkown(t *testing.T) {
|
||||
bodyReader := strings.NewReader("?")
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/rubbish")
|
||||
request := NewRequest(httpRequest)
|
||||
sam := new(Sample)
|
||||
err := request.ReadEntity(sam)
|
||||
if err == nil {
|
||||
t.Fatal("read should be in error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetAttribute(t *testing.T) {
|
||||
bodyReader := strings.NewReader("?")
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
request := NewRequest(httpRequest)
|
||||
request.SetAttribute("go", "there")
|
||||
there := request.Attribute("go")
|
||||
if there != "there" {
|
||||
t.Fatalf("missing request attribute:%v", there)
|
||||
}
|
||||
}
|
213
vendor/github.com/emicklei/go-restful/response_test.go
generated
vendored
213
vendor/github.com/emicklei/go-restful/response_test.go
generated
vendored
@ -1,213 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWriteHeader(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, true, nil}
|
||||
resp.WriteHeader(123)
|
||||
if resp.StatusCode() != 123 {
|
||||
t.Errorf("Unexpected status code:%d", resp.StatusCode())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoWriteHeader(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, true, nil}
|
||||
if resp.StatusCode() != http.StatusOK {
|
||||
t.Errorf("Unexpected status code:%d", resp.StatusCode())
|
||||
}
|
||||
}
|
||||
|
||||
type food struct {
|
||||
Kind string
|
||||
}
|
||||
|
||||
// go test -v -test.run TestMeasureContentLengthXml ...restful
|
||||
func TestMeasureContentLengthXml(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, true, nil}
|
||||
resp.WriteAsXml(food{"apple"})
|
||||
if resp.ContentLength() != 76 {
|
||||
t.Errorf("Incorrect measured length:%d", resp.ContentLength())
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestMeasureContentLengthJson ...restful
|
||||
func TestMeasureContentLengthJson(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, true, nil}
|
||||
resp.WriteAsJson(food{"apple"})
|
||||
if resp.ContentLength() != 22 {
|
||||
t.Errorf("Incorrect measured length:%d", resp.ContentLength())
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestMeasureContentLengthJsonNotPretty ...restful
|
||||
func TestMeasureContentLengthJsonNotPretty(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, false, nil}
|
||||
resp.WriteAsJson(food{"apple"})
|
||||
if resp.ContentLength() != 17 { // 16+1 using the Encoder directly yields another /n
|
||||
t.Errorf("Incorrect measured length:%d", resp.ContentLength())
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestMeasureContentLengthWriteErrorString ...restful
|
||||
func TestMeasureContentLengthWriteErrorString(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, true, nil}
|
||||
resp.WriteErrorString(404, "Invalid")
|
||||
if resp.ContentLength() != len("Invalid") {
|
||||
t.Errorf("Incorrect measured length:%d", resp.ContentLength())
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestStatusIsPassedToResponse ...restful
|
||||
func TestStatusIsPassedToResponse(t *testing.T) {
|
||||
for _, each := range []struct {
|
||||
write, read int
|
||||
}{
|
||||
{write: 204, read: 204},
|
||||
{write: 304, read: 304},
|
||||
{write: 200, read: 200},
|
||||
{write: 400, read: 400},
|
||||
} {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "*/*", []string{"*/*"}, 0, 0, true, nil}
|
||||
resp.WriteHeader(each.write)
|
||||
if got, want := httpWriter.Code, each.read; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestStatusCreatedAndContentTypeJson_Issue54 ...restful
|
||||
func TestStatusCreatedAndContentTypeJson_Issue54(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "application/json", []string{"application/json"}, 0, 0, true, nil}
|
||||
resp.WriteHeader(201)
|
||||
resp.WriteAsJson(food{"Juicy"})
|
||||
if httpWriter.HeaderMap.Get("Content-Type") != "application/json" {
|
||||
t.Errorf("Expected content type json but got:%s", httpWriter.HeaderMap.Get("Content-Type"))
|
||||
}
|
||||
if httpWriter.Code != 201 {
|
||||
t.Errorf("Expected status 201 but got:%d", httpWriter.Code)
|
||||
}
|
||||
}
|
||||
|
||||
type errorOnWriteRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
}
|
||||
|
||||
func (e errorOnWriteRecorder) Write(bytes []byte) (int, error) {
|
||||
return 0, errors.New("fail")
|
||||
}
|
||||
|
||||
// go test -v -test.run TestLastWriteErrorCaught ...restful
|
||||
func TestLastWriteErrorCaught(t *testing.T) {
|
||||
httpWriter := errorOnWriteRecorder{httptest.NewRecorder()}
|
||||
resp := Response{httpWriter, "application/json", []string{"application/json"}, 0, 0, true, nil}
|
||||
err := resp.WriteAsJson(food{"Juicy"})
|
||||
if err.Error() != "fail" {
|
||||
t.Errorf("Unexpected error message:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestAcceptStarStar_Issue83 ...restful
|
||||
func TestAcceptStarStar_Issue83(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
// Accept Produces
|
||||
resp := Response{httpWriter, "application/bogus,*/*;q=0.8", []string{"application/json"}, 0, 0, true, nil}
|
||||
resp.WriteEntity(food{"Juicy"})
|
||||
ct := httpWriter.Header().Get("Content-Type")
|
||||
if "application/json" != ct {
|
||||
t.Errorf("Unexpected content type:%s", ct)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestAcceptSkipStarStar_Issue83 ...restful
|
||||
func TestAcceptSkipStarStar_Issue83(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
// Accept Produces
|
||||
resp := Response{httpWriter, " application/xml ,*/* ; q=0.8", []string{"application/json", "application/xml"}, 0, 0, true, nil}
|
||||
resp.WriteEntity(food{"Juicy"})
|
||||
ct := httpWriter.Header().Get("Content-Type")
|
||||
if "application/xml" != ct {
|
||||
t.Errorf("Unexpected content type:%s", ct)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestAcceptXmlBeforeStarStar_Issue83 ...restful
|
||||
func TestAcceptXmlBeforeStarStar_Issue83(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
// Accept Produces
|
||||
resp := Response{httpWriter, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", []string{"application/json"}, 0, 0, true, nil}
|
||||
resp.WriteEntity(food{"Juicy"})
|
||||
ct := httpWriter.Header().Get("Content-Type")
|
||||
if "application/json" != ct {
|
||||
t.Errorf("Unexpected content type:%s", ct)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestWriteHeaderNoContent_Issue124 ...restful
|
||||
func TestWriteHeaderNoContent_Issue124(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "text/plain", []string{"text/plain"}, 0, 0, true, nil}
|
||||
resp.WriteHeader(http.StatusNoContent)
|
||||
if httpWriter.Code != http.StatusNoContent {
|
||||
t.Errorf("got %d want %d", httpWriter.Code, http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestStatusCreatedAndContentTypeJson_Issue163 ...restful
|
||||
func TestStatusCreatedAndContentTypeJson_Issue163(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "application/json", []string{"application/json"}, 0, 0, true, nil}
|
||||
resp.WriteHeader(http.StatusNotModified)
|
||||
if httpWriter.Code != http.StatusNotModified {
|
||||
t.Errorf("Got %d want %d", httpWriter.Code, http.StatusNotModified)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteHeaderAndEntity_Issue235(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "application/json", []string{"application/json"}, 0, 0, true, nil}
|
||||
var pong = struct {
|
||||
Foo string `json:"foo"`
|
||||
}{Foo: "123"}
|
||||
resp.WriteHeaderAndEntity(404, pong)
|
||||
if httpWriter.Code != http.StatusNotFound {
|
||||
t.Errorf("got %d want %d", httpWriter.Code, http.StatusNoContent)
|
||||
}
|
||||
if got, want := httpWriter.Header().Get("Content-Type"), "application/json"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
if !strings.HasPrefix(httpWriter.Body.String(), "{") {
|
||||
t.Errorf("expected pong struct in json:%s", httpWriter.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteEntityNoAcceptMatchWithProduces(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "application/bogus", []string{"application/json"}, 0, 0, true, nil}
|
||||
resp.WriteEntity("done")
|
||||
if httpWriter.Code != http.StatusOK {
|
||||
t.Errorf("got %d want %d", httpWriter.Code, http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteEntityNoAcceptMatchNoProduces(t *testing.T) {
|
||||
httpWriter := httptest.NewRecorder()
|
||||
resp := Response{httpWriter, "application/bogus", []string{}, 0, 0, true, nil}
|
||||
resp.WriteEntity("done")
|
||||
if httpWriter.Code != http.StatusNotAcceptable {
|
||||
t.Errorf("got %d want %d", httpWriter.Code, http.StatusNotAcceptable)
|
||||
}
|
||||
}
|
76
vendor/github.com/emicklei/go-restful/route_builder_test.go
generated
vendored
76
vendor/github.com/emicklei/go-restful/route_builder_test.go
generated
vendored
@ -1,76 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestRouteBuilder_PathParameter(t *testing.T) {
|
||||
p := &Parameter{&ParameterData{Name: "name", Description: "desc"}}
|
||||
p.AllowMultiple(true)
|
||||
p.DataType("int")
|
||||
p.Required(true)
|
||||
values := map[string]string{"a": "b"}
|
||||
p.AllowableValues(values)
|
||||
p.bePath()
|
||||
|
||||
b := new(RouteBuilder)
|
||||
b.function = dummy
|
||||
b.Param(p)
|
||||
r := b.Build()
|
||||
if !r.ParameterDocs[0].Data().AllowMultiple {
|
||||
t.Error("AllowMultiple invalid")
|
||||
}
|
||||
if r.ParameterDocs[0].Data().DataType != "int" {
|
||||
t.Error("dataType invalid")
|
||||
}
|
||||
if !r.ParameterDocs[0].Data().Required {
|
||||
t.Error("required invalid")
|
||||
}
|
||||
if r.ParameterDocs[0].Data().Kind != PathParameterKind {
|
||||
t.Error("kind invalid")
|
||||
}
|
||||
if r.ParameterDocs[0].Data().AllowableValues["a"] != "b" {
|
||||
t.Error("allowableValues invalid")
|
||||
}
|
||||
if b.ParameterNamed("name") == nil {
|
||||
t.Error("access to parameter failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteBuilder(t *testing.T) {
|
||||
json := "application/json"
|
||||
b := new(RouteBuilder)
|
||||
b.To(dummy)
|
||||
b.Path("/routes").Method("HEAD").Consumes(json).Produces(json).Metadata("test", "test-value").DefaultReturns("default", time.Now())
|
||||
r := b.Build()
|
||||
if r.Path != "/routes" {
|
||||
t.Error("path invalid")
|
||||
}
|
||||
if r.Produces[0] != json {
|
||||
t.Error("produces invalid")
|
||||
}
|
||||
if r.Consumes[0] != json {
|
||||
t.Error("consumes invalid")
|
||||
}
|
||||
if r.Operation != "dummy" {
|
||||
t.Error("Operation not set")
|
||||
}
|
||||
if r.Metadata["test"] != "test-value" {
|
||||
t.Errorf("Metadata not set")
|
||||
}
|
||||
if _, ok := r.ResponseErrors[0]; !ok {
|
||||
t.Fatal("expected default response")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnonymousFuncNaming(t *testing.T) {
|
||||
f1 := func() {}
|
||||
f2 := func() {}
|
||||
if got, want := nameOfFunction(f1), "func1"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
if got, want := nameOfFunction(f2), "func2"; got != want {
|
||||
t.Errorf("got %v want %v", got, want)
|
||||
}
|
||||
}
|
127
vendor/github.com/emicklei/go-restful/route_test.go
generated
vendored
127
vendor/github.com/emicklei/go-restful/route_test.go
generated
vendored
@ -1,127 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// accept should match produces
|
||||
func TestMatchesAcceptPlainTextWhenProducePlainTextAsLast(t *testing.T) {
|
||||
r := Route{Produces: []string{"application/json", "text/plain"}}
|
||||
if !r.matchesAccept("text/plain") {
|
||||
t.Errorf("accept should match text/plain")
|
||||
}
|
||||
}
|
||||
|
||||
// accept should match produces
|
||||
func TestMatchesAcceptStar(t *testing.T) {
|
||||
r := Route{Produces: []string{"application/xml"}}
|
||||
if !r.matchesAccept("*/*") {
|
||||
t.Errorf("accept should match star")
|
||||
}
|
||||
}
|
||||
|
||||
// accept should match produces
|
||||
func TestMatchesAcceptIE(t *testing.T) {
|
||||
r := Route{Produces: []string{"application/xml"}}
|
||||
if !r.matchesAccept("text/html, application/xhtml+xml, */*") {
|
||||
t.Errorf("accept should match star")
|
||||
}
|
||||
}
|
||||
|
||||
// accept should match produces
|
||||
func TestMatchesAcceptXml(t *testing.T) {
|
||||
r := Route{Produces: []string{"application/xml"}}
|
||||
if r.matchesAccept("application/json") {
|
||||
t.Errorf("accept should not match json")
|
||||
}
|
||||
if !r.matchesAccept("application/xml") {
|
||||
t.Errorf("accept should match xml")
|
||||
}
|
||||
}
|
||||
|
||||
// accept should match produces
|
||||
func TestMatchesAcceptAny(t *testing.T) {
|
||||
r := Route{Produces: []string{"*/*"}}
|
||||
if !r.matchesAccept("application/json") {
|
||||
t.Errorf("accept should match json")
|
||||
}
|
||||
if !r.matchesAccept("application/xml") {
|
||||
t.Errorf("accept should match xml")
|
||||
}
|
||||
}
|
||||
|
||||
// content type should match consumes
|
||||
func TestMatchesContentTypeXml(t *testing.T) {
|
||||
r := Route{Consumes: []string{"application/xml"}}
|
||||
if r.matchesContentType("application/json") {
|
||||
t.Errorf("accept should not match json")
|
||||
}
|
||||
if !r.matchesContentType("application/xml") {
|
||||
t.Errorf("accept should match xml")
|
||||
}
|
||||
}
|
||||
|
||||
// content type should match consumes
|
||||
func TestMatchesContentTypeCharsetInformation(t *testing.T) {
|
||||
r := Route{Consumes: []string{"application/json"}}
|
||||
if !r.matchesContentType("application/json; charset=UTF-8") {
|
||||
t.Errorf("matchesContentType should ignore charset information")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesPath_OneParam(t *testing.T) {
|
||||
params := doExtractParams("/from/{source}", 2, "/from/here", t)
|
||||
if params["source"] != "here" {
|
||||
t.Errorf("parameter mismatch here")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesPath_Slash(t *testing.T) {
|
||||
params := doExtractParams("/", 0, "/", t)
|
||||
if len(params) != 0 {
|
||||
t.Errorf("expected empty parameters")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesPath_SlashNonVar(t *testing.T) {
|
||||
params := doExtractParams("/any", 1, "/any", t)
|
||||
if len(params) != 0 {
|
||||
t.Errorf("expected empty parameters")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesPath_TwoVars(t *testing.T) {
|
||||
params := doExtractParams("/from/{source}/to/{destination}", 4, "/from/AMS/to/NY", t)
|
||||
if params["source"] != "AMS" {
|
||||
t.Errorf("parameter mismatch AMS")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesPath_VarOnFront(t *testing.T) {
|
||||
params := doExtractParams("{what}/from/{source}/", 3, "who/from/SOS/", t)
|
||||
if params["source"] != "SOS" {
|
||||
t.Errorf("parameter mismatch SOS")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractParameters_EmptyValue(t *testing.T) {
|
||||
params := doExtractParams("/fixed/{var}", 2, "/fixed/", t)
|
||||
if params["var"] != "" {
|
||||
t.Errorf("parameter mismatch var")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenizePath(t *testing.T) {
|
||||
if len(tokenizePath("/")) != 0 {
|
||||
t.Errorf("not empty path tokens")
|
||||
}
|
||||
}
|
||||
|
||||
func doExtractParams(routePath string, size int, urlPath string, t *testing.T) map[string]string {
|
||||
r := Route{Path: routePath}
|
||||
r.postBuild()
|
||||
if len(r.pathParts) != size {
|
||||
t.Fatalf("len not %v %v, but %v", size, r.pathParts, len(r.pathParts))
|
||||
}
|
||||
return r.extractParameters(urlPath)
|
||||
}
|
18
vendor/github.com/emicklei/go-restful/tracer_test.go
generated
vendored
18
vendor/github.com/emicklei/go-restful/tracer_test.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
package restful
|
||||
|
||||
import "testing"
|
||||
|
||||
// Use like this:
|
||||
//
|
||||
// TraceLogger(testLogger{t})
|
||||
type testLogger struct {
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (l testLogger) Print(v ...interface{}) {
|
||||
l.t.Log(v...)
|
||||
}
|
||||
|
||||
func (l testLogger) Printf(format string, v ...interface{}) {
|
||||
l.t.Logf(format, v...)
|
||||
}
|
343
vendor/github.com/emicklei/go-restful/web_service_test.go
generated
vendored
343
vendor/github.com/emicklei/go-restful/web_service_test.go
generated
vendored
@ -1,343 +0,0 @@
|
||||
package restful
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
pathGetFriends = "/get/{userId}/friends"
|
||||
)
|
||||
|
||||
func TestParameter(t *testing.T) {
|
||||
p := &Parameter{&ParameterData{Name: "name", Description: "desc"}}
|
||||
p.AllowMultiple(true)
|
||||
p.DataType("int")
|
||||
p.Required(true)
|
||||
values := map[string]string{"a": "b"}
|
||||
p.AllowableValues(values)
|
||||
p.bePath()
|
||||
|
||||
ws := new(WebService)
|
||||
ws.Param(p)
|
||||
if ws.pathParameters[0].Data().Name != "name" {
|
||||
t.Error("path parameter (or name) invalid")
|
||||
}
|
||||
}
|
||||
func TestWebService_CanCreateParameterKinds(t *testing.T) {
|
||||
ws := new(WebService)
|
||||
if ws.BodyParameter("b", "b").Kind() != BodyParameterKind {
|
||||
t.Error("body parameter expected")
|
||||
}
|
||||
if ws.PathParameter("p", "p").Kind() != PathParameterKind {
|
||||
t.Error("path parameter expected")
|
||||
}
|
||||
if ws.QueryParameter("q", "q").Kind() != QueryParameterKind {
|
||||
t.Error("query parameter expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapturePanic(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newPanicingService())
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/fire", nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
// override the default here
|
||||
DefaultContainer.DoNotRecover(false)
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 500 != httpWriter.Code {
|
||||
t.Error("500 expected on fire")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapturePanicWithEncoded(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newPanicingService())
|
||||
DefaultContainer.EnableContentEncoding(true)
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/fire", nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpRequest.Header.Set("Accept-Encoding", "gzip")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 500 != httpWriter.Code {
|
||||
t.Error("500 expected on fire, got", httpWriter.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotFound(t *testing.T) {
|
||||
tearDown()
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/missing", nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 404 != httpWriter.Code {
|
||||
t.Error("404 expected on missing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodNotAllowed(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newGetOnlyService())
|
||||
httpRequest, _ := http.NewRequest("POST", "http://here.com/get", nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 405 != httpWriter.Code {
|
||||
t.Error("405 expected method not allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectedRoutePath_Issue100(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newSelectedRouteTestingService())
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/get/232452/friends", nil)
|
||||
httpRequest.Header.Set("Accept", "*/*")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if http.StatusOK != httpWriter.Code {
|
||||
t.Error(http.StatusOK, "expected,", httpWriter.Code, "received.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentType415_Issue170(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newGetOnlyJsonOnlyService())
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 200 != httpWriter.Code {
|
||||
t.Errorf("Expected 200, got %d", httpWriter.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoContentTypePOST(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newPostNoConsumesService())
|
||||
httpRequest, _ := http.NewRequest("POST", "http://here.com/post", nil)
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 204 != httpWriter.Code {
|
||||
t.Errorf("Expected 204, got %d", httpWriter.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentType415_POST_Issue170(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newPostOnlyJsonOnlyService())
|
||||
httpRequest, _ := http.NewRequest("POST", "http://here.com/post", nil)
|
||||
httpRequest.Header.Set("Content-Type", "application/json")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 200 != httpWriter.Code {
|
||||
t.Errorf("Expected 200, got %d", httpWriter.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestContentType406PlainJson ...restful
|
||||
func TestContentType406PlainJson(t *testing.T) {
|
||||
tearDown()
|
||||
TraceLogger(testLogger{t})
|
||||
Add(newGetPlainTextOrJsonService())
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
|
||||
httpRequest.Header.Set("Accept", "text/plain")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 200; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveRoute(t *testing.T) {
|
||||
tearDown()
|
||||
TraceLogger(testLogger{t})
|
||||
ws := newGetPlainTextOrJsonService()
|
||||
Add(ws)
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
|
||||
httpRequest.Header.Set("Accept", "text/plain")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 200; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
|
||||
// dynamic apis are disabled, should error and do nothing
|
||||
if err := ws.RemoveRoute("/get", "GET"); err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
|
||||
httpWriter = httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 200; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
|
||||
ws.SetDynamicRoutes(true)
|
||||
if err := ws.RemoveRoute("/get", "GET"); err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
httpWriter = httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 404; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
func TestRemoveLastRoute(t *testing.T) {
|
||||
tearDown()
|
||||
TraceLogger(testLogger{t})
|
||||
ws := newGetPlainTextOrJsonServiceMultiRoute()
|
||||
Add(ws)
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
|
||||
httpRequest.Header.Set("Accept", "text/plain")
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 200; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
|
||||
// dynamic apis are disabled, should error and do nothing
|
||||
if err := ws.RemoveRoute("/get", "GET"); err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
|
||||
httpWriter = httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 200; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
|
||||
ws.SetDynamicRoutes(true)
|
||||
if err := ws.RemoveRoute("/get", "GET"); err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
httpWriter = httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if got, want := httpWriter.Code, 404; got != want {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -test.run TestContentTypeOctet_Issue170 ...restful
|
||||
func TestContentTypeOctet_Issue170(t *testing.T) {
|
||||
tearDown()
|
||||
Add(newGetConsumingOctetStreamService())
|
||||
// with content-type
|
||||
httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
|
||||
httpRequest.Header.Set("Content-Type", MIME_OCTET)
|
||||
httpWriter := httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 200 != httpWriter.Code {
|
||||
t.Errorf("Expected 200, got %d", httpWriter.Code)
|
||||
}
|
||||
// without content-type
|
||||
httpRequest, _ = http.NewRequest("GET", "http://here.com/get", nil)
|
||||
httpWriter = httptest.NewRecorder()
|
||||
DefaultContainer.dispatch(httpWriter, httpRequest)
|
||||
if 200 != httpWriter.Code {
|
||||
t.Errorf("Expected 200, got %d", httpWriter.Code)
|
||||
}
|
||||
}
|
||||
|
||||
type exampleBody struct{}
|
||||
|
||||
func TestParameterDataTypeDefaults(t *testing.T) {
|
||||
tearDown()
|
||||
ws := new(WebService)
|
||||
route := ws.POST("/post").Reads(&exampleBody{})
|
||||
if route.parameters[0].data.DataType != "*restful.exampleBody" {
|
||||
t.Errorf("body parameter incorrect name: %#v", route.parameters[0].data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParameterDataTypeCustomization(t *testing.T) {
|
||||
tearDown()
|
||||
ws := new(WebService)
|
||||
ws.TypeNameHandler(func(sample interface{}) string {
|
||||
return "my.custom.type.name"
|
||||
})
|
||||
route := ws.POST("/post").Reads(&exampleBody{})
|
||||
if route.parameters[0].data.DataType != "my.custom.type.name" {
|
||||
t.Errorf("body parameter incorrect name: %#v", route.parameters[0].data)
|
||||
}
|
||||
}
|
||||
|
||||
func newPanicingService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Route(ws.GET("/fire").To(doPanic))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newGetOnlyService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Route(ws.GET("/get").To(doPanic))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newPostOnlyJsonOnlyService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Consumes("application/json")
|
||||
ws.Route(ws.POST("/post").To(doNothing))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newGetOnlyJsonOnlyService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Consumes("application/json")
|
||||
ws.Route(ws.GET("/get").To(doNothing))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newGetPlainTextOrJsonService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Produces("text/plain", "application/json")
|
||||
ws.Route(ws.GET("/get").To(doNothing))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newGetPlainTextOrJsonServiceMultiRoute() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Produces("text/plain", "application/json")
|
||||
ws.Route(ws.GET("/get").To(doNothing))
|
||||
ws.Route(ws.GET("/status").To(doNothing))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newGetConsumingOctetStreamService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Consumes("application/octet-stream")
|
||||
ws.Route(ws.GET("/get").To(doNothing))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newPostNoConsumesService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Route(ws.POST("/post").To(return204))
|
||||
return ws
|
||||
}
|
||||
|
||||
func newSelectedRouteTestingService() *WebService {
|
||||
ws := new(WebService).Path("")
|
||||
ws.Route(ws.GET(pathGetFriends).To(selectedRouteChecker))
|
||||
return ws
|
||||
}
|
||||
|
||||
func selectedRouteChecker(req *Request, resp *Response) {
|
||||
if req.SelectedRoutePath() != pathGetFriends {
|
||||
resp.InternalServerError()
|
||||
}
|
||||
}
|
||||
|
||||
func doPanic(req *Request, resp *Response) {
|
||||
println("lightning...")
|
||||
panic("fire")
|
||||
}
|
||||
|
||||
func doNothing(req *Request, resp *Response) {
|
||||
}
|
||||
|
||||
func return204(req *Request, resp *Response) {
|
||||
resp.WriteHeader(204)
|
||||
}
|
1
vendor/github.com/go-openapi/jsonpointer/.drone.sec
generated
vendored
Normal file
1
vendor/github.com/go-openapi/jsonpointer/.drone.sec
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.pDqezepze0YqRx4u6M8GFaWtnVR-utTWZic-GX-RvMATAoYpG4H2sc9tlnGNCxa44dbRY0vY10qfBU7Sno8vkp21fsK42ofGLfen_suum_0ilm0sFS0X-kAwk7TIq5L5lPPKiChPMUiGp5oJW-g5MqMFX1jNiI-4fP-vSM3B3-eyZtJD_O517TgfIRLnblCzqwIkyRmAfPNopi-Fe8Y31TmO2Vd0nFc1Aqro_VaJSACzEVxOHTNpjETcMjlYzwgMXLeiAfLV-5hM0f6DXgHMlLSuMkB_Ndnw25dkB7hreGk4x0tHQ3X9mUfTgLq1hIDoyeeKDIM83Tqw4LBRph20BQ.qd_pNuyi23B0PlWz.JtpO7kqOm0SWOGzWDalkWheHuNd-eDpVbqI9WPAEFDOIBvz7TbsYMBlIYVWEGWbat4mkx_ejxnMn1L1l996NJnyP7eY-QE82cfPJbjx94d0Ob70KZ4DCm_UxcY2t-OKFiPJqxW7MA5jKyDuGD16bdxpjLEoe_cMSEr8FNu-MVG6wcchPcyYyRkqTQSl4mb09KikkAzHjwjo-DcO0f8ps4Uzsoc0aqAAWdE-ocG0YqierLoemjusYMiLH-eLF6MvaLRvHSte-cLzPuYCeZURnBDgxu3i3UApgddnX7g1c7tdGGBGvgCl-tEEDW58Vxgdjksim2S7y3lfoJ8FFzSWeRH2y7Kq04hgew3b2J_RiDB9ejzIopzG8ZGjJa3EO1-i9ORTl12nXK1RdlLGqu604ENaeVOPCIHL-0C8e6_wHdUGHydLZImSxKYSrNvy8resP1D_9t4B-3q2mkS9mhnMONrXbPDVw5QY5mvXlWs0Db99ARwzsl-Qlu0A_tsZwMjWT2I1QMvWPyTRScmMm0FJSv9zStjzxWa_q2GL7Naz1fI4Dd6ZgNJWYYq-mHN5chEeBdIcwb_zMPHczMQXXNL5nmfRGM1aPffkToFWCDpIlI8IXec83ZC6_POxZegS6n9Drrvc.6Nz8EXxs1lWX3ASaCeNElA
|
117
vendor/github.com/go-openapi/jsonpointer/.github/CONTRIBUTING.md
generated
vendored
117
vendor/github.com/go-openapi/jsonpointer/.github/CONTRIBUTING.md
generated
vendored
@ -1,117 +0,0 @@
|
||||
## Contribution Guidelines
|
||||
|
||||
### Pull requests are always welcome
|
||||
|
||||
We are always thrilled to receive pull requests, and do our best to
|
||||
process them as fast as possible. Not sure if that typo is worth a pull
|
||||
request? Do it! We will appreciate it.
|
||||
|
||||
If your pull request is not accepted on the first try, don't be
|
||||
discouraged! If there's a problem with the implementation, hopefully you
|
||||
received feedback on what to improve.
|
||||
|
||||
We're trying very hard to keep go-swagger lean and focused. We don't want it
|
||||
to do everything for everybody. This means that we might decide against
|
||||
incorporating a new feature. However, there might be a way to implement
|
||||
that feature *on top of* go-swagger.
|
||||
|
||||
|
||||
### Conventions
|
||||
|
||||
Fork the repo and make changes on your fork in a feature branch:
|
||||
|
||||
- If it's a bugfix branch, name it XXX-something where XXX is the number of the
|
||||
issue
|
||||
- If it's a feature branch, create an enhancement issue to announce your
|
||||
intentions, and name it XXX-something where XXX is the number of the issue.
|
||||
|
||||
Submit unit tests for your changes. Go has a great test framework built in; use
|
||||
it! Take a look at existing tests for inspiration. Run the full test suite on
|
||||
your branch before submitting a pull request.
|
||||
|
||||
Update the documentation when creating or modifying features. Test
|
||||
your documentation changes for clarity, concision, and correctness, as
|
||||
well as a clean documentation build. See ``docs/README.md`` for more
|
||||
information on building the docs and how docs get released.
|
||||
|
||||
Write clean code. Universally formatted code promotes ease of writing, reading,
|
||||
and maintenance. Always run `gofmt -s -w file.go` on each changed file before
|
||||
committing your changes. Most editors have plugins that do this automatically.
|
||||
|
||||
Pull requests descriptions should be as clear as possible and include a
|
||||
reference to all the issues that they address.
|
||||
|
||||
Pull requests must not contain commits from other users or branches.
|
||||
|
||||
Commit messages must start with a capitalized and short summary (max. 50
|
||||
chars) written in the imperative, followed by an optional, more detailed
|
||||
explanatory text which is separated from the summary by an empty line.
|
||||
|
||||
Code review comments may be added to your pull request. Discuss, then make the
|
||||
suggested modifications and push additional commits to your feature branch. Be
|
||||
sure to post a comment after pushing. The new commits will show up in the pull
|
||||
request automatically, but the reviewers will not be notified unless you
|
||||
comment.
|
||||
|
||||
Before the pull request is merged, make sure that you squash your commits into
|
||||
logical units of work using `git rebase -i` and `git push -f`. After every
|
||||
commit the test suite should be passing. Include documentation changes in the
|
||||
same commit so that a revert would remove all traces of the feature or fix.
|
||||
|
||||
Commits that fix or close an issue should include a reference like `Closes #XXX`
|
||||
or `Fixes #XXX`, which will automatically close the issue when merged.
|
||||
|
||||
### Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the
|
||||
patch, which certifies that you wrote it or otherwise have the right to
|
||||
pass it on as an open-source patch. The rules are pretty simple: if you
|
||||
can certify the below (from
|
||||
[developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
then you just add a line to every git commit message:
|
||||
|
||||
Signed-off-by: Joe Smith <joe@gmail.com>
|
||||
|
||||
using your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
You can add the sign off when creating the git commit via `git commit -s`.
|
313
vendor/github.com/go-openapi/jsonpointer/pointer_test.go
generated
vendored
313
vendor/github.com/go-openapi/jsonpointer/pointer_test.go
generated
vendored
@ -1,313 +0,0 @@
|
||||
// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// author sigu-399
|
||||
// author-github https://github.com/sigu-399
|
||||
// author-mail sigu.399@gmail.com
|
||||
//
|
||||
// repository-name jsonpointer
|
||||
// repository-desc An implementation of JSON Pointer - Go language
|
||||
//
|
||||
// description Automated tests on package.
|
||||
//
|
||||
// created 03-03-2013
|
||||
|
||||
package jsonpointer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
TestDocumentNBItems = 11
|
||||
TestNodeObjNBItems = 4
|
||||
TestDocumentString = `{
|
||||
"foo": ["bar", "baz"],
|
||||
"obj": { "a":1, "b":2, "c":[3,4], "d":[ {"e":9}, {"f":[50,51]} ] },
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}`
|
||||
)
|
||||
|
||||
var testDocumentJSON interface{}
|
||||
|
||||
type testStructJSON struct {
|
||||
Foo []string `json:"foo"`
|
||||
Obj struct {
|
||||
A int `json:"a"`
|
||||
B int `json:"b"`
|
||||
C []int `json:"c"`
|
||||
D []struct {
|
||||
E int `json:"e"`
|
||||
F []int `json:"f"`
|
||||
} `json:"d"`
|
||||
} `json:"obj"`
|
||||
}
|
||||
|
||||
type aliasedMap map[string]interface{}
|
||||
|
||||
var testStructJSONDoc testStructJSON
|
||||
var testStructJSONPtr *testStructJSON
|
||||
|
||||
func init() {
|
||||
json.Unmarshal([]byte(TestDocumentString), &testDocumentJSON)
|
||||
json.Unmarshal([]byte(TestDocumentString), &testStructJSONDoc)
|
||||
testStructJSONPtr = &testStructJSONDoc
|
||||
}
|
||||
|
||||
func TestEscaping(t *testing.T) {
|
||||
|
||||
ins := []string{`/`, `/`, `/a~1b`, `/a~1b`, `/c%d`, `/e^f`, `/g|h`, `/i\j`, `/k"l`, `/ `, `/m~0n`}
|
||||
outs := []float64{0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
for i := range ins {
|
||||
|
||||
p, err := New(ins[i])
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %v", ins[i], err.Error())
|
||||
}
|
||||
|
||||
result, _, err := p.Get(testDocumentJSON)
|
||||
if err != nil {
|
||||
t.Errorf("Get(%v) error %v", ins[i], err.Error())
|
||||
}
|
||||
|
||||
if result != outs[i] {
|
||||
t.Errorf("Get(%v) = %v, expect %v", ins[i], result, outs[i])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestFullDocument(t *testing.T) {
|
||||
|
||||
in := ``
|
||||
|
||||
p, err := New(in)
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %v", in, err.Error())
|
||||
}
|
||||
|
||||
result, _, err := p.Get(testDocumentJSON)
|
||||
if err != nil {
|
||||
t.Errorf("Get(%v) error %v", in, err.Error())
|
||||
}
|
||||
|
||||
if len(result.(map[string]interface{})) != TestDocumentNBItems {
|
||||
t.Errorf("Get(%v) = %v, expect full document", in, result)
|
||||
}
|
||||
|
||||
result, _, err = p.get(testDocumentJSON, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Get(%v) error %v", in, err.Error())
|
||||
}
|
||||
|
||||
if len(result.(map[string]interface{})) != TestDocumentNBItems {
|
||||
t.Errorf("Get(%v) = %v, expect full document", in, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodedTokens(t *testing.T) {
|
||||
p, err := New("/obj/a~1b")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{"obj", "a/b"}, p.DecodedTokens())
|
||||
}
|
||||
|
||||
func TestIsEmpty(t *testing.T) {
|
||||
p, err := New("")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, p.IsEmpty())
|
||||
p, err = New("/obj")
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, p.IsEmpty())
|
||||
}
|
||||
|
||||
func TestGetSingle(t *testing.T) {
|
||||
in := `/obj`
|
||||
|
||||
_, err := New(in)
|
||||
assert.NoError(t, err)
|
||||
result, _, err := GetForToken(testDocumentJSON, "obj")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, result, TestNodeObjNBItems)
|
||||
|
||||
result, _, err = GetForToken(testStructJSONDoc, "Obj")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
|
||||
result, _, err = GetForToken(testStructJSONDoc, "Obj2")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
}
|
||||
|
||||
type pointableImpl struct {
|
||||
a string
|
||||
}
|
||||
|
||||
func (p pointableImpl) JSONLookup(token string) (interface{}, error) {
|
||||
if token == "some" {
|
||||
return p.a, nil
|
||||
}
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
func TestPointableInterface(t *testing.T) {
|
||||
p := &pointableImpl{"hello"}
|
||||
|
||||
result, _, err := GetForToken(p, "some")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, p.a, result)
|
||||
|
||||
result, _, err = GetForToken(p, "something")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
}
|
||||
|
||||
func TestGetNode(t *testing.T) {
|
||||
|
||||
in := `/obj`
|
||||
|
||||
p, err := New(in)
|
||||
assert.NoError(t, err)
|
||||
result, _, err := p.Get(testDocumentJSON)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, result, TestNodeObjNBItems)
|
||||
|
||||
result, _, err = p.Get(aliasedMap(testDocumentJSON.(map[string]interface{})))
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, result, TestNodeObjNBItems)
|
||||
|
||||
result, _, err = p.Get(testStructJSONDoc)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testStructJSONDoc.Obj, result)
|
||||
|
||||
result, _, err = p.Get(testStructJSONPtr)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testStructJSONDoc.Obj, result)
|
||||
}
|
||||
|
||||
func TestArray(t *testing.T) {
|
||||
|
||||
ins := []string{`/foo/0`, `/foo/0`, `/foo/1`}
|
||||
outs := []string{"bar", "bar", "baz"}
|
||||
|
||||
for i := range ins {
|
||||
p, err := New(ins[i])
|
||||
assert.NoError(t, err)
|
||||
|
||||
result, _, err := p.Get(testStructJSONDoc)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, outs[i], result)
|
||||
|
||||
result, _, err = p.Get(testStructJSONPtr)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, outs[i], result)
|
||||
|
||||
result, _, err = p.Get(testDocumentJSON)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, outs[i], result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOtherThings(t *testing.T) {
|
||||
_, err := New("abc")
|
||||
assert.Error(t, err)
|
||||
|
||||
p, err := New("")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "", p.String())
|
||||
|
||||
p, err = New("/obj/a")
|
||||
assert.Equal(t, "/obj/a", p.String())
|
||||
|
||||
s := Escape("m~n")
|
||||
assert.Equal(t, "m~0n", s)
|
||||
s = Escape("m/n")
|
||||
assert.Equal(t, "m~1n", s)
|
||||
|
||||
p, err = New("/foo/3")
|
||||
assert.NoError(t, err)
|
||||
_, _, err = p.Get(testDocumentJSON)
|
||||
assert.Error(t, err)
|
||||
|
||||
p, err = New("/foo/a")
|
||||
assert.NoError(t, err)
|
||||
_, _, err = p.Get(testDocumentJSON)
|
||||
assert.Error(t, err)
|
||||
|
||||
p, err = New("/notthere")
|
||||
assert.NoError(t, err)
|
||||
_, _, err = p.Get(testDocumentJSON)
|
||||
assert.Error(t, err)
|
||||
|
||||
p, err = New("/invalid")
|
||||
assert.NoError(t, err)
|
||||
_, _, err = p.Get(1234)
|
||||
assert.Error(t, err)
|
||||
|
||||
p, err = New("/foo/1")
|
||||
assert.NoError(t, err)
|
||||
expected := "hello"
|
||||
bbb := testDocumentJSON.(map[string]interface{})["foo"]
|
||||
bbb.([]interface{})[1] = "hello"
|
||||
|
||||
v, _, err := p.Get(testDocumentJSON)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, v)
|
||||
|
||||
esc := Escape("a/")
|
||||
assert.Equal(t, "a~1", esc)
|
||||
unesc := Unescape(esc)
|
||||
assert.Equal(t, "a/", unesc)
|
||||
|
||||
unesc = Unescape("~01")
|
||||
assert.Equal(t, "~1", unesc)
|
||||
assert.Equal(t, "~0~1", Escape("~/"))
|
||||
assert.Equal(t, "~/", Unescape("~0~1"))
|
||||
}
|
||||
|
||||
func TestObject(t *testing.T) {
|
||||
|
||||
ins := []string{`/obj/a`, `/obj/b`, `/obj/c/0`, `/obj/c/1`, `/obj/c/1`, `/obj/d/1/f/0`}
|
||||
outs := []float64{1, 2, 3, 4, 4, 50}
|
||||
|
||||
for i := range ins {
|
||||
|
||||
p, err := New(ins[i])
|
||||
assert.NoError(t, err)
|
||||
|
||||
result, _, err := p.Get(testDocumentJSON)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, outs[i], result)
|
||||
|
||||
result, _, err = p.Get(testStructJSONDoc)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, outs[i], result)
|
||||
|
||||
result, _, err = p.Get(testStructJSONPtr)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, outs[i], result)
|
||||
}
|
||||
}
|
1
vendor/github.com/go-openapi/jsonreference/.drone.sec
generated
vendored
Normal file
1
vendor/github.com/go-openapi/jsonreference/.drone.sec
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Xe40Wx6g5Y-iN0JVMhKyFfubtOId3zAVE564szw_yYGzFNhc_cGZO9F3BtAcJ55CfHG9C_ozn9dpnUDl_zYZoy_6cPCq13Ekb95z8NAC3ekDtbAATsc9HZwRNwI7UfkhstdwxljEouGB01qoLcUn6lFutrou-Ho21COHeDb2caemnPSA-rEAnXkOiBFu0RQ1MIwMygzvHXIHHYNpNwAtXqmiggM10miSjqBM3JmRPxCi7VK6_Rxij5p6LlhmK1BDi8Y6oBh-9BX3--5GAJeWZ6Vof5TnP-Enioia18j8c8KFtfY4q0y6Ednjb-AarLZ12gj695ppkBNJUdTJQmwGwA.fVcz_RiLrUB5fgMS.rjWllDYC6m_NB-ket_LizNEy9mlJ27odBTZQcMKaUqqXZBtWUCmPrOoMXGq-_cc-c7chg7D-WMh9SPQ23pV0P-DY-jsDpbOqHG2STOMEfW9ZREoaOLJXQaWcuBldLjRyWFcq0HGj97LgE6szD1Zlou3bmdHS_Q-U9Up9YQ_8_YnDcESD_cj1w5FZom7HjchKJFeGjQjfDQpoCKCQNMJaavUqy9jHQEeQ_uVocSrETg3GpewDcUF2tuv8uGq7ZZWu7Vl8zmnY1MFTynaGBWzTCSRmCkAXjcsaUheDP_NT5D7k-xUS6LwtqEUiXAXV07SNFraorFj5lnBQZRDlZMYcA3NWR6zHiOxekR9LBYPofst6w1rIqUchj_5m1tDpVTBMPir1eAaFcnJtPgo4ch17OF-kmcmQGLhJI3U7n8wv4sTrmP1dewtRRKrvlJe5r3_6eDiK4xZ8K0rnK1D4g6zuQqU1gA8KaU7pmZkKpFx3Bew4v-6DH32YwQBvAI7Lbb8afou9WsCNB_iswz5XGimP4bifiJRwpWBEz9VGhZFdiw-hZpYWgbxzVb5gtqfTDLIvpbLDmFz1vge16uUQHHVFpo1pSozyr7A60X8qsh9pmmO3RcJ-ZGZBWqiRC-Kl5ejz7WQ.LFoK4Ibi11B2lWQ5WcPSag
|
117
vendor/github.com/go-openapi/jsonreference/.github/CONTRIBUTING.md
generated
vendored
117
vendor/github.com/go-openapi/jsonreference/.github/CONTRIBUTING.md
generated
vendored
@ -1,117 +0,0 @@
|
||||
## Contribution Guidelines
|
||||
|
||||
### Pull requests are always welcome
|
||||
|
||||
We are always thrilled to receive pull requests, and do our best to
|
||||
process them as fast as possible. Not sure if that typo is worth a pull
|
||||
request? Do it! We will appreciate it.
|
||||
|
||||
If your pull request is not accepted on the first try, don't be
|
||||
discouraged! If there's a problem with the implementation, hopefully you
|
||||
received feedback on what to improve.
|
||||
|
||||
We're trying very hard to keep go-swagger lean and focused. We don't want it
|
||||
to do everything for everybody. This means that we might decide against
|
||||
incorporating a new feature. However, there might be a way to implement
|
||||
that feature *on top of* go-swagger.
|
||||
|
||||
|
||||
### Conventions
|
||||
|
||||
Fork the repo and make changes on your fork in a feature branch:
|
||||
|
||||
- If it's a bugfix branch, name it XXX-something where XXX is the number of the
|
||||
issue
|
||||
- If it's a feature branch, create an enhancement issue to announce your
|
||||
intentions, and name it XXX-something where XXX is the number of the issue.
|
||||
|
||||
Submit unit tests for your changes. Go has a great test framework built in; use
|
||||
it! Take a look at existing tests for inspiration. Run the full test suite on
|
||||
your branch before submitting a pull request.
|
||||
|
||||
Update the documentation when creating or modifying features. Test
|
||||
your documentation changes for clarity, concision, and correctness, as
|
||||
well as a clean documentation build. See ``docs/README.md`` for more
|
||||
information on building the docs and how docs get released.
|
||||
|
||||
Write clean code. Universally formatted code promotes ease of writing, reading,
|
||||
and maintenance. Always run `gofmt -s -w file.go` on each changed file before
|
||||
committing your changes. Most editors have plugins that do this automatically.
|
||||
|
||||
Pull requests descriptions should be as clear as possible and include a
|
||||
reference to all the issues that they address.
|
||||
|
||||
Pull requests must not contain commits from other users or branches.
|
||||
|
||||
Commit messages must start with a capitalized and short summary (max. 50
|
||||
chars) written in the imperative, followed by an optional, more detailed
|
||||
explanatory text which is separated from the summary by an empty line.
|
||||
|
||||
Code review comments may be added to your pull request. Discuss, then make the
|
||||
suggested modifications and push additional commits to your feature branch. Be
|
||||
sure to post a comment after pushing. The new commits will show up in the pull
|
||||
request automatically, but the reviewers will not be notified unless you
|
||||
comment.
|
||||
|
||||
Before the pull request is merged, make sure that you squash your commits into
|
||||
logical units of work using `git rebase -i` and `git push -f`. After every
|
||||
commit the test suite should be passing. Include documentation changes in the
|
||||
same commit so that a revert would remove all traces of the feature or fix.
|
||||
|
||||
Commits that fix or close an issue should include a reference like `Closes #XXX`
|
||||
or `Fixes #XXX`, which will automatically close the issue when merged.
|
||||
|
||||
### Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the
|
||||
patch, which certifies that you wrote it or otherwise have the right to
|
||||
pass it on as an open-source patch. The rules are pretty simple: if you
|
||||
can certify the below (from
|
||||
[developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
then you just add a line to every git commit message:
|
||||
|
||||
Signed-off-by: Joe Smith <joe@gmail.com>
|
||||
|
||||
using your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
You can add the sign off when creating the git commit via `git commit -s`.
|
420
vendor/github.com/go-openapi/jsonreference/reference_test.go
generated
vendored
420
vendor/github.com/go-openapi/jsonreference/reference_test.go
generated
vendored
@ -1,420 +0,0 @@
|
||||
// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// author sigu-399
|
||||
// author-github https://github.com/sigu-399
|
||||
// author-mail sigu.399@gmail.com
|
||||
//
|
||||
// repository-name jsonreference
|
||||
// repository-desc An implementation of JSON Reference - Go language
|
||||
//
|
||||
// description Automated tests on package.
|
||||
//
|
||||
// created 03-03-2013
|
||||
|
||||
package jsonreference
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsRoot(t *testing.T) {
|
||||
in := "#"
|
||||
r1, err := New(in)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, r1.IsRoot())
|
||||
|
||||
in = "#/ok"
|
||||
r1 = MustCreateRef(in)
|
||||
assert.False(t, r1.IsRoot())
|
||||
|
||||
assert.Panics(t, assert.PanicTestFunc(func() {
|
||||
MustCreateRef("%2")
|
||||
}))
|
||||
}
|
||||
|
||||
func TestFull(t *testing.T) {
|
||||
|
||||
in := "http://host/path/a/b/c#/f/a/b"
|
||||
|
||||
r1, err := New(in)
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %s", in, err.Error())
|
||||
}
|
||||
|
||||
if in != r1.String() {
|
||||
t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in)
|
||||
}
|
||||
|
||||
if r1.HasFragmentOnly != false {
|
||||
t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFullURL != true {
|
||||
t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, true)
|
||||
}
|
||||
|
||||
if r1.HasURLPathOnly != false {
|
||||
t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFileScheme != false {
|
||||
t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false)
|
||||
}
|
||||
|
||||
if r1.GetPointer().String() != "/f/a/b" {
|
||||
t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "/f/a/b")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFullURL(t *testing.T) {
|
||||
|
||||
in := "http://host/path/a/b/c"
|
||||
|
||||
r1, err := New(in)
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %s", in, err.Error())
|
||||
}
|
||||
|
||||
if in != r1.String() {
|
||||
t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in)
|
||||
}
|
||||
|
||||
if r1.HasFragmentOnly != false {
|
||||
t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFullURL != true {
|
||||
t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, true)
|
||||
}
|
||||
|
||||
if r1.HasURLPathOnly != false {
|
||||
t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFileScheme != false {
|
||||
t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false)
|
||||
}
|
||||
|
||||
if r1.GetPointer().String() != "" {
|
||||
t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFragmentOnly(t *testing.T) {
|
||||
|
||||
in := "#/fragment/only"
|
||||
|
||||
r1, err := New(in)
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %s", in, err.Error())
|
||||
}
|
||||
|
||||
if in != r1.String() {
|
||||
t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in)
|
||||
}
|
||||
|
||||
if r1.HasFragmentOnly != true {
|
||||
t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, true)
|
||||
}
|
||||
|
||||
if r1.HasFullURL != false {
|
||||
t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, false)
|
||||
}
|
||||
|
||||
if r1.HasURLPathOnly != false {
|
||||
t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFileScheme != false {
|
||||
t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false)
|
||||
}
|
||||
|
||||
if r1.GetPointer().String() != "/fragment/only" {
|
||||
t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "/fragment/only")
|
||||
}
|
||||
|
||||
p, _ := jsonpointer.New(r1.referenceURL.Fragment)
|
||||
r2 := Ref{referencePointer: p, HasFragmentOnly: true}
|
||||
assert.Equal(t, r2.String(), in)
|
||||
|
||||
r3 := Ref{referencePointer: p, HasFragmentOnly: false}
|
||||
assert.Equal(t, r3.String(), in[1:])
|
||||
}
|
||||
|
||||
func TestURLPathOnly(t *testing.T) {
|
||||
|
||||
in := "/documents/document.json"
|
||||
|
||||
r1, err := New(in)
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %s", in, err.Error())
|
||||
}
|
||||
|
||||
if in != r1.String() {
|
||||
t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in)
|
||||
}
|
||||
|
||||
if r1.HasFragmentOnly != false {
|
||||
t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFullURL != false {
|
||||
t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, false)
|
||||
}
|
||||
|
||||
if r1.HasURLPathOnly != true {
|
||||
t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, true)
|
||||
}
|
||||
|
||||
if r1.HasFileScheme != false {
|
||||
t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false)
|
||||
}
|
||||
|
||||
if r1.GetPointer().String() != "" {
|
||||
t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "")
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLRelativePathOnly(t *testing.T) {
|
||||
|
||||
in := "document.json"
|
||||
|
||||
r1, err := New(in)
|
||||
if err != nil {
|
||||
t.Errorf("New(%v) error %s", in, err.Error())
|
||||
}
|
||||
|
||||
if in != r1.String() {
|
||||
t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in)
|
||||
}
|
||||
|
||||
if r1.HasFragmentOnly != false {
|
||||
t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFullURL != false {
|
||||
t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, false)
|
||||
}
|
||||
|
||||
if r1.HasURLPathOnly != true {
|
||||
t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, true)
|
||||
}
|
||||
|
||||
if r1.HasFileScheme != false {
|
||||
t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false)
|
||||
}
|
||||
|
||||
if r1.GetPointer().String() != "" {
|
||||
t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInheritsInValid(t *testing.T) {
|
||||
in1 := "http://www.test.com/doc.json"
|
||||
in2 := "#/a/b"
|
||||
|
||||
r1, _ := New(in1)
|
||||
r2 := Ref{}
|
||||
result, err := r1.Inherits(r2)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, result)
|
||||
|
||||
r1 = Ref{}
|
||||
r2, _ = New(in2)
|
||||
result, err = r1.Inherits(r2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, r2, *result)
|
||||
}
|
||||
|
||||
func TestInheritsValid(t *testing.T) {
|
||||
|
||||
in1 := "http://www.test.com/doc.json"
|
||||
in2 := "#/a/b"
|
||||
out := in1 + in2
|
||||
|
||||
r1, _ := New(in1)
|
||||
r2, _ := New(in2)
|
||||
|
||||
result, err := r1.Inherits(r2)
|
||||
if err != nil {
|
||||
t.Errorf("Inherits(%s,%s) error %s", r1.String(), r2.String(), err.Error())
|
||||
}
|
||||
|
||||
if result.String() != out {
|
||||
t.Errorf("Inherits(%s,%s) = %s, expect %s", r1.String(), r2.String(), result.String(), out)
|
||||
}
|
||||
|
||||
if result.GetPointer().String() != "/a/b" {
|
||||
t.Errorf("result(%v)::GetPointer() %v expect %v", result.String(), result.GetPointer().String(), "/a/b")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInheritsDifferentHost(t *testing.T) {
|
||||
|
||||
in1 := "http://www.test.com/doc.json"
|
||||
in2 := "http://www.test2.com/doc.json#bla"
|
||||
|
||||
r1, _ := New(in1)
|
||||
r2, _ := New(in2)
|
||||
|
||||
result, err := r1.Inherits(r2)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Inherits(%s,%s) should not fail. Error: %s", r1.String(), r2.String(), err.Error())
|
||||
}
|
||||
|
||||
if result.String() != in2 {
|
||||
t.Errorf("Inherits(%s,%s) should be %s but is %s", in1, in2, in2, result)
|
||||
}
|
||||
|
||||
if result.GetPointer().String() != "" {
|
||||
t.Errorf("result(%v)::GetPointer() %v expect %v", result.String(), result.GetPointer().String(), "")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileScheme(t *testing.T) {
|
||||
|
||||
in1 := "file:///Users/mac/1.json#a"
|
||||
in2 := "file:///Users/mac/2.json#b"
|
||||
|
||||
r1, _ := New(in1)
|
||||
r2, _ := New(in2)
|
||||
|
||||
if r1.HasFragmentOnly != false {
|
||||
t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in1, r1.HasFragmentOnly, false)
|
||||
}
|
||||
|
||||
if r1.HasFileScheme != true {
|
||||
t.Errorf("New(%v)::HasFileScheme %v expect %v", in1, r1.HasFileScheme, true)
|
||||
}
|
||||
|
||||
if r1.HasFullFilePath != true {
|
||||
t.Errorf("New(%v)::HasFullFilePath %v expect %v", in1, r1.HasFullFilePath, true)
|
||||
}
|
||||
|
||||
if r1.IsCanonical() != true {
|
||||
t.Errorf("New(%v)::IsCanonical %v expect %v", in1, r1.IsCanonical, true)
|
||||
}
|
||||
|
||||
result, err := r1.Inherits(r2)
|
||||
if err != nil {
|
||||
t.Errorf("Inherits(%s,%s) should not fail. Error: %s", r1.String(), r2.String(), err.Error())
|
||||
}
|
||||
if result.String() != in2 {
|
||||
t.Errorf("Inherits(%s,%s) should be %s but is %s", in1, in2, in2, result)
|
||||
}
|
||||
|
||||
if result.GetPointer().String() != "" {
|
||||
t.Errorf("result(%v)::GetPointer() %v expect %v", result.String(), result.GetPointer().String(), "")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReferenceResolution(t *testing.T) {
|
||||
|
||||
// 5.4. Reference Resolution Examples
|
||||
// http://tools.ietf.org/html/rfc3986#section-5.4
|
||||
|
||||
base := "http://a/b/c/d;p?q"
|
||||
baseRef, err := New(base)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("New(%s) failed error: %s", base, err.Error())
|
||||
}
|
||||
if baseRef.String() != base {
|
||||
t.Errorf("New(%s) %s expected %s", base, baseRef.String(), base)
|
||||
}
|
||||
|
||||
checks := []string{
|
||||
// 5.4.1. Normal Examples
|
||||
// http://tools.ietf.org/html/rfc3986#section-5.4.1
|
||||
|
||||
"g:h", "g:h",
|
||||
"g", "http://a/b/c/g",
|
||||
"./g", "http://a/b/c/g",
|
||||
"g/", "http://a/b/c/g/",
|
||||
"/g", "http://a/g",
|
||||
"//g", "http://g",
|
||||
"?y", "http://a/b/c/d;p?y",
|
||||
"g?y", "http://a/b/c/g?y",
|
||||
"#s", "http://a/b/c/d;p?q#s",
|
||||
"g#s", "http://a/b/c/g#s",
|
||||
"g?y#s", "http://a/b/c/g?y#s",
|
||||
";x", "http://a/b/c/;x",
|
||||
"g;x", "http://a/b/c/g;x",
|
||||
"g;x?y#s", "http://a/b/c/g;x?y#s",
|
||||
"", "http://a/b/c/d;p?q",
|
||||
".", "http://a/b/c/",
|
||||
"./", "http://a/b/c/",
|
||||
"..", "http://a/b/",
|
||||
"../", "http://a/b/",
|
||||
"../g", "http://a/b/g",
|
||||
"../..", "http://a/",
|
||||
"../../", "http://a/",
|
||||
"../../g", "http://a/g",
|
||||
|
||||
// 5.4.2. Abnormal Examples
|
||||
// http://tools.ietf.org/html/rfc3986#section-5.4.2
|
||||
|
||||
"../../../g", "http://a/g",
|
||||
"../../../../g", "http://a/g",
|
||||
|
||||
"/./g", "http://a/g",
|
||||
"/../g", "http://a/g",
|
||||
"g.", "http://a/b/c/g.",
|
||||
".g", "http://a/b/c/.g",
|
||||
"g..", "http://a/b/c/g..",
|
||||
"..g", "http://a/b/c/..g",
|
||||
|
||||
"./../g", "http://a/b/g",
|
||||
"./g/.", "http://a/b/c/g/",
|
||||
"g/./h", "http://a/b/c/g/h",
|
||||
"g/../h", "http://a/b/c/h",
|
||||
"g;x=1/./y", "http://a/b/c/g;x=1/y",
|
||||
"g;x=1/../y", "http://a/b/c/y",
|
||||
|
||||
"g?y/./x", "http://a/b/c/g?y/./x",
|
||||
"g?y/../x", "http://a/b/c/g?y/../x",
|
||||
"g#s/./x", "http://a/b/c/g#s/./x",
|
||||
"g#s/../x", "http://a/b/c/g#s/../x",
|
||||
|
||||
"http:g", "http:g", // for strict parsers
|
||||
//"http:g", "http://a/b/c/g", // for backward compatibility
|
||||
|
||||
}
|
||||
for i := 0; i < len(checks); i += 2 {
|
||||
child := checks[i]
|
||||
expected := checks[i+1]
|
||||
// fmt.Printf("%d: %v -> %v\n", i/2, child, expected)
|
||||
|
||||
childRef, e := New(child)
|
||||
if e != nil {
|
||||
t.Errorf("%d: New(%s) failed error: %s", i/2, child, e.Error())
|
||||
}
|
||||
|
||||
res, e := baseRef.Inherits(childRef)
|
||||
if res == nil {
|
||||
t.Errorf("%d: Inherits(%s, %s) nil not expected", i/2, base, child)
|
||||
}
|
||||
if e != nil {
|
||||
t.Errorf("%d: Inherits(%s) failed error: %s", i/2, child, e.Error())
|
||||
}
|
||||
if res.String() != expected {
|
||||
t.Errorf("%d: Inherits(%s, %s) %s expected %s", i/2, base, child, res.String(), expected)
|
||||
}
|
||||
}
|
||||
}
|
1
vendor/github.com/go-openapi/spec/.drone.sec
generated
vendored
Normal file
1
vendor/github.com/go-openapi/spec/.drone.sec
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Epk8dDFH8U1RPYIPDpajZO26L5zFJ1wnQNGWxVHHo5cXrWF148kENoZzh35FT9cAxxPS_4CeVVpf59EgvCc8bem1puuj0gBZptn-lYa7iXZdI-ESN2Te7nF5VbZfwbnI62nEikYGyxz-ozL_IFuMl-qWek4iLerF8Z_xh0MZOJ_w8Nog7qb2WQov72d997TJv5ZKjWcRYPbnsAy1q60-Cqxq3a6enhcSPXqpK46nYSXGKfHvognWBJ_pxwkEqIBPN6hE4EfNtJjMf2LFKEdYy02nbHz78d-2YZ8wIUSJ-IWIwn3GTzObdGqRed20Qf3JtWTsOespmexDrLSeo3HW6A.7XaHW-Y1jjRAWt_W.S1Adut62RLOYZc-lN02M0MGczEucch3zIr4J1UPBPnZooWzntiE5UaUz0UdhjHVszQE5hTfG-yocKD1rDQGER6qrLtnJVrCm9J3n4lHglM-xOz1eZln1XKrWcAgZnAKaKSzuAa5scPG4iTHW6RwbWi_PWm04tBJ1yazdjaVo3uvuhflwvU9if7uMPMtscrDesbBVvpG89xmeudiFjX-wjsV5oGBIjz6ukEBAMKzNDMqikNoG4SnGenpxUpjUjMkDXxiC3BC8oL2_myeIfFeEOF066DqEN3CLkqBVO25zdpWAF4Ou2jKv--mgGEb_E1aMgiSoAVBnybene0TKn2IJ8rtkyRdmWlLIRKZdDT3v775C1FPK6-tYzS7NVg9nnuvpta5PhzYNkqI1Ie74Sl0I-RFClhsdx9dLDhoFEKCx2etC4UDX9jhj2u0Y2MrL76dRGE9kEV1hL1fh6HMvS4ZAAWw3Qce4skCjcL-2YyIOHzKjgLGkZsR5cTUQwCJyacVkdHUOUKFdDGZaUzWkFyeZ1oyrlG2d52svaplpU5-vCOVbWkqUN9rOALGPTC51Ur0L7DFx29aDImhaxZqTe2t9mcdqY7VLcO3JgUiD3JKsEet7s2EDeN44MqITv9KBS8wqJW4.sRv4ov0wB0IxTHw90kJy-A
|
117
vendor/github.com/go-openapi/spec/.github/CONTRIBUTING.md
generated
vendored
117
vendor/github.com/go-openapi/spec/.github/CONTRIBUTING.md
generated
vendored
@ -1,117 +0,0 @@
|
||||
## Contribution Guidelines
|
||||
|
||||
### Pull requests are always welcome
|
||||
|
||||
We are always thrilled to receive pull requests, and do our best to
|
||||
process them as fast as possible. Not sure if that typo is worth a pull
|
||||
request? Do it! We will appreciate it.
|
||||
|
||||
If your pull request is not accepted on the first try, don't be
|
||||
discouraged! If there's a problem with the implementation, hopefully you
|
||||
received feedback on what to improve.
|
||||
|
||||
We're trying very hard to keep go-swagger lean and focused. We don't want it
|
||||
to do everything for everybody. This means that we might decide against
|
||||
incorporating a new feature. However, there might be a way to implement
|
||||
that feature *on top of* go-swagger.
|
||||
|
||||
|
||||
### Conventions
|
||||
|
||||
Fork the repo and make changes on your fork in a feature branch:
|
||||
|
||||
- If it's a bugfix branch, name it XXX-something where XXX is the number of the
|
||||
issue
|
||||
- If it's a feature branch, create an enhancement issue to announce your
|
||||
intentions, and name it XXX-something where XXX is the number of the issue.
|
||||
|
||||
Submit unit tests for your changes. Go has a great test framework built in; use
|
||||
it! Take a look at existing tests for inspiration. Run the full test suite on
|
||||
your branch before submitting a pull request.
|
||||
|
||||
Update the documentation when creating or modifying features. Test
|
||||
your documentation changes for clarity, concision, and correctness, as
|
||||
well as a clean documentation build. See ``docs/README.md`` for more
|
||||
information on building the docs and how docs get released.
|
||||
|
||||
Write clean code. Universally formatted code promotes ease of writing, reading,
|
||||
and maintenance. Always run `gofmt -s -w file.go` on each changed file before
|
||||
committing your changes. Most editors have plugins that do this automatically.
|
||||
|
||||
Pull requests descriptions should be as clear as possible and include a
|
||||
reference to all the issues that they address.
|
||||
|
||||
Pull requests must not contain commits from other users or branches.
|
||||
|
||||
Commit messages must start with a capitalized and short summary (max. 50
|
||||
chars) written in the imperative, followed by an optional, more detailed
|
||||
explanatory text which is separated from the summary by an empty line.
|
||||
|
||||
Code review comments may be added to your pull request. Discuss, then make the
|
||||
suggested modifications and push additional commits to your feature branch. Be
|
||||
sure to post a comment after pushing. The new commits will show up in the pull
|
||||
request automatically, but the reviewers will not be notified unless you
|
||||
comment.
|
||||
|
||||
Before the pull request is merged, make sure that you squash your commits into
|
||||
logical units of work using `git rebase -i` and `git push -f`. After every
|
||||
commit the test suite should be passing. Include documentation changes in the
|
||||
same commit so that a revert would remove all traces of the feature or fix.
|
||||
|
||||
Commits that fix or close an issue should include a reference like `Closes #XXX`
|
||||
or `Fixes #XXX`, which will automatically close the issue when merged.
|
||||
|
||||
### Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the
|
||||
patch, which certifies that you wrote it or otherwise have the right to
|
||||
pass it on as an open-source patch. The rules are pretty simple: if you
|
||||
can certify the below (from
|
||||
[developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
then you just add a line to every git commit message:
|
||||
|
||||
Signed-off-by: Joe Smith <joe@gmail.com>
|
||||
|
||||
using your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
You can add the sign off when creating the git commit via `git commit -s`.
|
128
vendor/github.com/go-openapi/spec/auth_test.go
generated
vendored
128
vendor/github.com/go-openapi/spec/auth_test.go
generated
vendored
@ -1,128 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package spec
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSerialization_AuthSerialization(t *testing.T) {
|
||||
assertSerializeJSON(t, BasicAuth(), `{"type":"basic"}`)
|
||||
|
||||
assertSerializeJSON(t, APIKeyAuth("api-key", "header"), `{"type":"apiKey","name":"api-key","in":"header"}`)
|
||||
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
OAuth2Implicit("http://foo.com/authorization"),
|
||||
`{"type":"oauth2","flow":"implicit","authorizationUrl":"http://foo.com/authorization"}`)
|
||||
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
OAuth2Password("http://foo.com/token"),
|
||||
`{"type":"oauth2","flow":"password","tokenUrl":"http://foo.com/token"}`)
|
||||
|
||||
assertSerializeJSON(t,
|
||||
OAuth2Application("http://foo.com/token"),
|
||||
`{"type":"oauth2","flow":"application","tokenUrl":"http://foo.com/token"}`)
|
||||
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
OAuth2AccessToken("http://foo.com/authorization", "http://foo.com/token"),
|
||||
`{"type":"oauth2","flow":"accessCode","authorizationUrl":"http://foo.com/authorization","tokenUrl":"http://foo.com/token"}`)
|
||||
|
||||
auth1 := OAuth2Implicit("http://foo.com/authorization")
|
||||
auth1.AddScope("email", "read your email")
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
auth1,
|
||||
`{"type":"oauth2","flow":"implicit","authorizationUrl":"http://foo.com/authorization","scopes":{"email":"read your email"}}`)
|
||||
|
||||
auth2 := OAuth2Password("http://foo.com/authorization")
|
||||
auth2.AddScope("email", "read your email")
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
auth2,
|
||||
`{"type":"oauth2","flow":"password","tokenUrl":"http://foo.com/authorization","scopes":{"email":"read your email"}}`)
|
||||
|
||||
auth3 := OAuth2Application("http://foo.com/token")
|
||||
auth3.AddScope("email", "read your email")
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
auth3,
|
||||
`{"type":"oauth2","flow":"application","tokenUrl":"http://foo.com/token","scopes":{"email":"read your email"}}`)
|
||||
|
||||
auth4 := OAuth2AccessToken("http://foo.com/authorization", "http://foo.com/token")
|
||||
auth4.AddScope("email", "read your email")
|
||||
assertSerializeJSON(
|
||||
t,
|
||||
auth4,
|
||||
`{"type":"oauth2","flow":"accessCode","authorizationUrl":"http://foo.com/authorization","tokenUrl":"http://foo.com/token","scopes":{"email":"read your email"}}`)
|
||||
}
|
||||
|
||||
func TestSerialization_AuthDeserialization(t *testing.T) {
|
||||
|
||||
assertParsesJSON(t, `{"type":"basic"}`, BasicAuth())
|
||||
|
||||
assertParsesJSON(
|
||||
t,
|
||||
`{"in":"header","name":"api-key","type":"apiKey"}`,
|
||||
APIKeyAuth("api-key", "header"))
|
||||
|
||||
assertParsesJSON(
|
||||
t,
|
||||
`{"authorizationUrl":"http://foo.com/authorization","flow":"implicit","type":"oauth2"}`,
|
||||
OAuth2Implicit("http://foo.com/authorization"))
|
||||
|
||||
assertParsesJSON(
|
||||
t,
|
||||
`{"flow":"password","tokenUrl":"http://foo.com/token","type":"oauth2"}`,
|
||||
OAuth2Password("http://foo.com/token"))
|
||||
|
||||
assertParsesJSON(
|
||||
t,
|
||||
`{"flow":"application","tokenUrl":"http://foo.com/token","type":"oauth2"}`,
|
||||
OAuth2Application("http://foo.com/token"))
|
||||
|
||||
assertParsesJSON(
|
||||
t,
|
||||
`{"authorizationUrl":"http://foo.com/authorization","flow":"accessCode","tokenUrl":"http://foo.com/token","type":"oauth2"}`,
|
||||
OAuth2AccessToken("http://foo.com/authorization", "http://foo.com/token"))
|
||||
|
||||
auth1 := OAuth2Implicit("http://foo.com/authorization")
|
||||
auth1.AddScope("email", "read your email")
|
||||
assertParsesJSON(t,
|
||||
`{"authorizationUrl":"http://foo.com/authorization","flow":"implicit","scopes":{"email":"read your email"},"type":"oauth2"}`,
|
||||
auth1)
|
||||
|
||||
auth2 := OAuth2Password("http://foo.com/token")
|
||||
auth2.AddScope("email", "read your email")
|
||||
assertParsesJSON(t,
|
||||
`{"flow":"password","scopes":{"email":"read your email"},"tokenUrl":"http://foo.com/token","type":"oauth2"}`,
|
||||
auth2)
|
||||
|
||||
auth3 := OAuth2Application("http://foo.com/token")
|
||||
auth3.AddScope("email", "read your email")
|
||||
assertParsesJSON(t,
|
||||
`{"flow":"application","scopes":{"email":"read your email"},"tokenUrl":"http://foo.com/token","type":"oauth2"}`,
|
||||
auth3)
|
||||
|
||||
auth4 := OAuth2AccessToken("http://foo.com/authorization", "http://foo.com/token")
|
||||
auth4.AddScope("email", "read your email")
|
||||
assertParsesJSON(
|
||||
t,
|
||||
`{"authorizationUrl":"http://foo.com/authorization","flow":"accessCode","scopes":{"email":"read your email"},"tokenUrl":"http://foo.com/token","type":"oauth2"}`,
|
||||
auth4)
|
||||
|
||||
}
|
37
vendor/github.com/go-openapi/spec/contact_info_test.go
generated
vendored
37
vendor/github.com/go-openapi/spec/contact_info_test.go
generated
vendored
@ -1,37 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package spec
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var contactInfoJSON = `{"name":"wordnik api team","url":"http://developer.wordnik.com","email":"some@mailayada.dkdkd"}`
|
||||
var contactInfoYAML = `name: wordnik api team
|
||||
url: http://developer.wordnik.com
|
||||
email: some@mailayada.dkdkd
|
||||
`
|
||||
var contactInfo = ContactInfo{
|
||||
Name: "wordnik api team",
|
||||
URL: "http://developer.wordnik.com",
|
||||
Email: "some@mailayada.dkdkd",
|
||||
}
|
||||
|
||||
func TestIntegrationContactInfo(t *testing.T) {
|
||||
assertSerializeJSON(t, contactInfo, contactInfoJSON)
|
||||
assertSerializeYAML(t, contactInfo, contactInfoYAML)
|
||||
assertParsesJSON(t, contactInfoJSON, contactInfo)
|
||||
assertParsesYAML(t, contactInfoYAML, contactInfo)
|
||||
}
|
1098
vendor/github.com/go-openapi/spec/expander_test.go
generated
vendored
1098
vendor/github.com/go-openapi/spec/expander_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
29
vendor/github.com/go-openapi/spec/external_docs_test.go
generated
vendored
29
vendor/github.com/go-openapi/spec/external_docs_test.go
generated
vendored
@ -1,29 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package spec
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIntegrationExternalDocs(t *testing.T) {
|
||||
var extDocs = ExternalDocumentation{"the name", "the url"}
|
||||
const extDocsYAML = "description: the name\nurl: the url\n"
|
||||
const extDocsJSON = `{"description":"the name","url":"the url"}`
|
||||
assertSerializeJSON(t, extDocs, extDocsJSON)
|
||||
assertSerializeYAML(t, extDocs, extDocsYAML)
|
||||
assertParsesJSON(t, extDocsJSON, extDocs)
|
||||
assertParsesYAML(t, extDocsYAML, extDocs)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user