mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
vendor files
This commit is contained in:
1
vendor/github.com/emicklei/go-restful/examples/.goconvey
generated
vendored
Normal file
1
vendor/github.com/emicklei/go-restful/examples/.goconvey
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
ignore
|
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/.goconvey
generated
vendored
Normal file
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/.goconvey
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
ignore
|
20
vendor/github.com/emicklei/go-restful/examples/google_app_engine/app.yaml
generated
vendored
Normal file
20
vendor/github.com/emicklei/go-restful/examples/google_app_engine/app.yaml
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# 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
Normal file
1
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/.goconvey
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
ignore
|
18
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/app.yaml
generated
vendored
Normal file
18
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/app.yaml
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
application: <your_app_id>
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
|
||||
handlers:
|
||||
# Regex for all swagger files to make as static content.
|
||||
# You should create the folder static/swagger and copy
|
||||
# swagger-ui into it.
|
||||
#
|
||||
- url: /apidocs/(.*?)/(.*\.(js|html|css))
|
||||
static_files: static/swagger/\1/\2
|
||||
upload: static/swagger/(.*?)/(.*\.(js|html|css))
|
||||
|
||||
# Catch all.
|
||||
- url: /.*
|
||||
script: _go_app
|
||||
login: required
|
267
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/main.go
generated
vendored
Normal file
267
vendor/github.com/emicklei/go-restful/examples/google_app_engine/datastore/main.go
generated
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/datastore"
|
||||
"google.golang.org/appengine/user"
|
||||
)
|
||||
|
||||
// This example demonstrates a reasonably complete suite of RESTful operations backed
|
||||
// by DataStore on Google App Engine.
|
||||
|
||||
// Our simple example struct.
|
||||
type Profile struct {
|
||||
LastModified time.Time `json:"-" xml:"-"`
|
||||
Email string `json:"-" xml:"-"`
|
||||
FirstName string `json:"first_name" xml:"first-name"`
|
||||
NickName string `json:"nick_name" xml:"nick-name"`
|
||||
LastName string `json:"last_name" xml:"last-name"`
|
||||
}
|
||||
|
||||
type ProfileApi struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func gaeUrl() string {
|
||||
if appengine.IsDevAppServer() {
|
||||
return "http://localhost:8080"
|
||||
} else {
|
||||
// Include your URL on App Engine here.
|
||||
// I found no way to get AppID without appengine.Context and this always
|
||||
// based on a http.Request.
|
||||
return "http://federatedservices.appspot.com"
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
u := ProfileApi{Path: "/profiles"}
|
||||
u.register()
|
||||
|
||||
// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open <your_app_id>.appspot.com/apidocs and enter
|
||||
// Place the Swagger UI files into a folder called static/swagger if you wish to use Swagger
|
||||
// http://<your_app_id>.appspot.com/apidocs.json in the api input field.
|
||||
// For testing, you can use http://localhost:8080/apidocs.json
|
||||
config := swagger.Config{
|
||||
// You control what services are visible
|
||||
WebServices: restful.RegisteredWebServices(),
|
||||
WebServicesUrl: gaeUrl(),
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specify 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)
|
||||
}
|
12
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-appstats-integration.go
generated
vendored
Normal file
12
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-appstats-integration.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/mjibson/appstats"
|
||||
)
|
||||
|
||||
func stats(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
c := appstats.NewContext(req.Request)
|
||||
chain.ProcessFilter(req, resp)
|
||||
c.Stats.Status = resp.StatusCode()
|
||||
c.Save()
|
||||
}
|
162
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-user-service.go
generated
vendored
Normal file
162
vendor/github.com/emicklei/go-restful/examples/google_app_engine/restful-user-service.go
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/memcache"
|
||||
)
|
||||
|
||||
// This example is functionally the same as ../restful-user-service.go
|
||||
// but it`s supposed to run on Goole App Engine (GAE)
|
||||
//
|
||||
// contributed by ivanhawkes
|
||||
|
||||
type User struct {
|
||||
Id, Name string
|
||||
}
|
||||
|
||||
type UserService struct {
|
||||
// normally one would use DAO (data access object)
|
||||
// but in this example we simple use memcache.
|
||||
}
|
||||
|
||||
func (u UserService) Register() {
|
||||
ws := new(restful.WebService)
|
||||
|
||||
ws.
|
||||
Path("/users").
|
||||
Consumes(restful.MIME_XML, restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser).
|
||||
// docs
|
||||
Doc("get a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Writes(User{})) // on the response
|
||||
|
||||
ws.Route(ws.PATCH("").To(u.updateUser).
|
||||
// docs
|
||||
Doc("update a user").
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.createUser).
|
||||
// docs
|
||||
Doc("create a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser).
|
||||
// docs
|
||||
Doc("delete a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")))
|
||||
|
||||
restful.Add(ws)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
func (u UserService) findUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
id := request.PathParameter("user-id")
|
||||
usr := new(User)
|
||||
_, err := memcache.Gob.Get(c, id, &usr)
|
||||
if err != nil || len(usr.Id) == 0 {
|
||||
response.WriteErrorString(http.StatusNotFound, "User could not be found.")
|
||||
} else {
|
||||
response.WriteEntity(usr)
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH http://localhost:8080/users
|
||||
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User>
|
||||
//
|
||||
func (u *UserService) updateUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
usr := new(User)
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
item := &memcache.Item{
|
||||
Key: usr.Id,
|
||||
Object: &usr,
|
||||
}
|
||||
err = memcache.Gob.Set(c, item)
|
||||
if err != nil {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// PUT http://localhost:8080/users/1
|
||||
// <User><Id>1</Id><Name>Melissa</Name></User>
|
||||
//
|
||||
func (u *UserService) createUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
usr := User{Id: request.PathParameter("user-id")}
|
||||
err := request.ReadEntity(&usr)
|
||||
if err == nil {
|
||||
item := &memcache.Item{
|
||||
Key: usr.Id,
|
||||
Object: &usr,
|
||||
}
|
||||
err = memcache.Gob.Add(c, item)
|
||||
if err != nil {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
response.WriteHeader(http.StatusCreated)
|
||||
response.WriteEntity(usr)
|
||||
} else {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE http://localhost:8080/users/1
|
||||
//
|
||||
func (u *UserService) removeUser(request *restful.Request, response *restful.Response) {
|
||||
c := appengine.NewContext(request.Request)
|
||||
id := request.PathParameter("user-id")
|
||||
err := memcache.Delete(c, id)
|
||||
if err != nil {
|
||||
response.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
func getGaeURL() string {
|
||||
if appengine.IsDevAppServer() {
|
||||
return "http://localhost:8080"
|
||||
} else {
|
||||
/**
|
||||
* Include your URL on App Engine here.
|
||||
* I found no way to get AppID without appengine.Context and this always
|
||||
* based on a http.Request.
|
||||
*/
|
||||
return "http://<your_app_id>.appspot.com"
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
u := UserService{}
|
||||
u.Register()
|
||||
|
||||
// Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open <your_app_id>.appspot.com/apidocs and enter http://<your_app_id>.appspot.com/apidocs.json in the api input field.
|
||||
config := swagger.Config{
|
||||
WebServices: restful.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesUrl: getGaeURL(),
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specify 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
Normal file
7
vendor/github.com/emicklei/go-restful/examples/home.html
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<h1>{{.Text}}</h1>
|
||||
</body>
|
||||
</html>
|
34
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity.go
generated
vendored
Normal file
34
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
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
Normal file
160
vendor/github.com/emicklei/go-restful/examples/msgpack/msgpack_entity_test.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
package restPack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
restful "github.com/emicklei/go-restful"
|
||||
)
|
||||
|
||||
func TestMsgPack(t *testing.T) {
|
||||
|
||||
// register msg pack entity
|
||||
restful.RegisterEntityAccessor(MIME_MSGPACK, NewEntityAccessorMsgPack())
|
||||
type Tool struct {
|
||||
Name string
|
||||
Vendor string
|
||||
}
|
||||
|
||||
// Write
|
||||
httpWriter := httptest.NewRecorder()
|
||||
mpack := &Tool{Name: "json", Vendor: "apple"}
|
||||
resp := restful.NewResponse(httpWriter)
|
||||
resp.SetRequestAccepts("application/x-msgpack,*/*;q=0.8")
|
||||
|
||||
err := resp.WriteEntity(mpack)
|
||||
if err != nil {
|
||||
t.Errorf("err %v", err)
|
||||
}
|
||||
|
||||
// Read
|
||||
bodyReader := bytes.NewReader(httpWriter.Body.Bytes())
|
||||
httpRequest, _ := http.NewRequest("GET", "/test", bodyReader)
|
||||
httpRequest.Header.Set("Content-Type", MIME_MSGPACK)
|
||||
request := restful.NewRequest(httpRequest)
|
||||
readMsgPack := new(Tool)
|
||||
err = request.ReadEntity(&readMsgPack)
|
||||
if err != nil {
|
||||
t.Errorf("err %v", err)
|
||||
}
|
||||
if equal := reflect.DeepEqual(mpack, readMsgPack); !equal {
|
||||
t.Fatalf("should not be error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithWebService(t *testing.T) {
|
||||
serverURL := "http://127.0.0.1:8090"
|
||||
go func() {
|
||||
runRestfulMsgPackRouterServer()
|
||||
}()
|
||||
if err := waitForServerUp(serverURL); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
// send a post request
|
||||
userData := user{Id: "0001", Name: "Tony"}
|
||||
msgPackData, err := msgpack.Marshal(userData)
|
||||
req, err := http.NewRequest("POST", serverURL+"/test/msgpack", bytes.NewBuffer(msgPackData))
|
||||
req.Header.Set("Content-Type", MIME_MSGPACK)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error in sending req: %v", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("unexpected response: %v, expected: %v", resp.StatusCode, http.StatusOK)
|
||||
}
|
||||
|
||||
ur := &userResponse{}
|
||||
expectMsgPackDocument(t, resp, ur)
|
||||
if ur.Status != statusActive {
|
||||
t.Fatalf("should not error")
|
||||
}
|
||||
log.Printf("user response:%v", ur)
|
||||
}
|
||||
|
||||
func expectMsgPackDocument(t *testing.T, r *http.Response, doc interface{}) {
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
defer r.Body.Close()
|
||||
if err != nil {
|
||||
t.Errorf("ExpectMsgPackDocument: unable to read response body :%v", err)
|
||||
return
|
||||
}
|
||||
// put the body back for re-reads
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(data))
|
||||
|
||||
err = msgpack.Unmarshal(data, doc)
|
||||
if err != nil {
|
||||
t.Errorf("ExpectMsgPackDocument: unable to unmarshal MsgPack:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runRestfulMsgPackRouterServer() {
|
||||
|
||||
container := restful.NewContainer()
|
||||
register(container)
|
||||
|
||||
log.Print("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
Normal file
68
vendor/github.com/emicklei/go-restful/examples/restful-CORS-filter.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
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.Print("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
Normal file
54
vendor/github.com/emicklei/go-restful/examples/restful-NCSA-logging.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
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)
|
||||
log.Fatal(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
Normal file
35
vendor/github.com/emicklei/go-restful/examples/restful-basic-authentication.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"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)
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
func basicAuthenticate(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||
// usr/pwd = admin/admin
|
||||
u, p, ok := req.Request.BasicAuth()
|
||||
if !ok || u != "admin" || p != "admin" {
|
||||
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
Normal file
65
vendor/github.com/emicklei/go-restful/examples/restful-cpuprofiler-service.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
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
Normal file
107
vendor/github.com/emicklei/go-restful/examples/restful-curly-router.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
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.Print("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
Normal file
149
vendor/github.com/emicklei/go-restful/examples/restful-curly-router_test.go
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
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.Print("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
Normal file
61
vendor/github.com/emicklei/go-restful/examples/restful-encoding-filter.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
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.Print("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.Print("findUser")
|
||||
response.WriteEntity(User{"42", "Gandalf"})
|
||||
}
|
114
vendor/github.com/emicklei/go-restful/examples/restful-filters.go
generated
vendored
Normal file
114
vendor/github.com/emicklei/go-restful/examples/restful-filters.go
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
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://localhost: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.Print("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.Print("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.Print("findUser")
|
||||
response.WriteEntity(User{"42", "Gandalf"})
|
||||
}
|
63
vendor/github.com/emicklei/go-restful/examples/restful-form-handling.go
generated
vendored
Normal file
63
vendor/github.com/emicklei/go-restful/examples/restful-form-handling.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/gorilla/schema"
|
||||
"io"
|
||||
"log"
|
||||
"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)
|
||||
log.Fatal(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>`)
|
||||
}
|
23
vendor/github.com/emicklei/go-restful/examples/restful-hello-world.go
generated
vendored
Normal file
23
vendor/github.com/emicklei/go-restful/examples/restful-hello-world.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"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)
|
||||
log.Fatal(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
Normal file
35
vendor/github.com/emicklei/go-restful/examples/restful-html-template.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
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")
|
||||
log.Fatal(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
Normal file
43
vendor/github.com/emicklei/go-restful/examples/restful-multi-containers.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
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() {
|
||||
log.Fatal(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")
|
||||
}
|
25
vendor/github.com/emicklei/go-restful/examples/restful-no-cache-filter.go
generated
vendored
Normal file
25
vendor/github.com/emicklei/go-restful/examples/restful-no-cache-filter.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"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)
|
||||
log.Fatal(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
Normal file
51
vendor/github.com/emicklei/go-restful/examples/restful-options-filter.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
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.Print("start listening on localhost:8080")
|
||||
server := &http.Server{Addr: ":8080", Handler: wsContainer}
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}
|
27
vendor/github.com/emicklei/go-restful/examples/restful-path-tail.go
generated
vendored
Normal file
27
vendor/github.com/emicklei/go-restful/examples/restful-path-tail.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
. "github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This example shows how to create a Route matching 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")
|
||||
log.Fatal(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
Normal file
98
vendor/github.com/emicklei/go-restful/examples/restful-pre-post-filters.go
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
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
Normal file
63
vendor/github.com/emicklei/go-restful/examples/restful-resource-functions.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
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()
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
39
vendor/github.com/emicklei/go-restful/examples/restful-route_test.go
generated
vendored
Normal file
39
vendor/github.com/emicklei/go-restful/examples/restful-route_test.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
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
Normal file
29
vendor/github.com/emicklei/go-restful/examples/restful-routefunction_test.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
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
Normal file
47
vendor/github.com/emicklei/go-restful/examples/restful-serve-static.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
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")
|
||||
log.Fatal(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
Normal file
61
vendor/github.com/emicklei/go-restful/examples/restful-swagger.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/emicklei/go-restful-swagger12"
|
||||
)
|
||||
|
||||
type Book struct {
|
||||
Title string
|
||||
Author string
|
||||
}
|
||||
|
||||
func main() {
|
||||
ws := new(restful.WebService)
|
||||
ws.Path("/books")
|
||||
ws.Consumes(restful.MIME_JSON, restful.MIME_XML)
|
||||
ws.Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||
restful.Add(ws)
|
||||
|
||||
ws.Route(ws.GET("/{medium}").To(noop).
|
||||
Doc("Search all books").
|
||||
Param(ws.PathParameter("medium", "digital or paperback").DataType("string")).
|
||||
Param(ws.QueryParameter("language", "en,nl,de").DataType("string")).
|
||||
Param(ws.HeaderParameter("If-Modified-Since", "last known timestamp").DataType("datetime")).
|
||||
Do(returns200, returns500))
|
||||
|
||||
ws.Route(ws.PUT("/{medium}").To(noop).
|
||||
Doc("Add a new book").
|
||||
Param(ws.PathParameter("medium", "digital or paperback").DataType("string")).
|
||||
Reads(Book{}))
|
||||
|
||||
// You can install the Swagger Service which provides a nice Web UI on your REST API
|
||||
// You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
|
||||
// Open http://localhost:8080/apidocs and enter http://localhost:8080/apidocs.json in the api input field.
|
||||
config := swagger.Config{
|
||||
WebServices: restful.DefaultContainer.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesUrl: "http://localhost:8080",
|
||||
ApiPath: "/apidocs.json",
|
||||
|
||||
// Optionally, specify where the UI is located
|
||||
SwaggerPath: "/apidocs/",
|
||||
SwaggerFilePath: "/Users/emicklei/xProjects/swagger-ui/dist"}
|
||||
swagger.RegisterSwaggerService(config, restful.DefaultContainer)
|
||||
|
||||
log.Print("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)
|
||||
}
|
170
vendor/github.com/emicklei/go-restful/examples/restful-user-resource.go
generated
vendored
Normal file
170
vendor/github.com/emicklei/go-restful/examples/restful-user-resource.go
generated
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
restfulspec "github.com/emicklei/go-restful-openapi"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
// UserResource is the REST layer to the User domain
|
||||
type UserResource struct {
|
||||
// normally one would use DAO (data access object)
|
||||
users map[string]User
|
||||
}
|
||||
|
||||
// WebService creates a new service that can handle REST requests for User resources.
|
||||
func (u UserResource) WebService() *restful.WebService {
|
||||
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
|
||||
|
||||
tags := []string{"users"}
|
||||
|
||||
ws.Route(ws.GET("/").To(u.findAllUsers).
|
||||
// docs
|
||||
Doc("get all users").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Writes([]User{}).
|
||||
Returns(200, "OK", []User{}))
|
||||
|
||||
ws.Route(ws.GET("/{user-id}").To(u.findUser).
|
||||
// docs
|
||||
Doc("get a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("integer").DefaultValue("1")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Writes(User{}). // on the response
|
||||
Returns(200, "OK", User{}).
|
||||
Returns(404, "Not Found", nil))
|
||||
|
||||
ws.Route(ws.PUT("/{user-id}").To(u.updateUser).
|
||||
// docs
|
||||
Doc("update a user").
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.PUT("").To(u.createUser).
|
||||
// docs
|
||||
Doc("create a user").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Reads(User{})) // from the request
|
||||
|
||||
ws.Route(ws.DELETE("/{user-id}").To(u.removeUser).
|
||||
// docs
|
||||
Doc("delete a user").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")))
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users
|
||||
//
|
||||
func (u UserResource) findAllUsers(request *restful.Request, response *restful.Response) {
|
||||
list := []User{}
|
||||
for _, each := range u.users {
|
||||
list = append(list, each)
|
||||
}
|
||||
response.WriteEntity(list)
|
||||
}
|
||||
|
||||
// GET http://localhost:8080/users/1
|
||||
//
|
||||
func (u UserResource) 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 *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.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.WriteError(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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() {
|
||||
u := UserResource{map[string]User{}}
|
||||
restful.DefaultContainer.Add(u.WebService())
|
||||
|
||||
config := restfulspec.Config{
|
||||
WebServices: restful.RegisteredWebServices(), // you control what services are visible
|
||||
WebServicesURL: "http://localhost:8080",
|
||||
APIPath: "/apidocs.json",
|
||||
PostBuildSwaggerObjectHandler: enrichSwaggerObject}
|
||||
restful.DefaultContainer.Add(restfulspec.NewOpenAPIService(config))
|
||||
|
||||
// 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/?url=http://localhost:8080/apidocs.json
|
||||
http.Handle("/apidocs/", http.StripPrefix("/apidocs/", http.FileServer(http.Dir("/Users/emicklei/Projects/swagger-ui/dist"))))
|
||||
|
||||
log.Printf("start listening on localhost:8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
func enrichSwaggerObject(swo *spec.Swagger) {
|
||||
swo.Info = &spec.Info{
|
||||
InfoProps: spec.InfoProps{
|
||||
Title: "UserService",
|
||||
Description: "Resource for managing Users",
|
||||
Contact: &spec.ContactInfo{
|
||||
Name: "john",
|
||||
Email: "john@doe.rp",
|
||||
URL: "http://johndoe.org",
|
||||
},
|
||||
License: &spec.License{
|
||||
Name: "MIT",
|
||||
URL: "http://mit.org",
|
||||
},
|
||||
Version: "1.0.0",
|
||||
},
|
||||
}
|
||||
swo.Tags = []spec.Tag{spec.Tag{TagProps: spec.TagProps{
|
||||
Name: "users",
|
||||
Description: "Managing users"}}}
|
||||
}
|
||||
|
||||
// User is just a sample type
|
||||
type User struct {
|
||||
ID string `json:"id" description:"identifier of the user"`
|
||||
Name string `json:"name" description:"name of the user" default:"john"`
|
||||
Age int `json:"age" description:"age of the user" default:"21"`
|
||||
}
|
Reference in New Issue
Block a user