mirror of
https://github.com/kataras/iris.git
synced 2025-12-20 03:17:04 +00:00
20 days of unstoppable work. Waiting fo go 1.8, I didn't finish yet, some touches remains.
Former-commit-id: ed84f99c89f43fe5e980a8e6d0ee22c186f0e1b9
This commit is contained in:
189
router_policy_test.go
Normal file
189
router_policy_test.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package iris_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
. "gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/httptest"
|
||||
)
|
||||
|
||||
// This will be removed at the final release
|
||||
// it's here just for my tests
|
||||
// it will may transfered to the (advanced) examples repository
|
||||
// in order to show the users how they can adapt any third-party router.
|
||||
// They can also view the ./adaptors/httprouter and ./adaptors/gorillamux.
|
||||
func newTestNativeRouter() Policies {
|
||||
fireMethodNotAllowed := false
|
||||
return Policies{
|
||||
EventPolicy: EventPolicy{
|
||||
Boot: func(s *Framework) {
|
||||
fireMethodNotAllowed = s.Config.FireMethodNotAllowed
|
||||
},
|
||||
},
|
||||
RouterReversionPolicy: RouterReversionPolicy{
|
||||
// path normalization done on iris' side
|
||||
StaticPath: func(path string) string { return path },
|
||||
WildcardPath: func(requestPath string, paramName string) string { return requestPath },
|
||||
URLPath: func(r RouteInfo, args ...string) string {
|
||||
if r == nil {
|
||||
return ""
|
||||
}
|
||||
// note:
|
||||
// as we already know, net/http servemux doesn't provides parameterized paths so we will
|
||||
// use the passed args(if any) to build the url query
|
||||
path := r.Path()
|
||||
if len(args) > 0 {
|
||||
if len(args)%2 != 0 {
|
||||
// key=value
|
||||
// so the result of len args should be %2==0.
|
||||
// if not return just the path.
|
||||
return path
|
||||
}
|
||||
path += "?"
|
||||
for i := 0; i < len(args)-1; i++ {
|
||||
path += args[i] + "=" + args[i+1]
|
||||
i++
|
||||
if i != len(args)-1 {
|
||||
path += "&"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return path
|
||||
},
|
||||
RouteContextLinker: func(r RouteInfo, ctx *Context) {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
ctx.Middleware = r.Middleware()
|
||||
},
|
||||
},
|
||||
RouterBuilderPolicy: func(repo RouteRepository, context ContextPool) http.Handler {
|
||||
servemux := http.NewServeMux()
|
||||
noIndexRegistered := true
|
||||
servemux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if noIndexRegistered {
|
||||
context.Run(w, r, func(ctx *Context) {
|
||||
ctx.EmitError(StatusNotFound)
|
||||
})
|
||||
}
|
||||
})
|
||||
repo.Visit(func(route RouteInfo) {
|
||||
path := route.Path()
|
||||
if path == "/" {
|
||||
noIndexRegistered = false // this goes before the handlefunc("/")
|
||||
}
|
||||
if path[len(path)-1] != '/' { // append a slash (net/http works this way)
|
||||
path += "/"
|
||||
repo.ChangePath(route, path)
|
||||
}
|
||||
servemux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.Acquire(w, r)
|
||||
|
||||
if ctx.Method() == route.Method() || ctx.Method() == MethodOptions && route.HasCors() {
|
||||
ctx.Middleware = route.Middleware()
|
||||
recorder := ctx.Recorder()
|
||||
ctx.Do()
|
||||
|
||||
// ok, we can't bypass the net/http server.go's err handlers
|
||||
// we have two options:
|
||||
// - create the mux by ourselve, not an ideal because we already done two of them.
|
||||
// - create a new response writer which will check once if user has registered error handler,if yes write that response instead.
|
||||
// - on "/" path(which net/http fallbacks if no any registered route handler found) make if requested_path != "/" or ""
|
||||
// and emit the 404 error, but for the rest of the custom errors...?
|
||||
// - use our custom context's recorder to record the status code, this will be a bit slower solution(maybe not)
|
||||
// but it covers all our scenarios.
|
||||
|
||||
statusCode := recorder.StatusCode()
|
||||
if statusCode >= 400 { // if we have an error status code try to find a custom error handler
|
||||
errorHandler := ctx.Framework().Errors.Get(statusCode)
|
||||
if errorHandler != nil {
|
||||
// it will reset the response and write its own response by the user's handler
|
||||
errorHandler.Serve(ctx)
|
||||
}
|
||||
}
|
||||
} else if fireMethodNotAllowed {
|
||||
ctx.EmitError(StatusMethodNotAllowed) // fire method not allowed if enabled
|
||||
} else { // else fire not found
|
||||
ctx.EmitError(StatusNotFound)
|
||||
}
|
||||
|
||||
context.Release(ctx)
|
||||
})
|
||||
})
|
||||
|
||||
return servemux
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func h(ctx *Context) {
|
||||
ctx.WriteString("hello from " + ctx.Path())
|
||||
}
|
||||
|
||||
type testNativeRoute struct {
|
||||
method, path, body string
|
||||
status int
|
||||
}
|
||||
|
||||
func TestRouterPolicyAdaptor(t *testing.T) {
|
||||
expectedWrongMethodStatus := StatusNotFound
|
||||
app := New(Configuration{FireMethodNotAllowed: true})
|
||||
app.Adapt(newTestNativeRouter())
|
||||
// 404 or 405
|
||||
if app.Config.FireMethodNotAllowed {
|
||||
expectedWrongMethodStatus = StatusMethodNotAllowed
|
||||
}
|
||||
|
||||
var testRoutes = []testNativeRoute{
|
||||
{"GET", "/hi", "Should be /hi/ \nhello from /hi/", StatusOK},
|
||||
{"GET", "/other", "Should be /other/ \nhello from /other/", StatusOK},
|
||||
{"GET", "/hi/you", "Should be /hi/you/ \nhello from /hi/you/", StatusOK},
|
||||
{"POST", "/hey", "hello from /hey/", StatusOK},
|
||||
{"GET", "/hey", "Method Not Allowed", expectedWrongMethodStatus},
|
||||
{"GET", "/doesntexists", "<b>Custom 404 page</b>", StatusNotFound},
|
||||
}
|
||||
app.OnError(404, func(ctx *Context) {
|
||||
ctx.HTML(404, "<b>Custom 404 page</b>")
|
||||
})
|
||||
|
||||
app.Get("/hi", func(ctx *Context) {
|
||||
ctx.Writef("Should be /hi/ \n")
|
||||
ctx.Next()
|
||||
}, h)
|
||||
|
||||
app.Get("/other", func(ctx *Context) {
|
||||
ctx.Writef("Should be /other/ \n")
|
||||
ctx.Next()
|
||||
}, h)
|
||||
|
||||
app.Get("/hi/you", func(ctx *Context) {
|
||||
ctx.Writef("Should be /hi/you/ \n")
|
||||
ctx.Next()
|
||||
}, h)
|
||||
|
||||
app.Post("/hey", h)
|
||||
|
||||
app.None("/profile", func(ctx *Context) {
|
||||
userid, _ := ctx.URLParamInt("user_id")
|
||||
ref := ctx.URLParam("ref")
|
||||
ctx.Writef("%s\n%d", userid, ref)
|
||||
}).ChangeName("profile")
|
||||
|
||||
e := httptest.New(app, t)
|
||||
expected := "/profile/?user_id=42&ref=iris-go&something=anything"
|
||||
|
||||
if got := app.Path("profile", "user_id", 42, "ref", "iris-go", "something", "anything"); got != expected {
|
||||
t.Fatalf("URLPath expected %s but got %s", expected, got)
|
||||
}
|
||||
|
||||
for _, r := range testRoutes {
|
||||
// post should be passed with ending / here, it's not iris-specific.
|
||||
if r.method == "POST" {
|
||||
r.path += "/"
|
||||
}
|
||||
e.Request(r.method, r.path).Expect().Status(r.status).Body().Equal(r.body).Raw()
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user