vendor: remove dep and use vndr
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
16f44674a4
commit
148e72d81e
16131 changed files with 73815 additions and 4235138 deletions
70
vendor/github.com/emicklei/go-restful/.gitignore
generated
vendored
70
vendor/github.com/emicklei/go-restful/.gitignore
generated
vendored
|
@ -1,70 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
restful.html
|
||||
|
||||
*.out
|
||||
|
||||
tmp.prof
|
||||
|
||||
go-restful.test
|
||||
|
||||
examples/restful-basic-authentication
|
||||
|
||||
examples/restful-encoding-filter
|
||||
|
||||
examples/restful-filters
|
||||
|
||||
examples/restful-hello-world
|
||||
|
||||
examples/restful-resource-functions
|
||||
|
||||
examples/restful-serve-static
|
||||
|
||||
examples/restful-user-service
|
||||
|
||||
*.DS_Store
|
||||
examples/restful-user-resource
|
||||
|
||||
examples/restful-multi-containers
|
||||
|
||||
examples/restful-form-handling
|
||||
|
||||
examples/restful-CORS-filter
|
||||
|
||||
examples/restful-options-filter
|
||||
|
||||
examples/restful-curly-router
|
||||
|
||||
examples/restful-cpuprofiler-service
|
||||
|
||||
examples/restful-pre-post-filters
|
||||
|
||||
curly.prof
|
||||
|
||||
examples/restful-NCSA-logging
|
||||
|
||||
examples/restful-html-template
|
||||
|
||||
s.html
|
||||
restful-path-tail
|
171
vendor/github.com/emicklei/go-restful/CHANGES.md
generated
vendored
171
vendor/github.com/emicklei/go-restful/CHANGES.md
generated
vendored
|
@ -1,171 +0,0 @@
|
|||
Change history of go-restful
|
||||
=
|
||||
2016-11-26
|
||||
- Default change! now use CurlyRouter (was RouterJSR311)
|
||||
- Default change! no more caching of request content
|
||||
- Default change! do not recover from panics
|
||||
|
||||
2016-09-22
|
||||
- fix the DefaultRequestContentType feature
|
||||
|
||||
2016-02-14
|
||||
- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response
|
||||
- add constructors for custom entity accessors for xml and json
|
||||
|
||||
2015-09-27
|
||||
- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency
|
||||
|
||||
2015-09-25
|
||||
- fixed problem with changing Header after WriteHeader (issue 235)
|
||||
|
||||
2015-09-14
|
||||
- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write)
|
||||
- added support for custom EntityReaderWriters.
|
||||
|
||||
2015-08-06
|
||||
- add support for reading entities from compressed request content
|
||||
- use sync.Pool for compressors of http response and request body
|
||||
- add Description to Parameter for documentation in Swagger UI
|
||||
|
||||
2015-03-20
|
||||
- add configurable logging
|
||||
|
||||
2015-03-18
|
||||
- if not specified, the Operation is derived from the Route function
|
||||
|
||||
2015-03-17
|
||||
- expose Parameter creation functions
|
||||
- make trace logger an interface
|
||||
- fix OPTIONSFilter
|
||||
- customize rendering of ServiceError
|
||||
- JSR311 router now handles wildcards
|
||||
- add Notes to Route
|
||||
|
||||
2014-11-27
|
||||
- (api add) PrettyPrint per response. (as proposed in #167)
|
||||
|
||||
2014-11-12
|
||||
- (api add) ApiVersion(.) for documentation in Swagger UI
|
||||
|
||||
2014-11-10
|
||||
- (api change) struct fields tagged with "description" show up in Swagger UI
|
||||
|
||||
2014-10-31
|
||||
- (api change) ReturnsError -> Returns
|
||||
- (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder
|
||||
- fix swagger nested structs
|
||||
- sort Swagger response messages by code
|
||||
|
||||
2014-10-23
|
||||
- (api add) ReturnsError allows you to document Http codes in swagger
|
||||
- fixed problem with greedy CurlyRouter
|
||||
- (api add) Access-Control-Max-Age in CORS
|
||||
- add tracing functionality (injectable) for debugging purposes
|
||||
- support JSON parse 64bit int
|
||||
- fix empty parameters for swagger
|
||||
- WebServicesUrl is now optional for swagger
|
||||
- fixed duplicate AccessControlAllowOrigin in CORS
|
||||
- (api change) expose ServeMux in container
|
||||
- (api add) added AllowedDomains in CORS
|
||||
- (api add) ParameterNamed for detailed documentation
|
||||
|
||||
2014-04-16
|
||||
- (api add) expose constructor of Request for testing.
|
||||
|
||||
2014-06-27
|
||||
- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification).
|
||||
- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons).
|
||||
|
||||
2014-07-03
|
||||
- (api add) CORS can be configured with a list of allowed domains
|
||||
|
||||
2014-03-12
|
||||
- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter)
|
||||
|
||||
2014-02-26
|
||||
- (api add) Request now provides information about the matched Route, see method SelectedRoutePath
|
||||
|
||||
2014-02-17
|
||||
- (api change) renamed parameter constants (go-lint checks)
|
||||
|
||||
2014-01-10
|
||||
- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier
|
||||
|
||||
2014-01-07
|
||||
- (api change) Write* methods in Response now return the error or nil.
|
||||
- added example of serving HTML from a Go template.
|
||||
- fixed comparing Allowed headers in CORS (is now case-insensitive)
|
||||
|
||||
2013-11-13
|
||||
- (api add) Response knows how many bytes are written to the response body.
|
||||
|
||||
2013-10-29
|
||||
- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information.
|
||||
|
||||
2013-10-04
|
||||
- (api add) Response knows what HTTP status has been written
|
||||
- (api add) Request can have attributes (map of string->interface, also called request-scoped variables
|
||||
|
||||
2013-09-12
|
||||
- (api change) Router interface simplified
|
||||
- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths
|
||||
|
||||
2013-08-05
|
||||
- add OPTIONS support
|
||||
- add CORS support
|
||||
|
||||
2013-08-27
|
||||
- fixed some reported issues (see github)
|
||||
- (api change) deprecated use of WriteError; use WriteErrorString instead
|
||||
|
||||
2014-04-15
|
||||
- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString
|
||||
|
||||
2013-08-08
|
||||
- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer.
|
||||
- (api add) the swagger package has be extended to have a UI per container.
|
||||
- if panic is detected then a small stack trace is printed (thanks to runner-mei)
|
||||
- (api add) WriteErrorString to Response
|
||||
|
||||
Important API changes:
|
||||
|
||||
- (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead.
|
||||
- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead.
|
||||
|
||||
|
||||
2013-07-06
|
||||
|
||||
- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature.
|
||||
|
||||
2013-06-19
|
||||
|
||||
- (improve) DoNotRecover option, moved request body closer, improved ReadEntity
|
||||
|
||||
2013-06-03
|
||||
|
||||
- (api change) removed Dispatcher interface, hide PathExpression
|
||||
- changed receiver names of type functions to be more idiomatic Go
|
||||
|
||||
2013-06-02
|
||||
|
||||
- (optimize) Cache the RegExp compilation of Paths.
|
||||
|
||||
2013-05-22
|
||||
|
||||
- (api add) Added support for request/response filter functions
|
||||
|
||||
2013-05-18
|
||||
|
||||
|
||||
- (api add) Added feature to change the default Http Request Dispatch function (travis cline)
|
||||
- (api change) Moved Swagger Webservice to swagger package (see example restful-user)
|
||||
|
||||
[2012-11-14 .. 2013-05-18>
|
||||
|
||||
- See https://github.com/emicklei/go-restful/commits
|
||||
|
||||
2012-11-14
|
||||
|
||||
- Initial commit
|
||||
|
||||
|
1
vendor/github.com/emicklei/go-restful/Srcfile
generated
vendored
1
vendor/github.com/emicklei/go-restful/Srcfile
generated
vendored
|
@ -1 +0,0 @@
|
|||
{"SkipDirs": ["examples"]}
|
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)
|
||||
}
|
||||
}
|
||||
}
|
10
vendor/github.com/emicklei/go-restful/bench_test.sh
generated
vendored
10
vendor/github.com/emicklei/go-restful/bench_test.sh
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
#go test -run=none -file bench_test.go -test.bench . -cpuprofile=bench_test.out
|
||||
|
||||
go test -c
|
||||
./go-restful.test -test.run=none -test.cpuprofile=tmp.prof -test.bench=BenchmarkMany
|
||||
./go-restful.test -test.run=none -test.cpuprofile=curly.prof -test.bench=BenchmarkManyCurly
|
||||
|
||||
#go tool pprof go-restful.test tmp.prof
|
||||
go tool pprof go-restful.test curly.prof
|
||||
|
||||
|
127
vendor/github.com/emicklei/go-restful/compress_test.go
generated
vendored
127
vendor/github.com/emicklei/go-restful/compress_test.go
generated
vendored
|
@ -1,127 +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
|
||||
|
||||
doCacheReadEntityBytes = false
|
||||
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
|
||||
|
||||
doCacheReadEntityBytes = false
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
2
vendor/github.com/emicklei/go-restful/coverage.sh
generated
vendored
2
vendor/github.com/emicklei/go-restful/coverage.sh
generated
vendored
|
@ -1,2 +0,0 @@
|
|||
go test -coverprofile=coverage.out
|
||||
go tool cover -html=coverage.out
|
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
|
266
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/main.go
generated
vendored
266
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/main.go
generated
vendored
|
@ -1,266 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/datastore"
|
||||
"google.golang.org/appengine/user"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 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()
|
||||
}
|
161
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-user-service.go
generated
vendored
161
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-user-service.go
generated
vendored
|
@ -1,161 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/memcache"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// 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"
|
||||
|
||||
restful "github.com/emicklei/go-restful"
|
||||
"gopkg.in/vmihailenco/msgpack.v2"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
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.Error("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.Error("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/swagger"
|
||||
)
|
||||
|
||||
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/swagger"
|
||||
)
|
||||
|
||||
// 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())
|
||||
}
|
137
vendor/github.com/emicklei/go-restful/examples/restful-user-service.go
generated
vendored
137
vendor/github.com/emicklei/go-restful/examples/restful-user-service.go
generated
vendored
|
@ -1,137 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
)
|
||||
|
||||
// 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").
|
||||
Returns(200, "OK", []User{}))
|
||||
|
||||
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")).
|
||||
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) {
|
||||
response.WriteEntity(u.users)
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
10
vendor/github.com/emicklei/go-restful/install.sh
generated
vendored
10
vendor/github.com/emicklei/go-restful/install.sh
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
go test -test.v ...restful && \
|
||||
go test -test.v ...swagger && \
|
||||
go vet ...restful && \
|
||||
go fmt ...swagger && \
|
||||
go install ...swagger && \
|
||||
go fmt ...restful && \
|
||||
go install ...restful
|
||||
cd examples
|
||||
ls *.go | xargs -I {} go build -o /tmp/ignore {}
|
||||
cd ..
|
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")
|
||||
}
|
||||
}
|
204
vendor/github.com/emicklei/go-restful/request_test.go
generated
vendored
204
vendor/github.com/emicklei/go-restful/request_test.go
generated
vendored
|
@ -1,204 +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 TestReadEntityXmlCached(t *testing.T) {
|
||||
SetCacheReadEntity(true)
|
||||
bodyReader := strings.NewReader("<Sample><Value>42</Value></Sample>")
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/xml")
|
||||
request := &Request{Request: httpRequest}
|
||||
sam := new(Sample)
|
||||
request.ReadEntity(sam)
|
||||
if sam.Value != "42" {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
if request.bodyContent == nil {
|
||||
t.Fatal("no expected cached bytes found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadEntityXmlNonCached(t *testing.T) {
|
||||
SetCacheReadEntity(false)
|
||||
bodyReader := strings.NewReader("<Sample><Value>42</Value></Sample>")
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", "application/xml")
|
||||
request := &Request{Request: httpRequest}
|
||||
sam := new(Sample)
|
||||
request.ReadEntity(sam)
|
||||
if sam.Value != "42" {
|
||||
t.Fatal("read failed")
|
||||
}
|
||||
if request.bodyContent != nil {
|
||||
t.Fatal("unexpected cached bytes found")
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
SetCacheReadEntity(true)
|
||||
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 TestReadEntityJsonNumberNonCached(t *testing.T) {
|
||||
SetCacheReadEntity(false)
|
||||
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)
|
||||
}
|
||||
}
|
58
vendor/github.com/emicklei/go-restful/route_builder_test.go
generated
vendored
58
vendor/github.com/emicklei/go-restful/route_builder_test.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
package restful
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
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)
|
||||
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")
|
||||
}
|
||||
}
|
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)
|
||||
}
|
43
vendor/github.com/emicklei/go-restful/swagger/CHANGES.md
generated
vendored
43
vendor/github.com/emicklei/go-restful/swagger/CHANGES.md
generated
vendored
|
@ -1,43 +0,0 @@
|
|||
Change history of swagger
|
||||
=
|
||||
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)
|
1283
vendor/github.com/emicklei/go-restful/swagger/model_builder_test.go
generated
vendored
1283
vendor/github.com/emicklei/go-restful/swagger/model_builder_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
48
vendor/github.com/emicklei/go-restful/swagger/model_list_test.go
generated
vendored
48
vendor/github.com/emicklei/go-restful/swagger/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)
|
||||
}
|
||||
}
|
70
vendor/github.com/emicklei/go-restful/swagger/model_property_ext_test.go
generated
vendored
70
vendor/github.com/emicklei/go-restful/swagger/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)
|
||||
}
|
||||
}
|
47
vendor/github.com/emicklei/go-restful/swagger/model_property_list_test.go
generated
vendored
47
vendor/github.com/emicklei/go-restful/swagger/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)
|
||||
}
|
||||
}
|
29
vendor/github.com/emicklei/go-restful/swagger/ordered_route_map_test.go
generated
vendored
29
vendor/github.com/emicklei/go-restful/swagger/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/swagger/postbuild_model_test.go
generated
vendored
42
vendor/github.com/emicklei/go-restful/swagger/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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
}
|
284
vendor/github.com/emicklei/go-restful/swagger/swagger_test.go
generated
vendored
284
vendor/github.com/emicklei/go-restful/swagger/swagger_test.go
generated
vendored
|
@ -1,284 +0,0 @@
|
|||
package swagger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful/swagger/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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
// clear && go test -v -test.run TestComposeResponseMessageArray ...swagger
|
||||
func TestComposeResponseMessageArray(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 != "array[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)
|
||||
}
|
||||
}
|
5
vendor/github.com/emicklei/go-restful/swagger/test_package/struct.go
generated
vendored
5
vendor/github.com/emicklei/go-restful/swagger/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/swagger/utils_test.go
generated
vendored
86
vendor/github.com/emicklei/go-restful/swagger/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", err)
|
||||
}
|
||||
} 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()
|
||||
}
|
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...)
|
||||
}
|
320
vendor/github.com/emicklei/go-restful/web_service_test.go
generated
vendored
320
vendor/github.com/emicklei/go-restful/web_service_test.go
generated
vendored
|
@ -1,320 +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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue