1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-18 17:35:57 +00:00

add Party.HandleServer and macro.IsMacro methods

This commit is contained in:
Gerasimos (Makis) Maropoulos
2023-12-06 01:09:43 +02:00
parent 6e8228596d
commit 7d540f580d
6 changed files with 121 additions and 2 deletions

View File

@@ -1540,6 +1540,83 @@ func (api *APIBuilder) Any(relativePath string, handlers ...context.Handler) (ro
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 {
api.Head(reqPath, h)
return api.Get(reqPath, h)

View File

@@ -393,6 +393,17 @@ type Party interface {
// Connect
// Trace
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.
// It does NOT registers the route. Use `Handle, Get...` methods instead.
// This method can be used for third-parties Iris helpers packages and tools

View File

@@ -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://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)
}