- removed serving of `index.html` since it was not used
- moved serving of UI template to the `SwaggerBase` - added `ui.initOAuth` UI call - added support for `Oauth2ClientID` and `Oauth2AppName` - added config helpers - minor refactoring - fixed tests since they were assuming that UI is always served from the root
This commit is contained in:
parent
362f7af176
commit
11a6cb395c
|
|
@ -64,7 +64,7 @@ import (
|
|||
func main() {
|
||||
r := gin.New()
|
||||
|
||||
swaggerBase := ginSwagger.SwaggerBase("docs/") // default `swagger/`
|
||||
swaggerBase := ginSwagger.SwaggerBase("/api/v2/docs/") // default `swagger/`
|
||||
specFileName := ginSwagger.SpecFileName("swagger.json") // default `doc.json`
|
||||
|
||||
apiGroup := r.Group("/api/v2")
|
||||
|
|
@ -75,7 +75,7 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
5. Run it, and browser to http://localhost:8080/swagger/index.html, you can see Swagger 2.0 Api documents.
|
||||
5. Run it, and browse to http://localhost:8080/api/v2/docs/, you can see Swagger 2.0 Api documents.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
3
go.mod
3
go.mod
|
|
@ -7,6 +7,7 @@ require (
|
|||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.8 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
|
||||
github.com/swaggo/swag v1.5.1
|
||||
github.com/ugorji/go v1.1.5-pre // indirect
|
||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a
|
||||
|
|
@ -15,3 +16,5 @@ require (
|
|||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -53,6 +53,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||
github.com/swaggo/swag v1.5.1 h1:2Agm8I4K5qb00620mHq0VJ05/KT4FtmALPIcQR9lEZM=
|
||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
|
|
@ -69,6 +71,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY=
|
||||
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a h1:+HHJiFUXVOIS9mr1ThqkQD1N8vpFCfCShqADBM12KTc=
|
||||
golang.org/x/net v0.0.0-20191206103017-1ddd1de85cb0 h1:LxY/gQN/MrcW24/46nLyiip1GhN/Yi14QPbeNskTvQA=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
|
|||
84
swagger.go
84
swagger.go
|
|
@ -2,6 +2,7 @@ package ginSwagger
|
|||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
|
@ -16,9 +17,11 @@ import (
|
|||
// Config stores ginSwagger configuration variables.
|
||||
type Config struct {
|
||||
//The url pointing to API definition (normally swagger.json or swagger.yaml). Default is `doc.json`.
|
||||
SpecFileName string
|
||||
SwaggerBase string
|
||||
DeepLinking bool
|
||||
SpecFileName string
|
||||
SwaggerBase string
|
||||
DeepLinking bool
|
||||
Oauth2ClientID string
|
||||
Oauth2AppName string
|
||||
}
|
||||
|
||||
// SwaggerBase sets the subpath of swagger router. Default is `swagger/`.
|
||||
|
|
@ -42,12 +45,28 @@ func DeepLinking(deepLinking bool) func(c *Config) {
|
|||
}
|
||||
}
|
||||
|
||||
// Oauth2ClientID sets OAuth2 client ID
|
||||
func Oauth2ClientID(clientID string) func(c *Config) {
|
||||
return func(c *Config) {
|
||||
c.Oauth2ClientID = clientID
|
||||
}
|
||||
}
|
||||
|
||||
// Oauth2AppName sets OAuth2 application name
|
||||
func Oauth2AppName(appName string) func(c *Config) {
|
||||
return func(c *Config) {
|
||||
c.Oauth2AppName = appName
|
||||
}
|
||||
}
|
||||
|
||||
// WrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
|
||||
func WrapHandler(h *webdav.Handler, confs ...func(c *Config)) gin.HandlerFunc {
|
||||
defaultConfig := &Config{
|
||||
SpecFileName: "doc.json",
|
||||
SwaggerBase: "swagger/",
|
||||
DeepLinking: true,
|
||||
SpecFileName: "doc.json",
|
||||
SwaggerBase: "/swagger/",
|
||||
DeepLinking: true,
|
||||
Oauth2ClientID: "your-client-id",
|
||||
Oauth2AppName: "your-app-name",
|
||||
}
|
||||
|
||||
for _, c := range confs {
|
||||
|
|
@ -69,25 +88,39 @@ func CustomWrapHandler(config *Config, h *webdav.Handler) gin.HandlerFunc {
|
|||
}
|
||||
|
||||
specRegexStr := strings.Replace(specFileName, ".", "\\.", -1)
|
||||
var rexp = regexp.MustCompile(`(.*)(index\.html|` + specRegexStr + `|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[\?|.]*`)
|
||||
var rexp = regexp.MustCompile(`(.*)(` + specRegexStr + `|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[\?|.]*`)
|
||||
|
||||
return func(c *gin.Context) {
|
||||
|
||||
type swaggerUIBundle struct {
|
||||
URL string
|
||||
Oauth2RedirectURL template.JS
|
||||
DeepLinking bool
|
||||
Oauth2RedirectURL template.JS
|
||||
Oauth2ClientID string
|
||||
Oauth2AppName string
|
||||
}
|
||||
|
||||
if c.Request.RequestURI == config.SwaggerBase {
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
index.Execute(c.Writer, &swaggerUIBundle{
|
||||
URL: filepath.Join(config.SwaggerBase, specFileName),
|
||||
DeepLinking: config.DeepLinking,
|
||||
Oauth2RedirectURL: template.JS("`${window.location.protocol}//${window.location.host}" + filepath.Join(config.SwaggerBase, "oauth2-redirect.html") + "`"),
|
||||
Oauth2ClientID: config.Oauth2ClientID,
|
||||
Oauth2AppName: config.Oauth2AppName,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var matches []string
|
||||
if matches = rexp.FindStringSubmatch(c.Request.RequestURI); len(matches) != 3 {
|
||||
c.Status(404)
|
||||
c.Status(http.StatusNotFound)
|
||||
c.Writer.Write([]byte("404 page not found"))
|
||||
return
|
||||
}
|
||||
|
||||
h.Prefix = matches[1]
|
||||
path := matches[2]
|
||||
prefix := matches[1]
|
||||
h.Prefix = prefix
|
||||
|
||||
if strings.HasSuffix(path, ".html") {
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
|
|
@ -99,39 +132,32 @@ func CustomWrapHandler(config *Config, h *webdav.Handler) gin.HandlerFunc {
|
|||
c.Header("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
switch path {
|
||||
case "index.html":
|
||||
index.Execute(c.Writer, &swaggerUIBundle{
|
||||
URL: filepath.Join(config.SwaggerBase, specFileName),
|
||||
Oauth2RedirectURL: template.JS("`${window.location.protocol}//${window.location.host}" + filepath.Join(config.SwaggerBase, "oauth2-redirect.html") + "`"),
|
||||
DeepLinking: config.DeepLinking,
|
||||
})
|
||||
case specFileName:
|
||||
if path == specFileName {
|
||||
doc, err := swag.ReadDoc()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.Writer.Write([]byte(doc))
|
||||
return
|
||||
default:
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// DisablingWrapHandler turn handler off
|
||||
// if specified environment variable passed
|
||||
func DisablingWrapHandler(h *webdav.Handler, envName string) gin.HandlerFunc {
|
||||
func DisablingWrapHandler(h *webdav.Handler, envName string, confs ...func(c *Config)) gin.HandlerFunc {
|
||||
eFlag := os.Getenv(envName)
|
||||
if eFlag != "" {
|
||||
return func(c *gin.Context) {
|
||||
// Simulate behavior when route unspecified and
|
||||
// return 404 HTTP code
|
||||
c.String(404, "")
|
||||
c.String(http.StatusNotFound, "")
|
||||
}
|
||||
}
|
||||
|
||||
return WrapHandler(h)
|
||||
return WrapHandler(h, confs...)
|
||||
}
|
||||
|
||||
// DisablingCustomWrapHandler turn handler off
|
||||
|
|
@ -142,7 +168,7 @@ func DisablingCustomWrapHandler(config *Config, h *webdav.Handler, envName strin
|
|||
return func(c *gin.Context) {
|
||||
// Simulate behavior when route unspecified and
|
||||
// return 404 HTTP code
|
||||
c.String(404, "")
|
||||
c.String(http.StatusNotFound, "")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +262,13 @@ window.onload = function() {
|
|||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
deepLinking: {{.DeepLinking}}
|
||||
deepLinking: {{.DeepLinking}},
|
||||
showExtensions: true
|
||||
})
|
||||
|
||||
ui.initOAuth({
|
||||
clientId: "localhost.vela.care",
|
||||
appName: "notifications"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ func TestWrapHandler(t *testing.T) {
|
|||
gin.SetMode(gin.TestMode)
|
||||
router := gin.New()
|
||||
|
||||
router.GET("/*any", WrapHandler(swaggerFiles.Handler))
|
||||
router.GET("/swagger/*any", WrapHandler(swaggerFiles.Handler))
|
||||
|
||||
w1 := performRequest("GET", "/index.html", router)
|
||||
w1 := performRequest("GET", "/swagger/", router)
|
||||
assert.Equal(t, 200, w1.Code)
|
||||
}
|
||||
|
||||
|
|
@ -28,9 +28,9 @@ func TestCustomWrapHandler(t *testing.T) {
|
|||
gin.SetMode(gin.TestMode)
|
||||
router := gin.New()
|
||||
|
||||
router.GET("/*any", CustomWrapHandler(&Config{}, swaggerFiles.Handler))
|
||||
router.GET("/*any", CustomWrapHandler(&Config{SwaggerBase: "/"}, swaggerFiles.Handler))
|
||||
|
||||
w1 := performRequest("GET", "/index.html", router)
|
||||
w1 := performRequest("GET", "/", router)
|
||||
assert.Equal(t, 200, w1.Code)
|
||||
|
||||
w2 := performRequest("GET", "/doc.json", router)
|
||||
|
|
@ -52,9 +52,9 @@ func TestDisablingWrapHandler(t *testing.T) {
|
|||
router := gin.New()
|
||||
disablingKey := "SWAGGER_DISABLE"
|
||||
|
||||
router.GET("/simple/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
|
||||
router.GET("/simple/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey, SwaggerBase("/simple/")))
|
||||
|
||||
w1 := performRequest("GET", "/simple/index.html", router)
|
||||
w1 := performRequest("GET", "/simple/", router)
|
||||
assert.Equal(t, 200, w1.Code)
|
||||
|
||||
w2 := performRequest("GET", "/simple/doc.json", router)
|
||||
|
|
@ -71,9 +71,9 @@ func TestDisablingWrapHandler(t *testing.T) {
|
|||
|
||||
os.Setenv(disablingKey, "true")
|
||||
|
||||
router.GET("/disabling/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
|
||||
router.GET("/disabling/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey, SwaggerBase("/disabling/")))
|
||||
|
||||
w11 := performRequest("GET", "/disabling/index.html", router)
|
||||
w11 := performRequest("GET", "/disabling/", router)
|
||||
assert.Equal(t, 404, w11.Code)
|
||||
|
||||
w22 := performRequest("GET", "/disabling/doc.json", router)
|
||||
|
|
@ -95,16 +95,16 @@ func TestDisablingCustomWrapHandler(t *testing.T) {
|
|||
router := gin.New()
|
||||
disablingKey := "SWAGGER_DISABLE2"
|
||||
|
||||
router.GET("/simple/*any", DisablingCustomWrapHandler(&Config{}, swaggerFiles.Handler, disablingKey))
|
||||
router.GET("/simple/*any", DisablingCustomWrapHandler(&Config{SwaggerBase: "/simple/"}, swaggerFiles.Handler, disablingKey))
|
||||
|
||||
w1 := performRequest("GET", "/simple/index.html", router)
|
||||
w1 := performRequest("GET", "/simple/", router)
|
||||
assert.Equal(t, 200, w1.Code)
|
||||
|
||||
os.Setenv(disablingKey, "true")
|
||||
|
||||
router.GET("/disabling/*any", DisablingCustomWrapHandler(&Config{}, swaggerFiles.Handler, disablingKey))
|
||||
router.GET("/disabling/*any", DisablingCustomWrapHandler(&Config{SwaggerBase: "/disabling/"}, swaggerFiles.Handler, disablingKey))
|
||||
|
||||
w11 := performRequest("GET", "/disabling/index.html", router)
|
||||
w11 := performRequest("GET", "/disabling/", router)
|
||||
assert.Equal(t, 404, w11.Code)
|
||||
}
|
||||
|
||||
|
|
@ -114,9 +114,9 @@ func TestWithGzipMiddleware(t *testing.T) {
|
|||
|
||||
router.Use(gzip.Gzip(gzip.BestSpeed))
|
||||
|
||||
router.GET("/*any", WrapHandler(swaggerFiles.Handler))
|
||||
router.GET("/*any", WrapHandler(swaggerFiles.Handler, SwaggerBase("/")))
|
||||
|
||||
w1 := performRequest("GET", "/index.html", router)
|
||||
w1 := performRequest("GET", "/", router)
|
||||
assert.Equal(t, 200, w1.Code)
|
||||
assert.Equal(t, w1.Header()["Content-Type"][0], "text/html; charset=utf-8")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue