mirror of
https://github.com/kataras/iris.git
synced 2025-02-09 02:34:55 +01:00
Implement a GetURI to get the full uri of a (named) route
This commit is contained in:
parent
79e984146e
commit
05b6723b19
|
@ -100,6 +100,7 @@ type (
|
||||||
// SetHeader sets the response headers first parameter is the key, second is the value
|
// SetHeader sets the response headers first parameter is the key, second is the value
|
||||||
SetHeader(string, string)
|
SetHeader(string, string)
|
||||||
Redirect(string, ...int)
|
Redirect(string, ...int)
|
||||||
|
RedirectTo(routeName string, args ...interface{})
|
||||||
// Errors
|
// Errors
|
||||||
NotFound()
|
NotFound()
|
||||||
Panic()
|
Panic()
|
||||||
|
|
|
@ -13,9 +13,9 @@ func (ctx *Context) SetHeader(k string, v string) {
|
||||||
// Redirect redirect sends a redirect response the client
|
// Redirect redirect sends a redirect response the client
|
||||||
// accepts 2 parameters string and an optional int
|
// accepts 2 parameters string and an optional int
|
||||||
// first parameter is the url to redirect
|
// first parameter is the url to redirect
|
||||||
// second parameter is the http status should send, default is 302 (Temporary redirect), you can set it to 301 (Permant redirect), if that's nessecery
|
// second parameter is the http status should send, default is 307 (Temporary redirect), you can set it to 301 (Permant redirect), if that's nessecery
|
||||||
func (ctx *Context) Redirect(urlToRedirect string, statusHeader ...int) {
|
func (ctx *Context) Redirect(urlToRedirect string, statusHeader ...int) {
|
||||||
httpStatus := 302 // temporary redirect
|
httpStatus := StatusTemporaryRedirect // temporary redirect
|
||||||
if statusHeader != nil && len(statusHeader) > 0 && statusHeader[0] > 0 {
|
if statusHeader != nil && len(statusHeader) > 0 && statusHeader[0] > 0 {
|
||||||
httpStatus = statusHeader[0]
|
httpStatus = statusHeader[0]
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,15 @@ func (ctx *Context) Redirect(urlToRedirect string, statusHeader ...int) {
|
||||||
ctx.StopExecution()
|
ctx.StopExecution()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RedirectTo does the same thing as Redirect but instead of receiving a uri or path it receives a route name
|
||||||
|
func (ctx *Context) RedirectTo(routeName string, args ...interface{}) {
|
||||||
|
s, ok := ctx.station.RouteByName(routeName).Parse(args...)
|
||||||
|
if ok {
|
||||||
|
ctx.Redirect(s, StatusTemporaryRedirect)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
|
|
||||||
// NotFound emits an error 404 to the client, using the custom http errors
|
// NotFound emits an error 404 to the client, using the custom http errors
|
||||||
|
|
3
iris.go
3
iris.go
|
@ -247,6 +247,9 @@ func (s *Iris) PreListen(opt config.Server) *server.Server {
|
||||||
func (s *Iris) PostListen() {
|
func (s *Iris) PostListen() {
|
||||||
//if not error opening the server, then:
|
//if not error opening the server, then:
|
||||||
|
|
||||||
|
// prepare the route actions, these actions needs real server's access because that it's after server's listen
|
||||||
|
s.router.optimizeLookups()
|
||||||
|
|
||||||
//set the rest (for Data, Text, JSON, JSONP, XML)
|
//set the rest (for Data, Text, JSON, JSONP, XML)
|
||||||
s.rest = rest.New(s.config.Render.Rest)
|
s.rest = rest.New(s.config.Render.Rest)
|
||||||
// set the templates
|
// set the templates
|
||||||
|
|
37
route.go
37
route.go
|
@ -18,9 +18,18 @@ type (
|
||||||
Name(string) IRoute
|
Name(string) IRoute
|
||||||
GetMiddleware() Middleware
|
GetMiddleware() Middleware
|
||||||
HasCors() bool
|
HasCors() bool
|
||||||
|
// internal methods
|
||||||
|
setTLS(bool)
|
||||||
|
setHost(string)
|
||||||
|
//
|
||||||
|
|
||||||
// used to check arguments with the route's named parameters and return the correct url
|
// used to check arguments with the route's named parameters and return the correct url
|
||||||
// second parameter is false when the action cannot be done
|
// second parameter is false when the action cannot be done
|
||||||
Parse(...interface{}) (string, bool)
|
Parse(...interface{}) (string, bool)
|
||||||
|
|
||||||
|
// GetURI returns the GetDomain() + Parse(...optional named parameters if route is dynamic)
|
||||||
|
// instead of Parse it just returns an empty string if path parse is failed
|
||||||
|
GetURI(...interface{}) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouteNameFunc is returned to from route handle
|
// RouteNameFunc is returned to from route handle
|
||||||
|
@ -34,7 +43,10 @@ type (
|
||||||
// the name of the route, the default name is just the registed path.
|
// the name of the route, the default name is just the registed path.
|
||||||
name string
|
name string
|
||||||
middleware Middleware
|
middleware Middleware
|
||||||
|
// if true then https://
|
||||||
|
isTLS bool
|
||||||
|
// the real host
|
||||||
|
host string
|
||||||
// this is used to convert /mypath/:aparam/:something to -> /mypath/%v/%v and /mypath/* -> mypath/%v
|
// this is used to convert /mypath/:aparam/:something to -> /mypath/%v/%v and /mypath/* -> mypath/%v
|
||||||
// we use %v to escape from the conversions between strings,booleans and integers.
|
// we use %v to escape from the conversions between strings,booleans and integers.
|
||||||
// used inside custom html template func 'url'
|
// used inside custom html template func 'url'
|
||||||
|
@ -149,6 +161,14 @@ func (r *Route) HasCors() bool {
|
||||||
return RouteConflicts(r, "httpmethod")
|
return RouteConflicts(r, "httpmethod")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Route) setTLS(isSecure bool) {
|
||||||
|
r.isTLS = isSecure
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Route) setHost(s string) {
|
||||||
|
r.host = s
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Route) Parse(args ...interface{}) (string, bool) {
|
func (r *Route) Parse(args ...interface{}) (string, bool) {
|
||||||
// check if arguments are not equal to the named parameters ( : = 1, * = all named parameters split to / ), if this happens then send not found err
|
// check if arguments are not equal to the named parameters ( : = 1, * = all named parameters split to / ), if this happens then send not found err
|
||||||
///TODO: I'm thinking of making an option to disable these checks and just return a result, because they have cost when rendering an html/template, not too big compared to the render action but... we will see
|
///TODO: I'm thinking of making an option to disable these checks and just return a result, because they have cost when rendering an html/template, not too big compared to the render action but... we will see
|
||||||
|
@ -190,6 +210,21 @@ func (r *Route) Parse(args ...interface{}) (string, bool) {
|
||||||
return fmt.Sprintf(r.formattedPath, args...), true
|
return fmt.Sprintf(r.formattedPath, args...), true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Route) GetURI(args ...interface{}) (uri string) {
|
||||||
|
scheme := "http://"
|
||||||
|
if r.isTLS {
|
||||||
|
scheme = "https://"
|
||||||
|
}
|
||||||
|
|
||||||
|
host := r.host
|
||||||
|
if parsedPath, ok := r.Parse(args...); ok {
|
||||||
|
uri = scheme + host + parsedPath
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// RouteConflicts checks for route's middleware conflicts
|
// RouteConflicts checks for route's middleware conflicts
|
||||||
func RouteConflicts(r *Route, with string) bool {
|
func RouteConflicts(r *Route, with string) bool {
|
||||||
for _, h := range r.middleware {
|
for _, h := range r.middleware {
|
||||||
|
|
17
router.go
17
router.go
|
@ -215,6 +215,23 @@ func (r *router) optimize() {
|
||||||
r.optimized = true
|
r.optimized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimizeLookups runs AFTER server's listen
|
||||||
|
func (r *router) optimizeLookups() {
|
||||||
|
// set the isTLS on all routes and the correct full domain (if it's local its empty but we don't want that) ( we don't use Domain because it's used to the tree)
|
||||||
|
listeningHost := r.station.server.Listener().Addr().String()
|
||||||
|
for idx, _ := range r.lookups {
|
||||||
|
theR := r.lookups[idx]
|
||||||
|
theR.setTLS(r.station.server.IsSecure())
|
||||||
|
if theR.GetDomain() == "" { // means local, no subdomain
|
||||||
|
theR.setHost(listeningHost)
|
||||||
|
} else {
|
||||||
|
// it's a subdomain route
|
||||||
|
theR.setHost(theR.GetDomain() + "." + listeningHost)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// notFound internal method, it justs takes the context from pool ( in order to have the custom errors available) and procedure a Not Found 404 error
|
// notFound internal method, it justs takes the context from pool ( in order to have the custom errors available) and procedure a Not Found 404 error
|
||||||
// this is being called when no route was found used on the ServeRequest.
|
// this is being called when no route was found used on the ServeRequest.
|
||||||
func (r *router) notFound(reqCtx *fasthttp.RequestCtx) {
|
func (r *router) notFound(reqCtx *fasthttp.RequestCtx) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user