mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
add Party.HandleServer and macro.IsMacro methods
This commit is contained in:
parent
6e8228596d
commit
7d540f580d
|
@ -1540,6 +1540,83 @@ func (api *APIBuilder) Any(relativePath string, handlers ...context.Handler) (ro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
// ServerHandler is the interface which all server handlers should implement.
|
||||||
|
// The Iris Application implements it.
|
||||||
|
// See `Party.HandleServer` method for more.
|
||||||
|
ServerHandler interface {
|
||||||
|
ServeHTTPC(*context.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverBuilder interface {
|
||||||
|
Build() error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandleServer registers a route for all HTTP methods which forwards the requests to the given server.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// app.HandleServer("/api/identity/{first:string}/orgs/{second:string}/{p:path}", otherApp)
|
||||||
|
//
|
||||||
|
// OR
|
||||||
|
//
|
||||||
|
// app.HandleServer("/api/identity", otherApp)
|
||||||
|
func (api *APIBuilder) HandleServer(path string, server ServerHandler) {
|
||||||
|
if app, ok := server.(serverBuilder); ok {
|
||||||
|
// Do an extra check for Build() error at any case
|
||||||
|
// the end-developer didn't call Build before.
|
||||||
|
if err := app.Build(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathParameterName := ""
|
||||||
|
|
||||||
|
// Check and get the last parameter name if it's a wildcard one by the end-developer.
|
||||||
|
parsedPath, err := macro.Parse(path, *api.macros)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n := len(parsedPath.Params); n > 0 {
|
||||||
|
lastParam := parsedPath.Params[n-1]
|
||||||
|
if lastParam.IsMacro(macro.Path) {
|
||||||
|
pathParameterName = lastParam.Name
|
||||||
|
// path remains as it was defined by the end-developer.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
if pathParameterName == "" {
|
||||||
|
pathParameterName = fmt.Sprintf("iris_wildcard_path_parameter%d", len(api.routes.routes))
|
||||||
|
path = fmt.Sprintf("%s/{%s:path}", path, pathParameterName)
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := makeServerHandler(pathParameterName, server.ServeHTTPC)
|
||||||
|
api.Any(path, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeServerHandler(givenPathParameter string, handler context.Handler) context.Handler {
|
||||||
|
return func(ctx *context.Context) {
|
||||||
|
pathValue := ""
|
||||||
|
if givenPathParameter == "" {
|
||||||
|
pathValue = ctx.Params().GetEntryAt(ctx.Params().Len() - 1).ValueRaw.(string)
|
||||||
|
} else {
|
||||||
|
pathValue = ctx.Params().Get(givenPathParameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiPath := "/" + pathValue
|
||||||
|
|
||||||
|
r := ctx.Request()
|
||||||
|
r.URL.Path = apiPath
|
||||||
|
r.URL.RawPath = apiPath
|
||||||
|
ctx.Params().Reset()
|
||||||
|
|
||||||
|
handler(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (api *APIBuilder) registerResourceRoute(reqPath string, h context.Handler) *Route {
|
func (api *APIBuilder) registerResourceRoute(reqPath string, h context.Handler) *Route {
|
||||||
api.Head(reqPath, h)
|
api.Head(reqPath, h)
|
||||||
return api.Get(reqPath, h)
|
return api.Get(reqPath, h)
|
||||||
|
|
|
@ -393,6 +393,17 @@ type Party interface {
|
||||||
// Connect
|
// Connect
|
||||||
// Trace
|
// Trace
|
||||||
Any(registeredPath string, handlers ...context.Handler) []*Route
|
Any(registeredPath string, handlers ...context.Handler) []*Route
|
||||||
|
// HandleServer registers a route for all HTTP methods which forwards the requests to the given server.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// app.HandleServer("/api/identity/{first:string}/orgs/{second:string}/{p:path}", otherApp)
|
||||||
|
//
|
||||||
|
// OR
|
||||||
|
//
|
||||||
|
// app.HandleServer("/api/identity", otherApp)
|
||||||
|
HandleServer(path string, server ServerHandler)
|
||||||
|
|
||||||
// CreateRoutes returns a list of Party-based Routes.
|
// CreateRoutes returns a list of Party-based Routes.
|
||||||
// It does NOT registers the route. Use `Handle, Get...` methods instead.
|
// It does NOT registers the route. Use `Handle, Get...` methods instead.
|
||||||
// This method can be used for third-parties Iris helpers packages and tools
|
// This method can be used for third-parties Iris helpers packages and tools
|
||||||
|
|
|
@ -196,3 +196,24 @@ func TestNewSubdomainPartyRedirectHandler(t *testing.T) {
|
||||||
e.GET("/").WithURL("http://testold.mydomain.com/notfound").Expect().Status(iris.StatusNotFound).Body().IsEqual("test 404")
|
e.GET("/").WithURL("http://testold.mydomain.com/notfound").Expect().Status(iris.StatusNotFound).Body().IsEqual("test 404")
|
||||||
e.GET("/").WithURL("http://leveled.testold.mydomain.com").Expect().Status(iris.StatusOK).Body().IsEqual("leveled.testold this can be fired")
|
e.GET("/").WithURL("http://leveled.testold.mydomain.com").Expect().Status(iris.StatusOK).Body().IsEqual("leveled.testold this can be fired")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleServer(t *testing.T) {
|
||||||
|
otherApp := iris.New()
|
||||||
|
otherApp.Get("/test/me/{first:string}", func(ctx iris.Context) {
|
||||||
|
ctx.HTML("<h1>Other App: %s</h1>", ctx.Params().Get("first"))
|
||||||
|
})
|
||||||
|
otherApp.Build()
|
||||||
|
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
app.Get("/", func(ctx iris.Context) {
|
||||||
|
ctx.HTML("<h1>Main App</h1>")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.HandleServer("/api/identity/{first:string}/orgs/{second:string}/{p:path}", otherApp)
|
||||||
|
|
||||||
|
e := httptest.New(t, app)
|
||||||
|
e.GET("/").Expect().Status(iris.StatusOK).Body().IsEqual("<h1>Main App</h1>")
|
||||||
|
e.GET("/api/identity/first/orgs/second/test/me/kataras").Expect().Status(iris.StatusOK).Body().IsEqual("<h1>Other App: kataras</h1>")
|
||||||
|
e.GET("/api/identity/first/orgs/second/test/me").Expect().Status(iris.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
|
@ -81,8 +81,9 @@ func makeStruct(structPtr interface{}, c *Container, partyParamsCount int) *Stru
|
||||||
singleton := true
|
singleton := true
|
||||||
elem := v.Elem()
|
elem := v.Elem()
|
||||||
|
|
||||||
// fmt.Printf("makeStruct: bindings length = %d\n", len(bindings))
|
// fmt.Printf("Service: %s, Bindings(%d):\n", typ, len(bindings))
|
||||||
for _, b := range bindings {
|
for _, b := range bindings {
|
||||||
|
// fmt.Printf("* " + b.String() + "\n")
|
||||||
if b.Dependency.Static {
|
if b.Dependency.Static {
|
||||||
// Fill now.
|
// Fill now.
|
||||||
input, err := b.Dependency.Handle(nil, b.Input)
|
input, err := b.Dependency.Handle(nil, b.Input)
|
||||||
|
|
2
iris.go
2
iris.go
|
@ -38,7 +38,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version is the current version of the Iris Web Framework.
|
// Version is the current version of the Iris Web Framework.
|
||||||
const Version = "12.2.8"
|
const Version = "12.2.9"
|
||||||
|
|
||||||
// Byte unit helpers.
|
// Byte unit helpers.
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -27,6 +27,8 @@ func (t *Template) IsTrailing() bool {
|
||||||
// TemplateParam is the parsed macro parameter's template
|
// TemplateParam is the parsed macro parameter's template
|
||||||
// they are being used to describe the param's syntax result.
|
// they are being used to describe the param's syntax result.
|
||||||
type TemplateParam struct {
|
type TemplateParam struct {
|
||||||
|
macro *Macro // keep for reference.
|
||||||
|
|
||||||
Src string `json:"src"` // the unparsed param'false source
|
Src string `json:"src"` // the unparsed param'false source
|
||||||
// Type is not useful anywhere here but maybe
|
// Type is not useful anywhere here but maybe
|
||||||
// it's useful on host to decide how to convert the path template to specific router's syntax
|
// it's useful on host to decide how to convert the path template to specific router's syntax
|
||||||
|
@ -117,6 +119,11 @@ func (p *TemplateParam) Eval(paramValue string) (interface{}, bool) {
|
||||||
return newValue, true
|
return newValue, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMacro reports whether this TemplateParam's underline macro matches the given one.
|
||||||
|
func (p *TemplateParam) IsMacro(macro *Macro) bool {
|
||||||
|
return p.macro == macro
|
||||||
|
}
|
||||||
|
|
||||||
// Parse takes a full route path and a macro map (macro map contains the macro types with their registered param functions)
|
// Parse takes a full route path and a macro map (macro map contains the macro types with their registered param functions)
|
||||||
// and returns a new Template.
|
// and returns a new Template.
|
||||||
// It builds all the parameter functions for that template
|
// It builds all the parameter functions for that template
|
||||||
|
@ -138,6 +145,8 @@ func Parse(src string, macros Macros) (Template, error) {
|
||||||
typEval := m.Evaluator
|
typEval := m.Evaluator
|
||||||
|
|
||||||
tmplParam := TemplateParam{
|
tmplParam := TemplateParam{
|
||||||
|
macro: m,
|
||||||
|
|
||||||
Src: p.Src,
|
Src: p.Src,
|
||||||
Type: p.Type,
|
Type: p.Type,
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user