Compare commits

..

No commits in common. "ab8042e9e5370bbe0e93ea5adc6e74ae4c5df95e" and "97eab7d09a8b048cab4a3d8ebd6c0ea78284c716" have entirely different histories.

7 changed files with 14 additions and 133 deletions

21
auth.go
View File

@ -15,7 +15,6 @@ import (
// AuthUserKey is the cookie name for user credential in basic auth.
const AuthUserKey = "user"
const AuthProxyUserKey = "proxy_user"
// Accounts defines a key/value for user/pass list of authorized logins.
type Accounts map[string]string
@ -90,23 +89,3 @@ func authorizationHeader(user, password string) string {
base := user + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString(bytesconv.StringToBytes(base))
}
func BasicAuthForProxy(accounts Accounts, realm string) HandlerFunc {
if realm == "" {
realm = "Proxy Authorization Required"
}
realm = "Basic realm=" + strconv.Quote(realm)
pairs := processAccounts(accounts)
return func(c *Context) {
proxyUser, found := pairs.searchCredential(c.requestHeader("Proxy-Authorization"))
if !found {
// Credentials doesn't match, we return 407 and abort handlers chain.
c.Header("Proxy-Authenticate", realm)
c.AbortWithStatus(http.StatusProxyAuthRequired)
return
}
// The proxy_user credentials was found, set proxy_user's id to key AuthProxyUserKey in this context, the proxy_user's id can be read later using
// c.MustGet(gin.AuthProxyUserKey).
c.Set(AuthProxyUserKey, proxyUser)
}
}

View File

@ -137,40 +137,3 @@ func TestBasicAuth401WithCustomRealm(t *testing.T) {
assert.Equal(t, http.StatusUnauthorized, w.Code)
assert.Equal(t, "Basic realm=\"My Custom \\\"Realm\\\"\"", w.Header().Get("WWW-Authenticate"))
}
func TestBasicAuthForProxySucceed(t *testing.T) {
accounts := Accounts{"admin": "password"}
router := New()
router.Use(BasicAuthForProxy(accounts, ""))
router.Any("/*proxyPath", func(c *Context) {
c.String(http.StatusOK, c.MustGet(AuthProxyUserKey).(string))
})
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("Proxy-Authorization", authorizationHeader("admin", "password"))
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, "admin", w.Body.String())
}
func TestBasicAuthForProxy407(t *testing.T) {
called := false
accounts := Accounts{"foo": "bar"}
router := New()
router.Use(BasicAuthForProxy(accounts, ""))
router.Any("/*proxyPath", func(c *Context) {
called = true
c.String(http.StatusOK, c.MustGet(AuthProxyUserKey).(string))
})
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("admin:password")))
router.ServeHTTP(w, req)
assert.False(t, called)
assert.Equal(t, http.StatusProxyAuthRequired, w.Code)
assert.Equal(t, "Basic realm=\"Proxy Authorization Required\"", w.Header().Get("Proxy-Authenticate"))
}

View File

@ -124,11 +124,9 @@ func (c *Context) Copy() *Context {
cKeys := c.Keys
cp.Keys = make(map[string]any, len(cKeys))
c.mu.RLock()
for k, v := range cKeys {
cp.Keys[k] = v
}
c.mu.RUnlock()
cParams := c.Params
cp.Params = make([]Param, len(cParams))
@ -393,7 +391,7 @@ func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string)
//
// router.GET("/user/:id", func(c *gin.Context) {
// // a GET request to /user/john
// id := c.Param("id") // id == "john"
// id := c.Param("id") // id == "/john"
// // a GET request to /user/john/
// id := c.Param("id") // id == "/john/"
// })
@ -880,9 +878,6 @@ func (c *Context) GetHeader(key string) string {
// GetRawData returns stream data.
func (c *Context) GetRawData() ([]byte, error) {
if c.Request.Body == nil {
return nil, errors.New("cannot read nil body")
}
return io.ReadAll(c.Request.Body)
}

View File

@ -1000,7 +1000,7 @@ func TestContextRenderFile(t *testing.T) {
c.File("./gin.go")
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), "func New(opts ...OptionFunc) *Engine {")
assert.Contains(t, w.Body.String(), "func New() *Engine {")
// Content-Type='text/plain; charset=utf-8' when go version <= 1.16,
// else, Content-Type='text/x-go; charset=utf-8'
assert.NotEqual(t, "", w.Header().Get("Content-Type"))
@ -1014,7 +1014,7 @@ func TestContextRenderFileFromFS(t *testing.T) {
c.FileFromFS("./gin.go", Dir(".", false))
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), "func New(opts ...OptionFunc) *Engine {")
assert.Contains(t, w.Body.String(), "func New() *Engine {")
// Content-Type='text/plain; charset=utf-8' when go version <= 1.16,
// else, Content-Type='text/x-go; charset=utf-8'
assert.NotEqual(t, "", w.Header().Get("Content-Type"))
@ -1030,7 +1030,7 @@ func TestContextRenderAttachment(t *testing.T) {
c.FileAttachment("./gin.go", newFilename)
assert.Equal(t, 200, w.Code)
assert.Contains(t, w.Body.String(), "func New(opts ...OptionFunc) *Engine {")
assert.Contains(t, w.Body.String(), "func New() *Engine {")
assert.Equal(t, fmt.Sprintf("attachment; filename=\"%s\"", newFilename), w.Header().Get("Content-Disposition"))
}
@ -1057,7 +1057,7 @@ func TestContextRenderUTF8Attachment(t *testing.T) {
c.FileAttachment("./gin.go", newFilename)
assert.Equal(t, 200, w.Code)
assert.Contains(t, w.Body.String(), "func New(opts ...OptionFunc) *Engine {")
assert.Contains(t, w.Body.String(), "func New() *Engine {")
assert.Equal(t, `attachment; filename*=UTF-8''`+url.QueryEscape(newFilename), w.Header().Get("Content-Disposition"))
}

View File

@ -23,9 +23,6 @@ func IsDebugging() bool {
// DebugPrintRouteFunc indicates debug log output format.
var DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string, nuHandlers int)
// DebugPrintFunc indicates debug log output format.
var DebugPrintFunc func(format string, values ...interface{})
func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
if IsDebugging() {
nuHandlers := len(handlers)
@ -51,19 +48,12 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
}
func debugPrint(format string, values ...any) {
if !IsDebugging() {
return
if IsDebugging() {
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
fmt.Fprintf(DefaultWriter, "[GIN-debug] "+format, values...)
}
if DebugPrintFunc != nil {
DebugPrintFunc(format, values...)
return
}
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
fmt.Fprintf(DefaultWriter, "[GIN-debug] "+format, values...)
}
func getMinVer(v string) (uint64, error) {

20
gin.go
View File

@ -47,9 +47,6 @@ var regRemoveRepeatedChar = regexp.MustCompile("/{2,}")
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
// OptionFunc defines the function to change the default configuration
type OptionFunc func(*Engine)
// HandlersChain defines a HandlerFunc slice.
type HandlersChain []HandlerFunc
@ -185,7 +182,7 @@ var _ IRouter = (*Engine)(nil)
// - ForwardedByClientIP: true
// - UseRawPath: false
// - UnescapePathValues: true
func New(opts ...OptionFunc) *Engine {
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
@ -214,15 +211,15 @@ func New(opts ...OptionFunc) *Engine {
engine.pool.New = func() any {
return engine.allocateContext(engine.maxParams)
}
return engine.With(opts...)
return engine
}
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default(opts ...OptionFunc) *Engine {
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine.With(opts...)
return engine
}
func (engine *Engine) Handler() http.Handler {
@ -316,15 +313,6 @@ func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
return engine
}
// With returns a new Engine instance with the provided options.
func (engine *Engine) With(opts ...OptionFunc) *Engine {
for _, opt := range opts {
opt(engine)
}
return engine
}
func (engine *Engine) rebuild404Handlers() {
engine.allNoRoute = engine.combineHandlers(engine.noRoute)
}

View File

@ -696,37 +696,3 @@ func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo)
func handlerTest1(c *Context) {}
func handlerTest2(c *Context) {}
func TestNewOptionFunc(t *testing.T) {
var fc = func(e *Engine) {
e.GET("/test1", handlerTest1)
e.GET("/test2", handlerTest2)
e.Use(func(c *Context) {
c.Next()
})
}
r := New(fc)
routes := r.Routes()
assertRoutePresent(t, routes, RouteInfo{Path: "/test1", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest1"})
assertRoutePresent(t, routes, RouteInfo{Path: "/test2", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest2"})
}
func TestWithOptionFunc(t *testing.T) {
r := New()
r.With(func(e *Engine) {
e.GET("/test1", handlerTest1)
e.GET("/test2", handlerTest2)
e.Use(func(c *Context) {
c.Next()
})
})
routes := r.Routes()
assertRoutePresent(t, routes, RouteInfo{Path: "/test1", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest1"})
assertRoutePresent(t, routes, RouteInfo{Path: "/test2", Method: "GET", Handler: "github.com/gin-gonic/gin.handlerTest2"})
}