mirror of
https://github.com/nabbar/golib.git
synced 2025-09-27 04:06:05 +08:00
Package Router:
- rework to apply standard hierarchy - move auth to dedicated sub package - move header to dedicated sub package Package Static: - fix bugs
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
package head
|
package head
|
||||||
|
|
||||||
import (
|
import (
|
||||||
librtr "github.com/nabbar/golib/router"
|
librtr "github.com/nabbar/golib/router/header"
|
||||||
spfcbr "github.com/spf13/cobra"
|
spfcbr "github.com/spf13/cobra"
|
||||||
spfvpr "github.com/spf13/viper"
|
spfvpr "github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
@@ -29,9 +29,10 @@ package head
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
librtr "github.com/nabbar/golib/router/header"
|
||||||
|
|
||||||
libcfg "github.com/nabbar/golib/config"
|
libcfg "github.com/nabbar/golib/config"
|
||||||
cfgtps "github.com/nabbar/golib/config/types"
|
cfgtps "github.com/nabbar/golib/config/types"
|
||||||
librtr "github.com/nabbar/golib/router"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ComponentHead interface {
|
type ComponentHead interface {
|
||||||
|
@@ -29,8 +29,9 @@ package head
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
librtr "github.com/nabbar/golib/router/header"
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
librtr "github.com/nabbar/golib/router"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type componentHead struct {
|
type componentHead struct {
|
||||||
|
@@ -31,7 +31,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
libmet "github.com/nabbar/golib/prometheus/metrics"
|
libmet "github.com/nabbar/golib/prometheus/metrics"
|
||||||
prmpol "github.com/nabbar/golib/prometheus/pool"
|
prmpol "github.com/nabbar/golib/prometheus/pool"
|
||||||
|
48
router/auth/interface.go
Normal file
48
router/auth/interface.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
|
rtrhdr "github.com/nabbar/golib/router/authheader"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Authorization interface {
|
||||||
|
Handler(c *ginsdk.Context)
|
||||||
|
Register(router ...ginsdk.HandlerFunc) ginsdk.HandlerFunc
|
||||||
|
Append(router ...ginsdk.HandlerFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAuthorization(log liblog.FuncLog, HeadAuthType string, authCheckFunc func(AuthHeader string) (rtrhdr.AuthCode, liberr.Error)) Authorization {
|
||||||
|
return &authorization{
|
||||||
|
log: log,
|
||||||
|
check: authCheckFunc,
|
||||||
|
authType: HeadAuthType,
|
||||||
|
router: make([]ginsdk.HandlerFunc, 0),
|
||||||
|
}
|
||||||
|
}
|
@@ -23,78 +23,28 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package router
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
liblog "github.com/nabbar/golib/logger"
|
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
liblog "github.com/nabbar/golib/logger"
|
||||||
loglvl "github.com/nabbar/golib/logger/level"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
|
librtr "github.com/nabbar/golib/router"
|
||||||
|
rtrhdr "github.com/nabbar/golib/router/authheader"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthCode uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
AUTH_CODE_SUCCESS = iota
|
|
||||||
AUTH_CODE_REQUIRE
|
|
||||||
AUTH_CODE_FORBIDDEN
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HEAD_AUTH_REQR = "WWW-Authenticate"
|
|
||||||
HEAD_AUTH_SEND = "Authorization"
|
|
||||||
HEAD_AUTH_REAL = "Basic realm=LDAP Authorization Required"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AuthRequire(c *ginsdk.Context, err error) {
|
|
||||||
if err != nil {
|
|
||||||
c.Errors = append(c.Errors, &ginsdk.Error{
|
|
||||||
Err: err,
|
|
||||||
Type: ginsdk.ErrorTypePrivate,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// Credentials doesn't match, we return 401 and abort handlers chain.
|
|
||||||
c.Header(HEAD_AUTH_REQR, HEAD_AUTH_REAL)
|
|
||||||
c.AbortWithStatus(http.StatusUnauthorized)
|
|
||||||
}
|
|
||||||
|
|
||||||
func AuthForbidden(c *ginsdk.Context, err error) {
|
|
||||||
if err != nil {
|
|
||||||
c.Errors = append(c.Errors, &ginsdk.Error{
|
|
||||||
Err: err,
|
|
||||||
Type: ginsdk.ErrorTypePrivate,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
|
||||||
|
|
||||||
type authorization struct {
|
type authorization struct {
|
||||||
log liblog.FuncLog
|
log liblog.FuncLog
|
||||||
check func(AuthHeader string) (AuthCode, liberr.Error)
|
check func(AuthHeader string) (rtrhdr.AuthCode, liberr.Error)
|
||||||
router []ginsdk.HandlerFunc
|
router []ginsdk.HandlerFunc
|
||||||
authType string
|
authType string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Authorization interface {
|
|
||||||
Handler(c *ginsdk.Context)
|
|
||||||
Register(router ...ginsdk.HandlerFunc) ginsdk.HandlerFunc
|
|
||||||
Append(router ...ginsdk.HandlerFunc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuthorization(log liblog.FuncLog, HeadAuthType string, authCheckFunc func(AuthHeader string) (AuthCode, liberr.Error)) Authorization {
|
|
||||||
return &authorization{
|
|
||||||
log: log,
|
|
||||||
check: authCheckFunc,
|
|
||||||
authType: HeadAuthType,
|
|
||||||
router: make([]ginsdk.HandlerFunc, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *authorization) Register(router ...ginsdk.HandlerFunc) ginsdk.HandlerFunc {
|
func (a *authorization) Register(router ...ginsdk.HandlerFunc) ginsdk.HandlerFunc {
|
||||||
a.router = router
|
a.router = router
|
||||||
return a.Handler
|
return a.Handler
|
||||||
@@ -112,10 +62,10 @@ func (a *authorization) logDebug(msg string, args ...interface{}) {
|
|||||||
|
|
||||||
func (a *authorization) Handler(c *ginsdk.Context) {
|
func (a *authorization) Handler(c *ginsdk.Context) {
|
||||||
// Search user in the slice of allowed credentials
|
// Search user in the slice of allowed credentials
|
||||||
auth := c.Request.Header.Get(HEAD_AUTH_SEND)
|
auth := c.Request.Header.Get(rtrhdr.HeaderAuthSend)
|
||||||
|
|
||||||
if auth == "" {
|
if auth == "" {
|
||||||
AuthRequire(c, fmt.Errorf("%v", ErrorHeaderAuthMissing.Error(nil).GetErrorSlice()))
|
rtrhdr.AuthRequire(c, fmt.Errorf("%v", librtr.ErrorHeaderAuthMissing.Error(nil).GetErrorSlice()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,24 +79,24 @@ func (a *authorization) Handler(c *ginsdk.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if authValue == "" {
|
if authValue == "" {
|
||||||
AuthRequire(c, fmt.Errorf("%v", ErrorHeaderAuthEmpty.Error(nil).GetErrorSlice()))
|
rtrhdr.AuthRequire(c, fmt.Errorf("%v", librtr.ErrorHeaderAuthEmpty.Error(nil).GetErrorSlice()))
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
code, err := a.check(authValue)
|
code, err := a.check(authValue)
|
||||||
|
|
||||||
switch code {
|
switch code {
|
||||||
case AUTH_CODE_SUCCESS:
|
case rtrhdr.AuthCodeSuccess:
|
||||||
for _, r := range a.router {
|
for _, r := range a.router {
|
||||||
a.logDebug("Calling router '%s=%s'", c.Request.Method, c.Request.URL.RawPath)
|
a.logDebug("Calling router '%s=%s'", c.Request.Method, c.Request.URL.RawPath)
|
||||||
r(c)
|
r(c)
|
||||||
}
|
}
|
||||||
case AUTH_CODE_REQUIRE:
|
case rtrhdr.AuthCodeRequire:
|
||||||
AuthRequire(c, fmt.Errorf("%v", ErrorHeaderAuthRequire.Error(err).GetErrorSlice()))
|
rtrhdr.AuthRequire(c, fmt.Errorf("%v", librtr.ErrorHeaderAuthRequire.Error(err).GetErrorSlice()))
|
||||||
case AUTH_CODE_FORBIDDEN:
|
case rtrhdr.AuthCodeForbidden:
|
||||||
AuthForbidden(c, fmt.Errorf("%v", ErrorHeaderAuthForbidden.Error(err).GetErrorSlice()))
|
rtrhdr.AuthForbidden(c, fmt.Errorf("%v", librtr.ErrorHeaderAuthForbidden.Error(err).GetErrorSlice()))
|
||||||
default:
|
default:
|
||||||
c.Errors = append(c.Errors, &ginsdk.Error{
|
c.Errors = append(c.Errors, &ginsdk.Error{
|
||||||
Err: fmt.Errorf("%v", ErrorHeaderAuth.Error(err).GetErrorSlice()),
|
Err: fmt.Errorf("%v", librtr.ErrorHeaderAuth.Error(err).GetErrorSlice()),
|
||||||
Type: ginsdk.ErrorTypePrivate,
|
Type: ginsdk.ErrorTypePrivate,
|
||||||
})
|
})
|
||||||
c.AbortWithStatus(http.StatusInternalServerError)
|
c.AbortWithStatus(http.StatusInternalServerError)
|
68
router/authheader/interface.go
Normal file
68
router/authheader/interface.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package authheader
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AuthCode uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
AuthCodeSuccess = iota
|
||||||
|
AuthCodeRequire
|
||||||
|
AuthCodeForbidden
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HeaderAuthRequire = "WWW-Authenticate"
|
||||||
|
HeaderAuthSend = "Authorization"
|
||||||
|
HeaderAuthReal = "Basic realm=LDAP Authorization Required"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthRequire(c *ginsdk.Context, err error) {
|
||||||
|
if err != nil {
|
||||||
|
c.Errors = append(c.Errors, &ginsdk.Error{
|
||||||
|
Err: err,
|
||||||
|
Type: ginsdk.ErrorTypePrivate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Credentials doesn't match, we return 401 and abort handlers chain.
|
||||||
|
c.Header(HeaderAuthRequire, HeaderAuthReal)
|
||||||
|
c.AbortWithStatus(http.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AuthForbidden(c *ginsdk.Context, err error) {
|
||||||
|
if err != nil {
|
||||||
|
c.Errors = append(c.Errors, &ginsdk.Error{
|
||||||
|
Err: err,
|
||||||
|
Type: ginsdk.ErrorTypePrivate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
c.AbortWithStatus(http.StatusForbidden)
|
||||||
|
}
|
109
router/default.go
Normal file
109
router/default.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DefaultGinInit() *ginsdk.Engine {
|
||||||
|
engine := ginsdk.New()
|
||||||
|
engine.Use(ginsdk.Logger(), ginsdk.Recovery())
|
||||||
|
|
||||||
|
return engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultGinWithTrustyProxy(trustyProxy []string) *ginsdk.Engine {
|
||||||
|
engine := ginsdk.New()
|
||||||
|
engine.Use(ginsdk.Logger(), ginsdk.Recovery())
|
||||||
|
|
||||||
|
if len(trustyProxy) > 0 {
|
||||||
|
_ = engine.SetTrustedProxies(trustyProxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
return engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultGinWithTrustedPlatform(trustedPlatform string) *ginsdk.Engine {
|
||||||
|
engine := ginsdk.New()
|
||||||
|
engine.Use(ginsdk.Logger(), ginsdk.Recovery())
|
||||||
|
|
||||||
|
if len(trustedPlatform) > 0 {
|
||||||
|
engine.TrustedPlatform = trustedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
return engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func RoutersRegister(method string, relativePath string, router ...ginsdk.HandlerFunc) {
|
||||||
|
defaultRouters.Register(method, relativePath, router...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RoutersRegisterInGroup(group, method string, relativePath string, router ...ginsdk.HandlerFunc) {
|
||||||
|
defaultRouters.RegisterInGroup(group, method, relativePath, router...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RoutersHandler(engine *ginsdk.Engine) {
|
||||||
|
defaultRouters.Handler(engine)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GinEngine(trustedPlatform string, trustyProxy ...string) (*ginsdk.Engine, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
engine := ginsdk.New()
|
||||||
|
if len(trustyProxy) > 0 {
|
||||||
|
err = engine.SetTrustedProxies(trustyProxy)
|
||||||
|
}
|
||||||
|
if len(trustedPlatform) > 0 {
|
||||||
|
engine.TrustedPlatform = trustedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
return engine, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GinAddGlobalMiddleware(eng *ginsdk.Engine, middleware ...ginsdk.HandlerFunc) *ginsdk.Engine {
|
||||||
|
eng.Use(middleware...)
|
||||||
|
return eng
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGinHandler func that return given func as ginTonic HandlerFunc interface type.
|
||||||
|
func SetGinHandler(fct func(c *ginsdk.Context)) ginsdk.HandlerFunc {
|
||||||
|
return fct
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(routerList RouterList) http.Handler {
|
||||||
|
e := routerList.Engine()
|
||||||
|
|
||||||
|
if routerList == nil {
|
||||||
|
RoutersHandler(e)
|
||||||
|
} else {
|
||||||
|
routerList.Handler(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
53
router/header/config.go
Normal file
53
router/header/config.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package header
|
||||||
|
|
||||||
|
import (
|
||||||
|
liberr "github.com/nabbar/golib/errors"
|
||||||
|
"github.com/nabbar/golib/router"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HeadersConfig map[string]string
|
||||||
|
|
||||||
|
func (h HeadersConfig) New() Headers {
|
||||||
|
var res = NewHeaders()
|
||||||
|
|
||||||
|
for k, v := range h {
|
||||||
|
res.Add(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HeadersConfig) Validate() liberr.Error {
|
||||||
|
err := router.ErrorConfigValidator.Error(nil)
|
||||||
|
|
||||||
|
if !err.HasParent() {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
51
router/header/interface.go
Normal file
51
router/header/interface.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package header
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Headers interface {
|
||||||
|
Add(key, value string)
|
||||||
|
Set(key, value string)
|
||||||
|
Get(key string) string
|
||||||
|
Del(key string)
|
||||||
|
|
||||||
|
Header() map[string]string
|
||||||
|
Register(router ...ginsdk.HandlerFunc) []ginsdk.HandlerFunc
|
||||||
|
Handler(c *ginsdk.Context)
|
||||||
|
|
||||||
|
Clone() Headers
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHeaders() Headers {
|
||||||
|
return &headers{
|
||||||
|
head: make(http.Header),
|
||||||
|
}
|
||||||
|
}
|
@@ -23,60 +23,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package router
|
package header
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type HeadersConfig map[string]string
|
|
||||||
|
|
||||||
func (h HeadersConfig) New() Headers {
|
|
||||||
var res = NewHeaders()
|
|
||||||
|
|
||||||
for k, v := range h {
|
|
||||||
res.Add(k, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h HeadersConfig) Validate() liberr.Error {
|
|
||||||
err := ErrorConfigValidator.Error(nil)
|
|
||||||
|
|
||||||
if !err.HasParent() {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type headers struct {
|
type headers struct {
|
||||||
head http.Header
|
head http.Header
|
||||||
}
|
}
|
||||||
|
|
||||||
type Headers interface {
|
|
||||||
Add(key, value string)
|
|
||||||
Set(key, value string)
|
|
||||||
Get(key string) string
|
|
||||||
Del(key string)
|
|
||||||
|
|
||||||
Header() map[string]string
|
|
||||||
Register(router ...ginsdk.HandlerFunc) []ginsdk.HandlerFunc
|
|
||||||
Handler(c *ginsdk.Context)
|
|
||||||
|
|
||||||
Clone() Headers
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHeaders() Headers {
|
|
||||||
return &headers{
|
|
||||||
head: make(http.Header),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h headers) Clone() Headers {
|
func (h headers) Clone() Headers {
|
||||||
return &headers{
|
return &headers{
|
||||||
head: h.head,
|
head: h.head,
|
67
router/interface.go
Normal file
67
router/interface.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
EmptyHandlerGroup = "<nil>"
|
||||||
|
GinContextStartUnixNanoTime = "gin-ctx-start-unix-nano-time"
|
||||||
|
GinContextRequestPath = "gin-ctx-request-path"
|
||||||
|
GinContextRequestUser = "gin-ctx-request-user"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultRouters = NewRouterList(DefaultGinInit)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if os.Getenv("GIN_MODE") == "" {
|
||||||
|
ginsdk.SetMode(ginsdk.ReleaseMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterRouter func(method string, relativePath string, router ...ginsdk.HandlerFunc)
|
||||||
|
type RegisterRouterInGroup func(group, method string, relativePath string, router ...ginsdk.HandlerFunc)
|
||||||
|
|
||||||
|
type RouterList interface {
|
||||||
|
Register(method string, relativePath string, router ...ginsdk.HandlerFunc)
|
||||||
|
RegisterInGroup(group, method string, relativePath string, router ...ginsdk.HandlerFunc)
|
||||||
|
RegisterMergeInGroup(group, method string, relativePath string, router ...ginsdk.HandlerFunc)
|
||||||
|
Handler(engine *ginsdk.Engine)
|
||||||
|
Engine() *ginsdk.Engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRouterList(initGin func() *ginsdk.Engine) RouterList {
|
||||||
|
return &rtr{
|
||||||
|
init: initGin,
|
||||||
|
list: make(map[string][]itm),
|
||||||
|
}
|
||||||
|
}
|
@@ -40,36 +40,6 @@ import (
|
|||||||
loglvl "github.com/nabbar/golib/logger/level"
|
loglvl "github.com/nabbar/golib/logger/level"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
EmptyHandlerGroup = "<nil>"
|
|
||||||
GinContextStartUnixNanoTime = "gin-ctx-start-unix-nano-time"
|
|
||||||
GinContextRequestPath = "gin-ctx-request-path"
|
|
||||||
GinContextRequestUser = "gin-ctx-request-user"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
defaultRouters = NewRouterList(DefaultGinInit)
|
|
||||||
)
|
|
||||||
|
|
||||||
func GinEngine(trustedPlatform string, trustyProxy ...string) (*ginsdk.Engine, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
engine := ginsdk.New()
|
|
||||||
if len(trustyProxy) > 0 {
|
|
||||||
err = engine.SetTrustedProxies(trustyProxy)
|
|
||||||
}
|
|
||||||
if len(trustedPlatform) > 0 {
|
|
||||||
engine.TrustedPlatform = trustedPlatform
|
|
||||||
}
|
|
||||||
|
|
||||||
return engine, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func GinAddGlobalMiddleware(eng *ginsdk.Engine, middleware ...ginsdk.HandlerFunc) *ginsdk.Engine {
|
|
||||||
eng.Use(middleware...)
|
|
||||||
return eng
|
|
||||||
}
|
|
||||||
|
|
||||||
func GinLatencyContext(c *ginsdk.Context) {
|
func GinLatencyContext(c *ginsdk.Context) {
|
||||||
// Start timer
|
// Start timer
|
||||||
c.Set(GinContextStartUnixNanoTime, time.Now().UnixNano())
|
c.Set(GinContextStartUnixNanoTime, time.Now().UnixNano())
|
||||||
@@ -78,13 +48,6 @@ func GinLatencyContext(c *ginsdk.Context) {
|
|||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func sanitizeString(s string) string {
|
|
||||||
s = strings.Replace(s, "\n", "", -1)
|
|
||||||
s = strings.Replace(s, "\r", "", -1)
|
|
||||||
s = strings.Replace(s, "\t", "", -1)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func GinRequestContext(c *ginsdk.Context) {
|
func GinRequestContext(c *ginsdk.Context) {
|
||||||
// Set Path
|
// Set Path
|
||||||
if c != nil {
|
if c != nil {
|
||||||
@@ -204,115 +167,3 @@ func GinErrorLog(log liblog.FuncLog) ginsdk.HandlerFunc {
|
|||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultGinInit() *ginsdk.Engine {
|
|
||||||
engine := ginsdk.New()
|
|
||||||
engine.Use(ginsdk.Logger(), ginsdk.Recovery())
|
|
||||||
|
|
||||||
return engine
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultGinWithTrustyProxy(trustyProxy []string) *ginsdk.Engine {
|
|
||||||
engine := ginsdk.New()
|
|
||||||
engine.Use(ginsdk.Logger(), ginsdk.Recovery())
|
|
||||||
|
|
||||||
if len(trustyProxy) > 0 {
|
|
||||||
_ = engine.SetTrustedProxies(trustyProxy)
|
|
||||||
}
|
|
||||||
|
|
||||||
return engine
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultGinWithTrustedPlatform(trustedPlatform string) *ginsdk.Engine {
|
|
||||||
engine := ginsdk.New()
|
|
||||||
engine.Use(ginsdk.Logger(), ginsdk.Recovery())
|
|
||||||
|
|
||||||
if len(trustedPlatform) > 0 {
|
|
||||||
engine.TrustedPlatform = trustedPlatform
|
|
||||||
}
|
|
||||||
|
|
||||||
return engine
|
|
||||||
}
|
|
||||||
|
|
||||||
type routerItem struct {
|
|
||||||
method string
|
|
||||||
relative string
|
|
||||||
router []ginsdk.HandlerFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
type routerList struct {
|
|
||||||
init func() *ginsdk.Engine
|
|
||||||
list map[string][]routerItem
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegisterRouter func(method string, relativePath string, router ...ginsdk.HandlerFunc)
|
|
||||||
type RegisterRouterInGroup func(group, method string, relativePath string, router ...ginsdk.HandlerFunc)
|
|
||||||
|
|
||||||
type RouterList interface {
|
|
||||||
Register(method string, relativePath string, router ...ginsdk.HandlerFunc)
|
|
||||||
RegisterInGroup(group, method string, relativePath string, router ...ginsdk.HandlerFunc)
|
|
||||||
Handler(engine *ginsdk.Engine)
|
|
||||||
Engine() *ginsdk.Engine
|
|
||||||
}
|
|
||||||
|
|
||||||
func RoutersRegister(method string, relativePath string, router ...ginsdk.HandlerFunc) {
|
|
||||||
defaultRouters.Register(method, relativePath, router...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RoutersRegisterInGroup(group, method string, relativePath string, router ...ginsdk.HandlerFunc) {
|
|
||||||
defaultRouters.RegisterInGroup(group, method, relativePath, router...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RoutersHandler(engine *ginsdk.Engine) {
|
|
||||||
defaultRouters.Handler(engine)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRouterList(initGin func() *ginsdk.Engine) RouterList {
|
|
||||||
return &routerList{
|
|
||||||
init: initGin,
|
|
||||||
list: make(map[string][]routerItem),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l routerList) Handler(engine *ginsdk.Engine) {
|
|
||||||
for grpRoute, grpList := range l.list {
|
|
||||||
if grpRoute == EmptyHandlerGroup {
|
|
||||||
for _, r := range grpList {
|
|
||||||
engine.Handle(r.method, r.relative, r.router...)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var grp = engine.Group(grpRoute)
|
|
||||||
for _, r := range grpList {
|
|
||||||
grp.Handle(r.method, r.relative, r.router...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *routerList) RegisterInGroup(group, method string, relativePath string, router ...ginsdk.HandlerFunc) {
|
|
||||||
if group == "" {
|
|
||||||
group = EmptyHandlerGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := l.list[group]; !ok {
|
|
||||||
l.list[group] = make([]routerItem, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
l.list[group] = append(l.list[group], routerItem{
|
|
||||||
method: method,
|
|
||||||
relative: relativePath,
|
|
||||||
router: router,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *routerList) Register(method string, relativePath string, router ...ginsdk.HandlerFunc) {
|
|
||||||
l.RegisterInGroup("", method, relativePath, router...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l routerList) Engine() *ginsdk.Engine {
|
|
||||||
if l.init != nil {
|
|
||||||
return l.init()
|
|
||||||
} else {
|
|
||||||
return DefaultGinInit()
|
|
||||||
}
|
|
||||||
}
|
|
104
router/model.go
Normal file
104
router/model.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type rtr struct {
|
||||||
|
init func() *ginsdk.Engine
|
||||||
|
list map[string][]itm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *rtr) Handler(engine *ginsdk.Engine) {
|
||||||
|
for grpRoute, grpList := range l.list {
|
||||||
|
if grpRoute == EmptyHandlerGroup {
|
||||||
|
for _, r := range grpList {
|
||||||
|
engine.Handle(r.method, r.relative, r.router...)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var grp = engine.Group(grpRoute)
|
||||||
|
for _, r := range grpList {
|
||||||
|
grp.Handle(r.method, r.relative, r.router...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *rtr) RegisterInGroup(group, method, relativePath string, router ...ginsdk.HandlerFunc) {
|
||||||
|
if group == "" {
|
||||||
|
group = EmptyHandlerGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := l.list[group]; !ok {
|
||||||
|
l.list[group] = make([]itm, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.list[group] = append(l.list[group], itm{
|
||||||
|
method: method,
|
||||||
|
relative: relativePath,
|
||||||
|
router: router,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *rtr) RegisterMergeInGroup(group, method, relativePath string, router ...ginsdk.HandlerFunc) {
|
||||||
|
if group == "" {
|
||||||
|
group = EmptyHandlerGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := l.list[group]; !ok {
|
||||||
|
l.list[group] = make([]itm, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if same route exists for same relative path and same method, so replace router list
|
||||||
|
for i, r := range l.list[group] {
|
||||||
|
if !r.Same(method, relativePath) {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
l.list[group][i].Merge(router...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l.list[group] = append(l.list[group], itm{
|
||||||
|
method: method,
|
||||||
|
relative: relativePath,
|
||||||
|
router: router,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *rtr) Register(method, relativePath string, router ...ginsdk.HandlerFunc) {
|
||||||
|
l.RegisterInGroup("", method, relativePath, router...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *rtr) Engine() *ginsdk.Engine {
|
||||||
|
if l.init != nil {
|
||||||
|
return l.init()
|
||||||
|
} else {
|
||||||
|
return DefaultGinInit()
|
||||||
|
}
|
||||||
|
}
|
@@ -25,32 +25,24 @@
|
|||||||
|
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import ginsdk "github.com/gin-gonic/gin"
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
type itm struct {
|
||||||
)
|
method string
|
||||||
|
relative string
|
||||||
func init() {
|
router []ginsdk.HandlerFunc
|
||||||
if os.Getenv("GIN_MODE") == "" {
|
|
||||||
ginsdk.SetMode(ginsdk.ReleaseMode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGinHandler func that return given func as ginTonic HandlerFunc interface type.
|
func (o *itm) Same(method, relative string) bool {
|
||||||
func SetGinHandler(fct func(c *ginsdk.Context)) ginsdk.HandlerFunc {
|
if o.method != method {
|
||||||
return fct
|
return false
|
||||||
|
}
|
||||||
|
if o.relative != relative {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func Handler(routerList RouterList) http.Handler {
|
func (o *itm) Merge(rtr ...ginsdk.HandlerFunc) {
|
||||||
e := routerList.Engine()
|
o.router = rtr
|
||||||
|
|
||||||
if routerList == nil {
|
|
||||||
RoutersHandler(e)
|
|
||||||
} else {
|
|
||||||
routerList.Handler(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return e
|
|
||||||
}
|
}
|
||||||
|
35
router/tools.go
Normal file
35
router/tools.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Nicolas JUHEL
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package router
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
func sanitizeString(s string) string {
|
||||||
|
s = strings.Replace(s, "\n", "", -1)
|
||||||
|
s = strings.Replace(s, "\r", "", -1)
|
||||||
|
s = strings.Replace(s, "\t", "", -1)
|
||||||
|
return s
|
||||||
|
}
|
@@ -30,7 +30,6 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
libfpg "github.com/nabbar/golib/file/progress"
|
libfpg "github.com/nabbar/golib/file/progress"
|
||||||
@@ -48,7 +47,7 @@ type Static interface {
|
|||||||
RegisterRouter(route string, register librtr.RegisterRouter, router ...ginsdk.HandlerFunc)
|
RegisterRouter(route string, register librtr.RegisterRouter, router ...ginsdk.HandlerFunc)
|
||||||
RegisterRouterInGroup(route, group string, register librtr.RegisterRouterInGroup, router ...ginsdk.HandlerFunc)
|
RegisterRouterInGroup(route, group string, register librtr.RegisterRouterInGroup, router ...ginsdk.HandlerFunc)
|
||||||
|
|
||||||
RegisterLogger(log func() liblog.Logger)
|
RegisterLogger(log liblog.FuncLog)
|
||||||
|
|
||||||
SetDownload(pathFile string, flag bool)
|
SetDownload(pathFile string, flag bool)
|
||||||
SetIndex(group, route, pathFile string)
|
SetIndex(group, route, pathFile string)
|
||||||
@@ -79,15 +78,19 @@ type Static interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx libctx.FuncContext, content embed.FS, embedRootDir ...string) Static {
|
func New(ctx libctx.FuncContext, content embed.FS, embedRootDir ...string) Static {
|
||||||
return &staticHandler{
|
s := &staticHandler{
|
||||||
m: sync.RWMutex{},
|
l: new(atomic.Value),
|
||||||
l: nil,
|
|
||||||
c: content,
|
c: content,
|
||||||
b: embedRootDir,
|
b: new(atomic.Value),
|
||||||
z: 0,
|
z: new(atomic.Int64),
|
||||||
i: libctx.NewConfig[string](ctx),
|
i: libctx.NewConfig[string](ctx),
|
||||||
d: libctx.NewConfig[string](ctx),
|
d: libctx.NewConfig[string](ctx),
|
||||||
f: libctx.NewConfig[string](ctx),
|
f: libctx.NewConfig[string](ctx),
|
||||||
|
s: libctx.NewConfig[string](ctx),
|
||||||
r: new(atomic.Value),
|
r: new(atomic.Value),
|
||||||
|
h: new(atomic.Value),
|
||||||
}
|
}
|
||||||
|
s._setBase(embedRootDir...)
|
||||||
|
s._setLogger(nil)
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,6 @@ package static
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
libctx "github.com/nabbar/golib/context"
|
libctx "github.com/nabbar/golib/context"
|
||||||
@@ -40,62 +39,46 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type staticHandler struct {
|
type staticHandler struct {
|
||||||
m sync.RWMutex
|
l *atomic.Value // logger
|
||||||
l func() liblog.Logger
|
r *atomic.Value // router
|
||||||
|
h *atomic.Value // monitor
|
||||||
|
|
||||||
c embed.FS
|
c embed.FS
|
||||||
b []string // base
|
b *atomic.Value // base []string
|
||||||
z int64 // size
|
z *atomic.Int64 // size
|
||||||
|
|
||||||
i libctx.Config[string] // index
|
i libctx.Config[string] // index
|
||||||
d libctx.Config[string] // download
|
d libctx.Config[string] // download
|
||||||
f libctx.Config[string] // follow
|
f libctx.Config[string] // follow
|
||||||
s libctx.Config[string] // specific
|
s libctx.Config[string] // specific
|
||||||
r *atomic.Value // router
|
|
||||||
h *atomic.Value // monitor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _setLogger(fct func() liblog.Logger) {
|
func (s *staticHandler) _setLogger(fct liblog.FuncLog) {
|
||||||
s.m.Lock()
|
if fct == nil {
|
||||||
defer s.m.Unlock()
|
fct = s._getDefaultLogger
|
||||||
|
}
|
||||||
|
|
||||||
s.l = fct
|
s.l.Store(fct())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _getLogger() liblog.Logger {
|
func (s *staticHandler) _getLogger() liblog.Logger {
|
||||||
s.m.RLock()
|
i := s.l.Load()
|
||||||
defer s.m.RUnlock()
|
|
||||||
|
|
||||||
var log liblog.Logger
|
if i == nil {
|
||||||
|
return s._getDefaultLogger()
|
||||||
if s.l == nil {
|
} else if l, k := i.(liblog.FuncLog); !k {
|
||||||
s.m.RUnlock()
|
return s._getDefaultLogger()
|
||||||
log = s._getDefaultLogger()
|
} else if log := l(); log == nil {
|
||||||
s.m.RLock()
|
return s._getDefaultLogger()
|
||||||
return log
|
|
||||||
} else if log = s.l(); log == nil {
|
|
||||||
s.m.RUnlock()
|
|
||||||
log = s._getDefaultLogger()
|
|
||||||
s.m.RLock()
|
|
||||||
return log
|
|
||||||
} else {
|
} else {
|
||||||
return log
|
return log
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _getDefaultLogger() liblog.Logger {
|
func (s *staticHandler) _getDefaultLogger() liblog.Logger {
|
||||||
s.m.Lock()
|
return liblog.New(s.d.GetContext)
|
||||||
defer s.m.Unlock()
|
|
||||||
|
|
||||||
var log = liblog.New(s.d.GetContext)
|
|
||||||
|
|
||||||
s.l = func() liblog.Logger {
|
|
||||||
return log
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return log
|
func (s *staticHandler) RegisterLogger(log liblog.FuncLog) {
|
||||||
}
|
|
||||||
|
|
||||||
func (s *staticHandler) RegisterLogger(log func() liblog.Logger) {
|
|
||||||
s._setLogger(log)
|
s._setLogger(log)
|
||||||
}
|
}
|
||||||
|
@@ -41,31 +41,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *staticHandler) _getSize() int64 {
|
func (s *staticHandler) _getSize() int64 {
|
||||||
s.m.RLock()
|
return s.z.Load()
|
||||||
defer s.m.RUnlock()
|
|
||||||
|
|
||||||
return s.z
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _setSize(size int64) {
|
func (s *staticHandler) _setSize(size int64) {
|
||||||
s.m.Lock()
|
s.z.Store(size)
|
||||||
defer s.m.Unlock()
|
|
||||||
|
|
||||||
s.z = size
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _getBase() []string {
|
func (s *staticHandler) _getBase() []string {
|
||||||
s.m.RLock()
|
i := s.b.Load()
|
||||||
defer s.m.RUnlock()
|
if i == nil {
|
||||||
|
return make([]string, 0)
|
||||||
return s.b
|
} else if b, k := i.([]string); !k {
|
||||||
|
return make([]string, 0)
|
||||||
|
} else {
|
||||||
|
return b
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _setBase(base ...string) {
|
func (s *staticHandler) _setBase(base ...string) {
|
||||||
s.m.Lock()
|
var b = make([]string, 0)
|
||||||
defer s.m.Unlock()
|
|
||||||
|
|
||||||
s.b = base
|
if len(base) > 0 {
|
||||||
|
b = append(b, base...)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.b.Store(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _listEmbed(root string) ([]fs.DirEntry, liberr.Error) {
|
func (s *staticHandler) _listEmbed(root string) ([]fs.DirEntry, liberr.Error) {
|
||||||
@@ -73,9 +74,6 @@ func (s *staticHandler) _listEmbed(root string) ([]fs.DirEntry, liberr.Error) {
|
|||||||
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.m.RLock()
|
|
||||||
defer s.m.RUnlock()
|
|
||||||
|
|
||||||
val, err := s.c.ReadDir(root)
|
val, err := s.c.ReadDir(root)
|
||||||
|
|
||||||
if err != nil && errors.Is(err, fs.ErrNotExist) {
|
if err != nil && errors.Is(err, fs.ErrNotExist) {
|
||||||
@@ -108,9 +106,6 @@ func (s *staticHandler) _fileInfo(pathFile string) (fs.FileInfo, liberr.Error) {
|
|||||||
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.m.RLock()
|
|
||||||
defer s.m.RUnlock()
|
|
||||||
|
|
||||||
var inf fs.FileInfo
|
var inf fs.FileInfo
|
||||||
obj, err := s.c.Open(pathFile)
|
obj, err := s.c.Open(pathFile)
|
||||||
|
|
||||||
@@ -140,9 +135,6 @@ func (s *staticHandler) _fileBuff(pathFile string) (io.ReadCloser, liberr.Error)
|
|||||||
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.m.RLock()
|
|
||||||
defer s.m.RUnlock()
|
|
||||||
|
|
||||||
obj, err := s.c.ReadFile(pathFile)
|
obj, err := s.c.ReadFile(pathFile)
|
||||||
|
|
||||||
if err != nil && errors.Is(err, fs.ErrNotExist) {
|
if err != nil && errors.Is(err, fs.ErrNotExist) {
|
||||||
@@ -159,9 +151,6 @@ func (s *staticHandler) _fileTemp(pathFile string) (libfpg.Progress, liberr.Erro
|
|||||||
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
return nil, ErrorParamEmpty.Error(fmt.Errorf("pathfile is empty"))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.m.RLock()
|
|
||||||
defer s.m.RUnlock()
|
|
||||||
|
|
||||||
var tmp libfpg.Progress
|
var tmp libfpg.Progress
|
||||||
obj, err := s.c.Open(pathFile)
|
obj, err := s.c.Open(pathFile)
|
||||||
|
|
||||||
|
@@ -35,6 +35,8 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/nabbar/golib/router/header"
|
||||||
|
|
||||||
ginsdk "github.com/gin-gonic/gin"
|
ginsdk "github.com/gin-gonic/gin"
|
||||||
ginrdr "github.com/gin-gonic/gin/render"
|
ginrdr "github.com/gin-gonic/gin/render"
|
||||||
liberr "github.com/nabbar/golib/errors"
|
liberr "github.com/nabbar/golib/errors"
|
||||||
@@ -50,18 +52,53 @@ func (s *staticHandler) _makeRoute(group, route string) string {
|
|||||||
return path.Join(group, route)
|
return path.Join(group, route)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) RegisterRouter(route string, register librtr.RegisterRouter, router ...ginsdk.HandlerFunc) {
|
func (s *staticHandler) genRegisterRouter(route, group string, register any, router ...ginsdk.HandlerFunc) {
|
||||||
s._setRouter(append(s._getRouter(), s._makeRoute(urlPathSeparator, route)))
|
var (
|
||||||
|
ok bool
|
||||||
|
rte string
|
||||||
|
reg librtr.RegisterRouter
|
||||||
|
grp librtr.RegisterRouterInGroup
|
||||||
|
)
|
||||||
|
|
||||||
|
if register == nil {
|
||||||
|
return
|
||||||
|
} else if reg, ok = register.(librtr.RegisterRouter); ok {
|
||||||
|
rte = s._makeRoute(urlPathSeparator, route)
|
||||||
|
grp = nil
|
||||||
|
} else if grp, ok = register.(librtr.RegisterRouterInGroup); ok {
|
||||||
|
rte = s._makeRoute(group, route)
|
||||||
|
reg = nil
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(router) > 0 {
|
||||||
router = append(router, s.Get)
|
router = append(router, s.Get)
|
||||||
register(http.MethodGet, path.Join(route, urlPathSeparator+"*file"), router...)
|
} else {
|
||||||
|
router = append(make([]ginsdk.HandlerFunc, 0), s.Get)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rtr := s._getRouter(); len(rtr) > 0 {
|
||||||
|
s._setRouter(append(rtr, rte))
|
||||||
|
} else {
|
||||||
|
s._setRouter(append(make([]string, 0), rte))
|
||||||
|
}
|
||||||
|
|
||||||
|
if reg != nil {
|
||||||
|
reg(http.MethodGet, path.Join(route, urlPathSeparator+"*file"), router...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if grp != nil {
|
||||||
|
grp(group, http.MethodGet, path.Join(route, urlPathSeparator+"*file"), router...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *staticHandler) RegisterRouter(route string, register librtr.RegisterRouter, router ...ginsdk.HandlerFunc) {
|
||||||
|
s.genRegisterRouter(route, "", register, router...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) RegisterRouterInGroup(route, group string, register librtr.RegisterRouterInGroup, router ...ginsdk.HandlerFunc) {
|
func (s *staticHandler) RegisterRouterInGroup(route, group string, register librtr.RegisterRouterInGroup, router ...ginsdk.HandlerFunc) {
|
||||||
s._setRouter(append(s._getRouter(), s._makeRoute(group, route)))
|
s.genRegisterRouter(route, group, register, router...)
|
||||||
|
|
||||||
router = append(router, s.Get)
|
|
||||||
register(group, http.MethodGet, path.Join(route, urlPathSeparator+"*file"), router...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) Get(c *ginsdk.Context) {
|
func (s *staticHandler) Get(c *ginsdk.Context) {
|
||||||
@@ -139,7 +176,7 @@ func (s *staticHandler) Get(c *ginsdk.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) SendFile(c *ginsdk.Context, filename string, size int64, isDownload bool, buf io.ReadCloser) {
|
func (s *staticHandler) SendFile(c *ginsdk.Context, filename string, size int64, isDownload bool, buf io.ReadCloser) {
|
||||||
head := librtr.NewHeaders()
|
head := header.NewHeaders()
|
||||||
|
|
||||||
if isDownload {
|
if isDownload {
|
||||||
head.Add("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", path.Base(filename)))
|
head.Add("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", path.Base(filename)))
|
||||||
|
@@ -26,36 +26,22 @@
|
|||||||
|
|
||||||
package static
|
package static
|
||||||
|
|
||||||
import "sync/atomic"
|
|
||||||
|
|
||||||
func (s *staticHandler) _getRouter() []string {
|
func (s *staticHandler) _getRouter() []string {
|
||||||
s.m.Lock()
|
|
||||||
defer s.m.Unlock()
|
|
||||||
|
|
||||||
var def = make([]string, 0)
|
|
||||||
if s.r == nil {
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
if i := s.r.Load(); i == nil {
|
if i := s.r.Load(); i == nil {
|
||||||
return def
|
return make([]string, 0)
|
||||||
} else if o, ok := i.([]string); !ok {
|
} else if o, ok := i.([]string); !ok {
|
||||||
return def
|
return make([]string, 0)
|
||||||
} else {
|
} else {
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *staticHandler) _setRouter(val []string) {
|
func (s *staticHandler) _setRouter(val []string) {
|
||||||
s.m.Lock()
|
var rtr = make([]string, 0)
|
||||||
defer s.m.Unlock()
|
|
||||||
|
|
||||||
if val == nil {
|
if len(val) > 0 {
|
||||||
val = make([]string, 0)
|
copy(rtr, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.r == nil {
|
s.r.Store(rtr)
|
||||||
s.r = new(atomic.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.r.Store(val)
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user