mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
Wildcard subdomain full support | v3.0.0-beta.2
Update to v3.0.0-beta.2. Wildcard subdomain e-book section: https://kataras.gitbooks.io/iris/content/subdomains.html
This commit is contained in:
parent
b4612dcfe0
commit
1a433e34d5
|
@ -6,7 +6,7 @@
|
|||
[Travis]: http://travis-ci.org/kataras/iris
|
||||
[License Widget]: https://img.shields.io/badge/license-Apache%20License%202.0-E91E63.svg?style=flat-square
|
||||
[License]: https://github.com/kataras/iris/blob/master/LICENSE
|
||||
[Release Widget]: https://img.shields.io/badge/release-v3.0.0--beta-blue.svg?style=flat-square
|
||||
[Release Widget]: https://img.shields.io/badge/release-v3.0.0--beta.2-blue.svg?style=flat-square
|
||||
[Release]: https://github.com/kataras/iris/releases
|
||||
[Gitter Widget]: https://img.shields.io/badge/chat-on%20gitter-00BCD4.svg?style=flat-square
|
||||
[Gitter]: https://gitter.im/kataras/iris
|
||||
|
@ -116,7 +116,7 @@ Iris suggests you to use [this](https://github.com/gavv/httpexpect) new suite t
|
|||
Versioning
|
||||
------------
|
||||
|
||||
Current: **v3.0.0-beta.1**
|
||||
Current: **v3.0.0-beta.2**
|
||||
> Iris is an active project
|
||||
|
||||
|
||||
|
@ -131,11 +131,13 @@ Todo
|
|||
------------
|
||||
> for the next release 'v3'
|
||||
|
||||
- [x] [Dynamic/Wildcard subdomains](https://kataras.gitbooks.io/iris/content/subdomains.html).
|
||||
- [x] Create server & client side (js) library for .on('event', func action(...)) / .emit('event')... (like socket.io but supports only websocket).
|
||||
- [x] Find and provide support for the most stable template engine and be able to change it via the configuration, keep html/templates support.
|
||||
- [x] Extend, test and publish to the public the [Iris' cmd](https://github.com/kataras/iris/tree/master/iris).
|
||||
- [x] Route naming and html url func, requested [here](https://github.com/kataras/iris/issues/165).
|
||||
|
||||
|
||||
If you're willing to donate click [here](DONATIONS.md)
|
||||
|
||||
People
|
||||
|
|
|
@ -55,6 +55,8 @@ type (
|
|||
sessionStore store.IStore
|
||||
// pos is the position number of the Context, look .Next to understand
|
||||
pos uint8
|
||||
// subdomain the subdomain (taken from the host), this is empty until GetSubdomain called
|
||||
subdomain string
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ type (
|
|||
RemoteAddr() string
|
||||
RequestHeader(k string) string
|
||||
PostFormValue(string) string
|
||||
GetSubdomain() string
|
||||
}
|
||||
|
||||
// IContextResponse is part of the IContext
|
||||
|
|
|
@ -95,6 +95,20 @@ func (ctx *Context) PostFormValue(name string) string {
|
|||
return string(ctx.RequestCtx.PostArgs().Peek(name))
|
||||
}
|
||||
|
||||
// GetSubdomain returns the subdomain if any, else empty string
|
||||
func (ctx *Context) GetSubdomain() string {
|
||||
if ctx.subdomain == "" {
|
||||
host := ctx.HostString()
|
||||
if index := strings.IndexByte(host, '.'); index > 0 {
|
||||
subdomain := host[0:index]
|
||||
ctx.subdomain = subdomain
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.subdomain
|
||||
|
||||
}
|
||||
|
||||
// URLEncode returns the path encoded as url
|
||||
// useful when you want to pass something to a database and be valid to retrieve it via context.Param
|
||||
// use it only for special cases, when the default behavior doesn't suits you.
|
||||
|
|
4
iris.go
4
iris.go
|
@ -1,4 +1,4 @@
|
|||
// Package iris v3.0.0-beta.1
|
||||
// Package iris v3.0.0-beta.2
|
||||
//
|
||||
// Note: When 'Station', we mean the Iris type.
|
||||
package iris
|
||||
|
@ -31,7 +31,7 @@ import (
|
|||
|
||||
const (
|
||||
// Version of the iris
|
||||
Version = "v3.0.0-beta.1"
|
||||
Version = "v3.0.0-beta.2"
|
||||
banner = ` _____ _
|
||||
|_ _| (_)
|
||||
| | ____ _ ___
|
||||
|
|
|
@ -81,6 +81,18 @@ func HandleFunc(method string, path string, handlersFn ...HandlerFunc) IRoute {
|
|||
return DefaultIris.HandleFunc(method, path, handlersFn...)
|
||||
}
|
||||
|
||||
// Wildcard same as .Party("*.")
|
||||
// registers a route for Dynamic subdomain
|
||||
// receives three parameters
|
||||
// the first is the http method
|
||||
// the second is the request path, can be a dynamic path also like others
|
||||
// the third are the handlerfuncs
|
||||
//
|
||||
// example: subdomains_2
|
||||
func Wildcard(method string, registedPath string, handlersFn ...HandlerFunc) {
|
||||
DefaultIris.Wildcard(method, registedPath, handlersFn...)
|
||||
}
|
||||
|
||||
// API converts & registers a custom struct to the router
|
||||
// receives two parameters
|
||||
// first is the request path (string)
|
||||
|
|
20
party.go
20
party.go
|
@ -21,6 +21,7 @@ type (
|
|||
IParty interface {
|
||||
Handle(string, string, ...Handler) IRoute
|
||||
HandleFunc(string, string, ...HandlerFunc) IRoute
|
||||
Wildcard(string, string, ...HandlerFunc)
|
||||
API(path string, controller HandlerAPI, middlewares ...HandlerFunc) error
|
||||
Get(string, ...HandlerFunc) RouteNameFunc
|
||||
Post(string, ...HandlerFunc) RouteNameFunc
|
||||
|
@ -88,6 +89,20 @@ func (p *GardenParty) HandleFunc(method string, registedPath string, handlersFn
|
|||
return p.Handle(method, registedPath, ConvertToHandlers(handlersFn)...)
|
||||
}
|
||||
|
||||
// Wildcard same as .Party("*.")
|
||||
// registers a route for Dynamic subdomain
|
||||
// receives three parameters
|
||||
// the first is the http method
|
||||
// the second is the request path, can be a dynamic path also like others
|
||||
// the third are the handlerfuncs
|
||||
//
|
||||
// Note that this is just a global route, no party's route.
|
||||
// example: subdomains_2
|
||||
func (p *GardenParty) Wildcard(method string, registedPath string, handlersFn ...HandlerFunc) {
|
||||
path := PrefixDynamicSubdomain + registedPath
|
||||
p.station.router.HandleFunc(method, path, handlersFn...)
|
||||
}
|
||||
|
||||
// API converts & registers a custom struct to the router
|
||||
// receives two parameters
|
||||
// first is the request path (string)
|
||||
|
@ -589,7 +604,10 @@ func (p *GardenParty) StaticContent(reqPath string, contentType string, content
|
|||
func (p *GardenParty) Party(path string, handlersFn ...HandlerFunc) IParty {
|
||||
middleware := ConvertToHandlers(handlersFn)
|
||||
if path[0] != SlashByte && strings.Contains(path, ".") {
|
||||
//it's domain so no handlers share (even the global ) or path, nothing.
|
||||
//it's a domain so no handlers share (even the global ) or path, nothing.
|
||||
if path[0] == MatchEverythingByte { // it's a dynamic subdomain
|
||||
path = PrefixDynamicSubdomain
|
||||
}
|
||||
} else {
|
||||
// set path to parent+child
|
||||
path = absPath(p.relativePath, path)
|
||||
|
|
1
route.go
1
route.go
|
@ -240,6 +240,7 @@ func (r *Route) GetURI(args ...interface{}) (uri string) {
|
|||
}
|
||||
|
||||
host := r.host
|
||||
|
||||
if parsedPath, ok := r.Parse(args...); ok {
|
||||
uri = scheme + host + parsedPath
|
||||
}
|
||||
|
|
35
router.go
35
router.go
|
@ -19,6 +19,8 @@ const (
|
|||
Slash = "/"
|
||||
// MatchEverythingByte is just a byte of '*" rune/char
|
||||
MatchEverythingByte = byte('*')
|
||||
// PrefixDynamicSubdomain is the prefix which dynamic subdomains are registed to, as virtual. Used internaly by Iris but good to know.
|
||||
PrefixDynamicSubdomain = "www.iris_subd0mAin.iris"
|
||||
|
||||
// HTTP Methods(1)
|
||||
|
||||
|
@ -43,6 +45,9 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
// PrefixDynamicSubdomainBytes is the prefix (as []byte) which dynamic subdomains are registed to, as virtual. Used internaly by Iris but good to know.
|
||||
PrefixDynamicSubdomainBytes = []byte(PrefixDynamicSubdomain)
|
||||
|
||||
// HTTP Methods(2)
|
||||
|
||||
// MethodConnectBytes []byte("CONNECT")
|
||||
|
@ -217,6 +222,7 @@ func (r *router) optimize() {
|
|||
|
||||
// optimizeLookups runs AFTER server's listen
|
||||
func (r *router) optimizeLookups() {
|
||||
if r.station.server != nil && r.station.server.IsListening() {
|
||||
// set the isTLS on all routes and the listening full host
|
||||
listeningHost := r.station.server.Listener().Addr().String()
|
||||
for idx := range r.lookups {
|
||||
|
@ -232,6 +238,8 @@ func (r *router) optimizeLookups() {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (r *router) notFound(reqCtx *fasthttp.RequestCtx) {
|
||||
|
@ -271,18 +279,29 @@ func (r *router) serveFunc(reqCtx *fasthttp.RequestCtx) {
|
|||
// If no route found, it sends an http status 404
|
||||
func (r *router) serveDomainFunc(reqCtx *fasthttp.RequestCtx) {
|
||||
method := utils.BytesToString(reqCtx.Method())
|
||||
domain := utils.BytesToString(reqCtx.Host())
|
||||
path := r.getRequestPath(reqCtx)
|
||||
host := utils.BytesToString(reqCtx.Host())
|
||||
fulldomain := ""
|
||||
if strings.Count(host, ".") >= 2 {
|
||||
if portIdx := strings.Index(host, ":"); portIdx != -1 {
|
||||
fulldomain = host[0:portIdx]
|
||||
} else {
|
||||
fulldomain = host
|
||||
}
|
||||
}
|
||||
path := utils.BytesToString(r.getRequestPath(reqCtx))
|
||||
tree := r.garden.first
|
||||
for tree != nil {
|
||||
if tree.hosts && tree.domain == domain {
|
||||
// here we have an issue, at fasthttp/uri.go 273-274 line normalize path it adds a '/' slash at the beginning, it doesn't checks for subdomains
|
||||
// I could fix it but i leave it as it is, I just create a new function inside tree named 'serveReturn' which accepts a path too. ->
|
||||
//-> reqCtx.Request.URI().SetPathBytes(append(reqCtx.Host(), reqCtx.Path()...)) <-
|
||||
path = append(reqCtx.Host(), path...)
|
||||
if tree.hosts && tree.domain != "" && fulldomain != "" {
|
||||
if tree.domain == fulldomain { // it's a static subdomain
|
||||
path = fulldomain + path
|
||||
} else if strings.Index(tree.domain, PrefixDynamicSubdomain) != -1 { // it's a dynamic virtual subdomain
|
||||
path = PrefixDynamicSubdomain + path
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if r.methodMatch(tree.method, method) {
|
||||
if tree.serve(reqCtx, utils.BytesToString(path)) {
|
||||
if tree.serve(reqCtx, path) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user