mirror of
https://github.com/kataras/iris.git
synced 2025-01-24 11:11:03 +01:00
244a59e055
Former-commit-id: ed84f99c89f43fe5e980a8e6d0ee22c186f0e1b9
151 lines
4.3 KiB
Go
151 lines
4.3 KiB
Go
package gorillamux
|
|
|
|
// +------------------------------------------------------------+
|
|
// | Usage |
|
|
// +------------------------------------------------------------+
|
|
//
|
|
//
|
|
// package main
|
|
//
|
|
// import (
|
|
// "gopkg.in/kataras/iris.v6/adaptors/gorillamux"
|
|
// "gopkg.in/kataras/iris.v6"
|
|
// )
|
|
//
|
|
// func main() {
|
|
// app := iris.New()
|
|
//
|
|
// app.Adapt(gorillamux.New()) // Add this line and you're ready.
|
|
//
|
|
// app.Get("/api/users/{userid:[0-9]+}", func(ctx *iris.Context) {
|
|
// ctx.Writef("User with id: %s", ctx.Param("userid"))
|
|
// })
|
|
//
|
|
// app.Listen(":8080")
|
|
// }
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gorilla/mux"
|
|
"gopkg.in/kataras/iris.v6"
|
|
)
|
|
|
|
const dynamicSymbol = '{'
|
|
|
|
// New returns a new gorilla mux router which can be plugged inside iris.
|
|
// This is magic.
|
|
func New() iris.Policies {
|
|
router := mux.NewRouter()
|
|
var logger func(iris.LogMode, string)
|
|
return iris.Policies{
|
|
EventPolicy: iris.EventPolicy{Boot: func(s *iris.Framework) {
|
|
logger = s.Log
|
|
}},
|
|
RouterReversionPolicy: iris.RouterReversionPolicy{
|
|
// path normalization done on iris' side
|
|
StaticPath: func(path string) string {
|
|
i := strings.IndexByte(path, dynamicSymbol)
|
|
if i > -1 {
|
|
return path[0:i]
|
|
}
|
|
|
|
return path
|
|
},
|
|
WildcardPath: func(requestPath string, paramName string) string {
|
|
return requestPath + "/{" + paramName + ":.*}"
|
|
},
|
|
// Note: on gorilla mux the {{ url }} and {{ path}} should give the key and the value, not only the values by order.
|
|
// {{ url "nameOfTheRoute" "parameterName" "parameterValue"}}.
|
|
//
|
|
// so: {{ url "providerLink" "facebook"}} should become
|
|
// {{ url "providerLink" "provider" "facebook"}}
|
|
// for a path: "/auth/{provider}" with name 'providerLink'
|
|
URLPath: func(r iris.RouteInfo, args ...string) string {
|
|
if r == nil {
|
|
return ""
|
|
}
|
|
if gr := router.Get(r.Name()); gr != nil {
|
|
u, err := gr.URLPath(args...)
|
|
if err != nil {
|
|
logger(iris.DevMode, "error on gorilla mux adaptor's URLPath(reverse routing): "+err.Error())
|
|
return ""
|
|
}
|
|
return u.Path
|
|
}
|
|
return ""
|
|
},
|
|
RouteContextLinker: func(r iris.RouteInfo, ctx *iris.Context) {
|
|
if r == nil {
|
|
return
|
|
}
|
|
route := router.Get(r.Name())
|
|
if route != nil {
|
|
mapToContext(ctx.Request, r.Middleware(), ctx)
|
|
}
|
|
},
|
|
},
|
|
RouterBuilderPolicy: func(repo iris.RouteRepository, context iris.ContextPool) http.Handler {
|
|
repo.Visit(func(route iris.RouteInfo) {
|
|
registerRoute(route, router, context)
|
|
})
|
|
|
|
router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := context.Acquire(w, r)
|
|
// to catch custom 404 not found http errors may registered by user
|
|
ctx.EmitError(iris.StatusNotFound)
|
|
context.Release(ctx)
|
|
})
|
|
return router
|
|
},
|
|
}
|
|
}
|
|
|
|
func mapToContext(r *http.Request, middleware iris.Middleware, ctx *iris.Context) {
|
|
if params := mux.Vars(r); len(params) > 0 {
|
|
// set them with ctx.Set in order to be accesible by ctx.Param in the user's handler
|
|
for k, v := range params {
|
|
ctx.Set(k, v)
|
|
}
|
|
}
|
|
// including the iris.Default.Use/UseFunc and the route's middleware,
|
|
// main handler and any done handlers.
|
|
ctx.Middleware = middleware
|
|
}
|
|
|
|
// so easy:
|
|
func registerRoute(route iris.RouteInfo, gorillaRouter *mux.Router, context iris.ContextPool) {
|
|
if route.IsOnline() {
|
|
handler := func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := context.Acquire(w, r)
|
|
|
|
mapToContext(r, route.Middleware(), ctx)
|
|
ctx.Do()
|
|
|
|
context.Release(ctx)
|
|
}
|
|
|
|
// remember, we get a new iris.Route foreach of the HTTP Methods, so this should be work
|
|
methods := []string{route.Method()}
|
|
// if route has cors then we register the route with the "OPTIONS" method too
|
|
if route.HasCors() {
|
|
methods = append(methods, http.MethodOptions)
|
|
}
|
|
gorillaRoute := gorillaRouter.HandleFunc(route.Path(), handler).Methods(methods...).Name(route.Name())
|
|
|
|
subdomain := route.Subdomain()
|
|
if subdomain != "" {
|
|
if subdomain == "*." {
|
|
// it's an iris wildcard subdomain
|
|
// so register it as wildcard on gorilla mux too (hopefuly, it supports these things)
|
|
subdomain = "{subdomain}."
|
|
} else {
|
|
// it's a static subdomain (which contains the dot)
|
|
}
|
|
// host = subdomain + listening host
|
|
gorillaRoute.Host(subdomain + context.Framework().Config.VHost)
|
|
}
|
|
}
|
|
}
|