mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
Ability to change the whole default router
This commit is contained in:
parent
000dfbbee2
commit
131eddb701
|
@ -2,6 +2,10 @@
|
|||
|
||||
**How to upgrade**: remove your `$GOPATH/src/github.com/kataras/iris` folder, open your command-line and execute this command: `go get -u github.com/kataras/iris`.
|
||||
|
||||
## 4.2.6 -> 4.2.7
|
||||
|
||||
- **ADDED**: You are now able to use a raw fasthttp handler as the router instead of the default Iris' one. Example [here](https://github.com/iris-contrib/examples/blob/master/custom_fasthttp_router/main.go). But remember that I'm always recommending to use the Iris' default which supports subdomains, group of routes(parties), auto path correction and many other built'n features. This exists for specific users who told me that they need a feature like that inside Iris, we have no performance cost at all so that's ok to exists.
|
||||
|
||||
## 4.2.5 -> 4.2.6
|
||||
|
||||
- **CHANGE**: Updater (See 4.2.4 and 4.2.3) runs in its own goroutine now, unless the `iris.Config.CheckForUpdatesSync` is true.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<br/>
|
||||
|
||||
|
||||
<a href="https://github.com/kataras/iris/releases"><img src="https://img.shields.io/badge/%20version%20-%204.2.6%20-blue.svg?style=flat-square" alt="Releases"></a>
|
||||
<a href="https://github.com/kataras/iris/releases"><img src="https://img.shields.io/badge/%20version%20-%204.2.7%20-blue.svg?style=flat-square" alt="Releases"></a>
|
||||
|
||||
<a href="https://github.com/iris-contrib/examples"><img src="https://img.shields.io/badge/%20examples-repository-3362c2.svg?style=flat-square" alt="Examples"></a>
|
||||
|
||||
|
@ -181,7 +181,7 @@ I recommend writing your API tests using this new library, [httpexpect](https://
|
|||
Versioning
|
||||
------------
|
||||
|
||||
Current: **v4.2.6**
|
||||
Current: **v4.2.7**
|
||||
|
||||
> Iris is an active project
|
||||
|
||||
|
@ -224,7 +224,7 @@ License can be found [here](LICENSE).
|
|||
[Travis]: http://travis-ci.org/kataras/iris
|
||||
[License Widget]: https://img.shields.io/badge/license-Apache%202.0%20%20-E91E63.svg?style=flat-square
|
||||
[License]: https://github.com/kataras/iris/blob/master/LICENSE
|
||||
[Release Widget]: https://img.shields.io/badge/release-v4.2.6-blue.svg?style=flat-square
|
||||
[Release Widget]: https://img.shields.io/badge/release-v4.2.7-blue.svg?style=flat-square
|
||||
[Release]: https://github.com/kataras/iris/releases
|
||||
[Chat Widget]: https://img.shields.io/badge/community-chat-00BCD4.svg?style=flat-square
|
||||
[Chat]: https://kataras.rocket.chat/channel/iris
|
||||
|
|
|
@ -688,6 +688,7 @@ type ServerConfiguration struct {
|
|||
// for an optional second server with a different port you can always use:
|
||||
// iris.AddServer(iris.ServerConfiguration{ListeningAddr: ":9090", MaxRequestsPerConn:100})
|
||||
MaxRequestsPerConn int
|
||||
|
||||
// RedirectTo, defaults to empty, set it in order to override the station's handler and redirect all requests to this address which is of form(HOST:PORT or :PORT)
|
||||
//
|
||||
// NOTE: the http status is 'StatusMovedPermanently', means one-time-redirect(the browser remembers the new addr and goes to the new address without need to request something from this server
|
||||
|
|
96
http.go
96
http.go
|
@ -48,24 +48,25 @@ var (
|
|||
AllMethods = [...]string{MethodGet, MethodPost, MethodPut, MethodDelete, MethodConnect, MethodHead, MethodPatch, MethodOptions, MethodTrace}
|
||||
|
||||
/* methods as []byte, these are really used by iris */
|
||||
// methodGetBytes "GET"
|
||||
methodGetBytes = []byte(MethodGet)
|
||||
// methodPostBytes "POST"
|
||||
methodPostBytes = []byte(MethodPost)
|
||||
// methodPutBytes "PUT"
|
||||
methodPutBytes = []byte(MethodPut)
|
||||
// methodDeleteBytes "DELETE"
|
||||
methodDeleteBytes = []byte(MethodDelete)
|
||||
// methodConnectBytes "CONNECT"
|
||||
methodConnectBytes = []byte(MethodConnect)
|
||||
// methodHeadBytes "HEAD"
|
||||
methodHeadBytes = []byte(MethodHead)
|
||||
// methodPatchBytes "PATCH"
|
||||
methodPatchBytes = []byte(MethodPatch)
|
||||
// methodOptionsBytes "OPTIONS"
|
||||
methodOptionsBytes = []byte(MethodOptions)
|
||||
// methodTraceBytes "TRACE"
|
||||
methodTraceBytes = []byte(MethodTrace)
|
||||
|
||||
// MethodGetBytes "GET"
|
||||
MethodGetBytes = []byte(MethodGet)
|
||||
// MethodPostBytes "POST"
|
||||
MethodPostBytes = []byte(MethodPost)
|
||||
// MethodPutBytes "PUT"
|
||||
MethodPutBytes = []byte(MethodPut)
|
||||
// MethodDeleteBytes "DELETE"
|
||||
MethodDeleteBytes = []byte(MethodDelete)
|
||||
// MethodConnectBytes "CONNECT"
|
||||
MethodConnectBytes = []byte(MethodConnect)
|
||||
// MethodHeadBytes "HEAD"
|
||||
MethodHeadBytes = []byte(MethodHead)
|
||||
// MethodPatchBytes "PATCH"
|
||||
MethodPatchBytes = []byte(MethodPatch)
|
||||
// MethodOptionsBytes "OPTIONS"
|
||||
MethodOptionsBytes = []byte(MethodOptions)
|
||||
// MethodTraceBytes "TRACE"
|
||||
MethodTraceBytes = []byte(MethodTrace)
|
||||
/* */
|
||||
|
||||
)
|
||||
|
@ -1444,7 +1445,7 @@ func (mux *serveMux) register(method []byte, subdomain string, path string, midd
|
|||
|
||||
// build collects all routes info and adds them to the registry in order to be served from the request handler
|
||||
// this happens once when server is setting the mux's handler.
|
||||
func (mux *serveMux) build() {
|
||||
func (mux *serveMux) build() (func(reqCtx *fasthttp.RequestCtx) string, func([]byte, []byte) bool) {
|
||||
mux.tree = nil
|
||||
sort.Sort(bySubdomain(mux.lookups))
|
||||
for _, r := range mux.lookups {
|
||||
|
@ -1474,6 +1475,31 @@ func (mux *serveMux) build() {
|
|||
mux.logger.Panic(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// optimize this once once, we could do that: context.RequestPath(mux.escapePath), but we lose some nanoseconds on if :)
|
||||
getRequestPath := func(reqCtx *fasthttp.RequestCtx) string {
|
||||
return utils.BytesToString(reqCtx.Path()) //string(ctx.Path()[:]) // a little bit of memory allocation, old method used: BytesToString, If I see the benchmarks get low I will change it back to old, but this way is safer.
|
||||
}
|
||||
|
||||
if !mux.escapePath {
|
||||
getRequestPath = func(reqCtx *fasthttp.RequestCtx) string { return utils.BytesToString(reqCtx.RequestURI()) }
|
||||
}
|
||||
|
||||
methodEqual := func(treeMethod []byte, reqMethod []byte) bool {
|
||||
return bytes.Equal(treeMethod, reqMethod)
|
||||
}
|
||||
// check for cors conflicts
|
||||
for _, r := range mux.lookups {
|
||||
if r.hasCors() {
|
||||
methodEqual = func(treeMethod []byte, reqMethod []byte) bool {
|
||||
return bytes.Equal(treeMethod, reqMethod) || bytes.Equal(reqMethod, MethodOptionsBytes)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return getRequestPath, methodEqual
|
||||
|
||||
}
|
||||
|
||||
func (mux *serveMux) lookup(routeName string) *route {
|
||||
|
@ -1485,34 +1511,14 @@ func (mux *serveMux) lookup(routeName string) *route {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (mux *serveMux) Handler() HandlerFunc {
|
||||
// BuildHandler the default Iris router when iris.Handler is nil
|
||||
func (mux *serveMux) BuildHandler() HandlerFunc {
|
||||
|
||||
// initialize the router once
|
||||
mux.build()
|
||||
// optimize this once once, we could do that: context.RequestPath(mux.escapePath), but we lose some nanoseconds on if :)
|
||||
getRequestPath := func(ctx *Context) string {
|
||||
return utils.BytesToString(ctx.Path()) //string(ctx.Path()[:]) // a little bit of memory allocation, old method used: BytesToString, If I see the benchmarks get low I will change it back to old, but this way is safer.
|
||||
}
|
||||
if !mux.escapePath {
|
||||
getRequestPath = func(ctx *Context) string { return utils.BytesToString(ctx.RequestCtx.RequestURI()) }
|
||||
}
|
||||
|
||||
methodEqual := func(treeMethod []byte, reqMethod []byte) bool {
|
||||
return bytes.Equal(treeMethod, reqMethod)
|
||||
}
|
||||
|
||||
// check for cors conflicts
|
||||
for _, r := range mux.lookups {
|
||||
if r.hasCors() {
|
||||
methodEqual = func(treeMethod []byte, reqMethod []byte) bool {
|
||||
return bytes.Equal(treeMethod, reqMethod) || bytes.Equal(reqMethod, methodOptionsBytes)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
getRequestPath, methodEqual := mux.build()
|
||||
|
||||
return func(context *Context) {
|
||||
routePath := getRequestPath(context)
|
||||
routePath := getRequestPath(context.RequestCtx)
|
||||
tree := mux.tree
|
||||
for tree != nil {
|
||||
if !methodEqual(tree.method, context.Method()) {
|
||||
|
@ -1553,7 +1559,7 @@ func (mux *serveMux) Handler() HandlerFunc {
|
|||
//ctx.Request.Header.SetUserAgentBytes(DefaultUserAgent)
|
||||
context.Do()
|
||||
return
|
||||
} else if mustRedirect && mux.correctPath && !bytes.Equal(context.Method(), methodConnectBytes) {
|
||||
} else if mustRedirect && mux.correctPath && !bytes.Equal(context.Method(), MethodConnectBytes) {
|
||||
|
||||
reqPath := routePath
|
||||
pathLen := len(reqPath)
|
||||
|
@ -1574,7 +1580,7 @@ func (mux *serveMux) Handler() HandlerFunc {
|
|||
// RFC2616 recommends that a short note "SHOULD" be included in the
|
||||
// response because older user agents may not understand 301/307.
|
||||
// Shouldn't send the response for POST or HEAD; that leaves GET.
|
||||
if bytes.Equal(tree.method, methodGetBytes) {
|
||||
if bytes.Equal(tree.method, MethodGetBytes) {
|
||||
note := "<a href=\"" + utils.HTMLEscape(urlToRedirect) + "\">Moved Permanently</a>.\n"
|
||||
context.Write(note)
|
||||
}
|
||||
|
|
52
iris.go
52
iris.go
|
@ -78,7 +78,7 @@ import (
|
|||
|
||||
const (
|
||||
// Version is the current version of the Iris web framework
|
||||
Version = "4.2.6"
|
||||
Version = "4.2.7"
|
||||
|
||||
banner = ` _____ _
|
||||
|_ _| (_)
|
||||
|
@ -167,6 +167,11 @@ type (
|
|||
// Implements the FrameworkAPI
|
||||
Framework struct {
|
||||
*muxAPI
|
||||
// Handler field which can change the default iris' mux behavior
|
||||
// if you want to get benefit with iris' context make use of:
|
||||
// ctx:= iris.AcquireCtx(*fasthttp.RequestCtx) to get the context at the beginning of your handler
|
||||
// iris.ReleaseCtx(ctx) to release/put the context to the pool, at the very end of your custom handler.
|
||||
Handler fasthttp.RequestHandler
|
||||
contextPool sync.Pool
|
||||
Config *Configuration
|
||||
sessions sessions.Sessions
|
||||
|
@ -301,24 +306,47 @@ func Go() error {
|
|||
return Default.Go()
|
||||
}
|
||||
|
||||
// AcquireCtx gets an Iris' Context from pool
|
||||
// see iris.Handler & ReleaseCtx, Go()
|
||||
func (s *Framework) AcquireCtx(reqCtx *fasthttp.RequestCtx) {
|
||||
ctx := s.contextPool.Get().(*Context) // Changed to use the pool's New 09/07/2016, ~ -4k nanoseconds(9 bench tests) per requests (better performance)
|
||||
ctx.RequestCtx = reqCtx
|
||||
}
|
||||
|
||||
// ReleaseCtx puts the Iris' Context back to the pool in order to be re-used
|
||||
// see iris.Handler & AcquireCtx, Go()
|
||||
func (s *Framework) ReleaseCtx(ctx *Context) {
|
||||
ctx.Params = ctx.Params[0:0]
|
||||
ctx.middleware = nil
|
||||
ctx.session = nil
|
||||
s.contextPool.Put(ctx)
|
||||
}
|
||||
|
||||
// Go starts the iris station, listens to all registered servers, and prepare only if Virtual
|
||||
func (s *Framework) Go() error {
|
||||
s.initialize()
|
||||
s.Plugins.DoPreListen(s)
|
||||
// build the fasthttp handler to bind it to the servers
|
||||
h := s.mux.Handler()
|
||||
reqHandler := func(reqCtx *fasthttp.RequestCtx) {
|
||||
ctx := s.contextPool.Get().(*Context) // Changed to use the pool's New 09/07/2016, ~ -4k nanoseconds(9 bench tests) per requests (better performance)
|
||||
ctx.RequestCtx = reqCtx
|
||||
|
||||
h(ctx)
|
||||
if s.Handler == nil { // use the 'h' which is the default mux' handler
|
||||
// build and get the default mux' handler(*Context)
|
||||
serve := s.mux.BuildHandler()
|
||||
// build the fasthttp handler to bind it to the servers
|
||||
defaultHandler := func(reqCtx *fasthttp.RequestCtx) {
|
||||
ctx := s.contextPool.Get().(*Context) // Changed to use the pool's New 09/07/2016, ~ -4k nanoseconds(9 bench tests) per requests (better performance)
|
||||
ctx.RequestCtx = reqCtx
|
||||
|
||||
ctx.Params = ctx.Params[0:0]
|
||||
ctx.middleware = nil
|
||||
ctx.session = nil
|
||||
s.contextPool.Put(ctx)
|
||||
serve(ctx)
|
||||
|
||||
ctx.Params = ctx.Params[0:0]
|
||||
ctx.middleware = nil
|
||||
ctx.session = nil
|
||||
s.contextPool.Put(ctx)
|
||||
}
|
||||
|
||||
s.Handler = defaultHandler
|
||||
}
|
||||
if firstErr := s.Servers.OpenAll(reqHandler); firstErr != nil {
|
||||
|
||||
if firstErr := s.Servers.OpenAll(s.Handler); firstErr != nil {
|
||||
return firstErr
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user