mirror of
https://github.com/kataras/iris.git
synced 2026-03-06 08:25:59 +00:00
20 days of unstoppable work. Waiting fo go 1.8, I didn't finish yet, some touches remains.
Former-commit-id: ed84f99c89f43fe5e980a8e6d0ee22c186f0e1b9
This commit is contained in:
28
adaptors/gorillamux/LICENSE
Normal file
28
adaptors/gorillamux/LICENSE
Normal file
@@ -0,0 +1,28 @@
|
||||
Copyright (c) 2012 Rodrigo Moraes author of gorillamux.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
103
adaptors/gorillamux/README.md
Normal file
103
adaptors/gorillamux/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
## Package information
|
||||
|
||||
Gorillamux is a plugin for Iris which overrides the Iris' default router with the [Gorilla Mux](https://github.com/gorilla/mux)
|
||||
which enables path matching using custom `regexp` ( thing that the Iris' default router doesn't supports for performance reasons).
|
||||
|
||||
All these without need to change any of your existing Iris code. All features are supported.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ go get -u github.com/iris-contrib/plugin/gorillamux
|
||||
```
|
||||
|
||||
|
||||
```go
|
||||
iris.Plugins.Add(gorillamux.New())
|
||||
```
|
||||
|
||||
## [Example](https://github.com/iris-contrib/examples/tree/master/plugin_gorillamux)
|
||||
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/iris-contrib/plugin/gorillamux"
|
||||
"github.com/kataras/iris"
|
||||
)
|
||||
|
||||
func main() {
|
||||
iris.Plugins.Add(gorillamux.New())
|
||||
|
||||
// CUSTOM HTTP ERRORS ARE SUPPORTED
|
||||
// NOTE: Gorilla mux allows customization only on StatusNotFound(404)
|
||||
// Iris allows for everything, so you can register any other custom http error
|
||||
// but you have to call it manually from ctx.EmitError(status_code) // 500 for example
|
||||
// this will work because it's StatusNotFound:
|
||||
iris.Default.OnError(iris.StatusNotFound, func(ctx *iris.Context) {
|
||||
ctx.HTML(iris.StatusNotFound, "<h1> CUSTOM NOT FOUND ERROR PAGE </h1>")
|
||||
})
|
||||
|
||||
// GLOBAL/PARTY MIDDLEWARE ARE SUPPORTED
|
||||
iris.Default.UseFunc(func(ctx *iris.Context) {
|
||||
println("Request: " + ctx.Path())
|
||||
ctx.Next()
|
||||
})
|
||||
|
||||
// http://mydomain.com
|
||||
iris.Default.Get("/", func(ctx *iris.Context) {
|
||||
ctx.Writef("Hello from index")
|
||||
})
|
||||
|
||||
/// -------------------------------------- IMPORTANT --------------------------------------
|
||||
/// GORILLA MUX PARAMETERS(regexp) ARE SUPPORTED
|
||||
/// http://mydomain.com/api/users/42
|
||||
/// ---------------------------------------------------------------------------------------
|
||||
iris.Default.Get("/api/users/{userid:[0-9]+}", func(ctx *iris.Context) {
|
||||
ctx.Writef("User with id: %s", ctx.Param("userid"))
|
||||
})
|
||||
|
||||
// PER-ROUTE MIDDLEWARE ARE SUPPORTED
|
||||
// http://mydomain.com/other
|
||||
iris.Default.Get("/other", func(ctx *iris.Context) {
|
||||
ctx.Writef("/other 1 middleware \n")
|
||||
ctx.Next()
|
||||
}, func(ctx *iris.Context) {
|
||||
ctx.HTML(iris.StatusOK, "<b>Hello from /other</b>")
|
||||
})
|
||||
|
||||
// SUBDOMAINS ARE SUPPORTED
|
||||
// http://admin.mydomain.com
|
||||
iris.Default.Party("admin.").Get("/", func(ctx *iris.Context) {
|
||||
ctx.Writef("Hello from admin. subdomain!")
|
||||
})
|
||||
|
||||
// WILDCARD SUBDOMAINS ARE SUPPORTED
|
||||
// http://api.mydomain.com/hi
|
||||
// http://admin.mydomain.com/hi
|
||||
// http://x.mydomain.com/hi
|
||||
// [depends on your host configuration,
|
||||
// you will see an example(win) outside of this folder].
|
||||
iris.Default.Party("*.").Get("/hi", func(ctx *iris.Context) {
|
||||
ctx.Writef("Hello from wildcard subdomain: %s", ctx.Subdomain())
|
||||
})
|
||||
|
||||
// DOMAIN NAMING IS SUPPORTED
|
||||
iris.Default.Listen("mydomain.com")
|
||||
// iris.Default.Listen(":80")
|
||||
}
|
||||
|
||||
/* HOSTS FILE LINES TO RUN THIS EXAMPLE:
|
||||
|
||||
127.0.0.1 mydomain.com
|
||||
127.0.0.1 admin.mydomain.com
|
||||
127.0.0.1 api.mydomain.com
|
||||
127.0.0.1 x.mydomain.com
|
||||
|
||||
*/
|
||||
|
||||
|
||||
```
|
||||
|
||||
> Custom domain is totally optionally, you can still use `iris.Default.Listen(":8080")` of course.
|
||||
150
adaptors/gorillamux/gorillamux.go
Normal file
150
adaptors/gorillamux/gorillamux.go
Normal file
@@ -0,0 +1,150 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user