diff --git a/benchmarks_test.go b/benchmarks_test.go index 196880c..26a5c93 100644 --- a/benchmarks_test.go +++ b/benchmarks_test.go @@ -68,6 +68,23 @@ func BenchmarkOneRouteSet(B *testing.B) { runRequest("BenchmarkOneRouteSet", B, app, "GET", "/ping") } +func BenchmarkLocalDo(B *testing.B) { + app := New() + app.GET("/ping", func(c *Context) IResponse { + c.Set("key", "value") + return &Response{Status: 200} + }) + req, err := http.NewRequest(http.MethodGet, "/ping", nil) + if err != nil { + panic(err) + } + B.ReportAllocs() + B.ResetTimer() + for i := 0; i < B.N; i++ { + app.LocalDo(req) + } +} + func BenchmarkOneRouteString(B *testing.B) { app := New() app.GET("/text", func(c *Context) IResponse { diff --git a/just.go b/just.go index f37dc52..08b1bbc 100644 --- a/just.go +++ b/just.go @@ -14,7 +14,7 @@ import ( ) const ( - Version = "v0.1.12" + Version = "v0.1.14" DebugEnvName = "JUST_DEBUG_MODE" ) @@ -33,6 +33,8 @@ type IApplication interface { SerializerManager() ISerializerManager TemplatingManager() ITemplatingManager + LocalDo(req *http.Request) IResponse + SetProfiler(p IProfiler) IApplication SetTranslator(t ITranslator) IApplication SetNoRouteHandler(handler HandlerFunc) IApplication @@ -148,7 +150,7 @@ func (app *application) handleHttpRequest(w http.ResponseWriter, c *Context) { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) if app.profiler != nil { - app.profiler.Error(errors.New("Invalid response, recover panic!")) + app.profiler.Error(errors.New("invalid response, recover panic")) } } }() @@ -203,6 +205,33 @@ func (app *application) handleHttpRequest(w http.ResponseWriter, c *Context) { } } +// Локальный вызов запроса внутри движка +func (app *application) LocalDo(req *http.Request) IResponse { + if req == nil { + return nil + } + c := app.pool.Get().(*Context).reset() + defer app.pool.Put(c) + + c.Request, c.IsFrozenRequestBody = req, true + + httpMethod, path := c.Request.Method, c.Request.URL.Path + if app.checkMethodForHaveBody(httpMethod) && c.Request.Body != nil { + if b, _ := ioutil.ReadAll(c.Request.Body); len(b) > 0 { + c.Request.Body.Close() + c.Request.Body = ioutil.NopCloser(bytes.NewReader(b)) + } + } + defer func() { + if rvr := recover(); rvr != nil { + fmt.Fprintf(os.Stderr, "Panic: %+v\n", rvr) + debug.PrintStack() + } + }() + response, _ := app.handleRouter(&app.Router, httpMethod, path, c) + return response +} + func (app *application) handleRouter(router *Router, httpMethod, path string, c *Context) (IResponse, bool) { if router != nil { // Поиск роута