diff --git a/HISTORY.md b/HISTORY.md index 084a4911..3a9318a4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,27 @@ **How to upgrade**: remove your `$GOPATH/src/github.com/kataras` folder, open your command-line and execute this command: `go get -u github.com/kataras/iris/iris`. +## 6.0.6 -> 6.0.7 + +- `iris.Config.DisablePathEscape` -> renamed to `iris.Config.EnablePathEscape`, which defaults to false. Path escape is turned off by-default now, +if you're waiting for unescaped path parameters, then just enable it by putting: `iris.Config.EnablePathEscape = true` anywhere in your code OR +use the `context.ParamDecoded` instead of the context.Param when you want to escape a single path parameter. + +- Example for `iris.UsePreRender` https://github.com/iris-contrib/examples/tree/master/template_engines/template_prerender + +## 6.0.5 -> 6.0.6 + +http.Request access from WebsocketConnection. + +Example: + +- https://github.com/iris-contrib/examples/blob/master/websocket/main.go#L34 + +Relative commits to kataras/go-websocket: +- https://github.com/kataras/go-websocket/commit/550fc8b32eb13b3b4a4bfeb227ef1a896c8f8698 + +- https://github.com/kataras/go-websocket/commit/62c2d989d8b5e9126cdbf451c0e41e2e2b0b31b8 + ## 6.0.4 -> 6.0.5 - Add `iris.DestroySessionByID(string)` and `iris.DestroyAllSessions()` functions as requested by a community member in the [chat](https://kataras.rocket.chat/channel/iris) diff --git a/README.md b/README.md index 73d755a6..1dd8b484 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@
-CHANGELOG/HISTORY +CHANGELOG/HISTORY Examples @@ -938,14 +938,14 @@ You can read the full article [here](https://translate.google.com/translate?sl=a Testing ------------ -I recommend writing your API tests using this new library, [httpexpect](https://github.com/gavv/httpexpect). You can find Iris examples [here](https://github.com/kataras/iris/blob/master/vendor/github.com/gavv/httpexpect/_examples/iris_test.go), [here](https://github.com/kataras/iris/blob/master/http_test.go) and [here](https://github.com/kataras/iris/blob/master/context_test.go). +I recommend testing your API using this new library, [httpexpect](https://github.com/gavv/httpexpect). You can find Iris examples [here](https://github.com/gavv/httpexpect/blob/master/_examples/iris_test.go), [here](https://github.com/kataras/iris/blob/master/http_test.go) and [here](https://github.com/kataras/iris/blob/master/context_test.go). Versioning ------------ -Current: **v6.0.6** +Current: **v6.0.7** -Stable: **[v5/fasthttp](https://github.com/kataras/iris/tree/5.0.0)** +Older: **[v5/fasthttp](https://github.com/kataras/iris/tree/5.0.0)** Iris is a **Community-Driven** Project, waiting for your suggestions and [feature requests](https://github.com/kataras/iris/issues?utf8=%E2%9C%93&q=label%3A%22feature%20request%22)! diff --git a/configuration.go b/configuration.go index 26c24109..35075ad6 100644 --- a/configuration.go +++ b/configuration.go @@ -127,10 +127,10 @@ type Configuration struct { // Default is false DisablePathCorrection bool - // DisablePathEscape when is false then its escapes the path, the named parameters (if any). - // Change to true it if you want something like this https://github.com/kataras/iris/issues/135 to work + // EnablePathEscape when is true then its escapes the path, the named parameters (if any). + // Change to false it if you want something like this https://github.com/kataras/iris/issues/135 to work // - // When do you need to Disable(true) it: + // When do you need to Disable(false) it: // accepts parameters with slash '/' // Request: http://localhost:8080/details/Project%2FDelta // ctx.Param("project") returns the raw named parameter: Project%2FDelta @@ -139,7 +139,7 @@ type Configuration struct { // Look here: https://github.com/kataras/iris/issues/135 for more // // Default is false - DisablePathEscape bool + EnablePathEscape bool // FireMethodNotAllowed if it's true router checks for StatusMethodNotAllowed(405) and fires the 405 error instead of 404 // Default is false @@ -325,10 +325,10 @@ var ( } - // OptionDisablePathEscape when is false then its escapes the path, the named parameters (if any). - OptionDisablePathEscape = func(val bool) OptionSet { + // OptionEnablePathEscape when is true then its escapes the path, the named path parameters (if any). + OptionEnablePathEscape = func(val bool) OptionSet { return func(c *Configuration) { - c.DisablePathEscape = val + c.EnablePathEscape = val } } @@ -435,7 +435,7 @@ var ( // Default values for base Iris conf const ( DefaultDisablePathCorrection = false - DefaultDisablePathEscape = false + DefaultEnablePathEscape = false DefaultCharset = "UTF-8" DefaultLoggerPreffix = "[IRIS] " // Per-connection buffer size for requests' reading. @@ -469,7 +469,7 @@ func DefaultConfiguration() Configuration { CheckForUpdates: false, CheckForUpdatesSync: false, DisablePathCorrection: DefaultDisablePathCorrection, - DisablePathEscape: DefaultDisablePathEscape, + EnablePathEscape: DefaultEnablePathEscape, FireMethodNotAllowed: false, DisableBanner: false, LoggerOut: DefaultLoggerOut, diff --git a/context.go b/context.go index 89c87b50..4f762c83 100644 --- a/context.go +++ b/context.go @@ -242,15 +242,15 @@ func (ctx *Context) VirtualHostname() string { // Path returns the full escaped path as string // for unescaped use: ctx.RequestCtx.RequestURI() or RequestPath(escape bool) func (ctx *Context) Path() string { - return ctx.RequestPath(!ctx.framework.Config.DisablePathEscape) + return ctx.RequestPath(ctx.framework.Config.EnablePathEscape) } // RequestPath returns the requested path func (ctx *Context) RequestPath(escape bool) string { if escape { - return ctx.Request.URL.EscapedPath() + return DecodeQuery(ctx.Request.URL.EscapedPath()) } - return ctx.Request.RequestURI + return ctx.Request.URL.Path } // RemoteAddr tries to return the real client's request IP @@ -957,16 +957,16 @@ func (ctx *Context) Set(key string, value interface{}) { // // visitor must not retain references to key and value after returning. // Make key and/or value copies if you need storing them after returning. -func (ctx *Context) VisitValues(visitor func([]byte, interface{})) { +func (ctx *Context) VisitValues(visitor func(string, interface{})) { for i, n := 0, len(ctx.values); i < n; i++ { kv := &ctx.values[i] - visitor(kv.key, kv.value) + visitor(string(kv.key), kv.value) } } // ParamsLen tries to return all the stored values which values are string, probably most of them will be the path parameters func (ctx *Context) ParamsLen() (n int) { - ctx.VisitValues(func(kb []byte, vg interface{}) { + ctx.VisitValues(func(kb string, vg interface{}) { if _, ok := vg.(string); ok { n++ } @@ -1001,7 +1001,7 @@ func (ctx *Context) ParamInt64(key string) (int64, error) { // hasthe form of key1=value1,key2=value2... func (ctx *Context) ParamsSentence() string { var buff bytes.Buffer - ctx.VisitValues(func(kb []byte, vg interface{}) { + ctx.VisitValues(func(kb string, vg interface{}) { v, ok := vg.(string) if !ok { return diff --git a/context_test.go b/context_test.go index f42a2922..cf18cf91 100644 --- a/context_test.go +++ b/context_test.go @@ -127,7 +127,7 @@ func TestContextURLParams(t *testing.T) { params := ctx.URLParams() ctx.JSON(iris.StatusOK, params) }) - e := httptest.New(iris.Default, t) + e := httptest.New(iris.Default, t, httptest.Debug(true)) e.GET("/").WithQueryObject(passedParams).Expect().Status(iris.StatusOK).JSON().Equal(passedParams) } diff --git a/http_test.go b/http_test.go index c6c3e747..c30b1928 100644 --- a/http_test.go +++ b/http_test.go @@ -322,7 +322,7 @@ func TestMuxSimple(t *testing.T) { {"GET", "/test_get_urlparameter2/second", "/test_get_urlparameter2/second", "name=irisurl&something=anything", "name=irisurl,something=anything", 200, true, nil, []param{{"name", "irisurl"}, {"something", "anything"}}}, {"GET", "/test_get_urlparameter2/first/second/third", "/test_get_urlparameter2/first/second/third", "name=irisurl&something=anything&else=elsehere", "name=irisurl,something=anything,else=elsehere", 200, true, nil, []param{{"name", "irisurl"}, {"something", "anything"}, {"else", "elsehere"}}}, } - defer iris.Close() + iris.ResetDefault() for idx := range testRoutes { @@ -353,7 +353,7 @@ func TestMuxSimple(t *testing.T) { } } - e := httptest.New(iris.Default, t) + e := httptest.New(iris.Default, t, httptest.Debug(true)) // run the tests (1) for idx := range testRoutes { @@ -483,6 +483,7 @@ func TestRealSubdomainSimple(t *testing.T) { func TestMuxPathEscape(t *testing.T) { iris.ResetDefault() + iris.Config.EnablePathEscape = true iris.Get("/details/:name", func(ctx *iris.Context) { name := ctx.ParamDecoded("name") diff --git a/iris.go b/iris.go index 02957999..bc5cd154 100644 --- a/iris.go +++ b/iris.go @@ -54,7 +54,6 @@ visit https://docs.iris-go.com package iris // import "github.com/kataras/iris" import ( - "bytes" "fmt" "log" "net" @@ -81,7 +80,7 @@ const ( // IsLongTermSupport flag is true when the below version number is a long-term-support version IsLongTermSupport = false // Version is the current version number of the Iris web framework - Version = "6.0.6" + Version = "6.0.7" banner = ` _____ _ |_ _| (_) @@ -866,6 +865,8 @@ func (s *Framework) UseSerializer(forContentType string, e serializer.Serializer // so, you can change the filenameOrSource, the page binding, the options, and even add cookies, session value or a flash message through ctx // the return value of a PreRender is a boolean, if returns false then the next PreRender will not be executed, keep note // that the actual context's Render will be called at any case. +// +// Example: https://github.com/iris-contrib/examples/tree/master/template_engines/template_prerender func UsePreRender(pre PreRender) { Default.UsePreRender(pre) } @@ -877,6 +878,8 @@ func UsePreRender(pre PreRender) { // so, you can change the filenameOrSource, the page binding, the options, and even add cookies, session value or a flash message through ctx // the return value of a PreRender is a boolean, if returns false then the next PreRender will not be executed, keep note // that the actual context's Render will be called at any case. +// +// Example: https://github.com/iris-contrib/examples/tree/master/template_engines/template_prerender func (s *Framework) UsePreRender(pre PreRender) { s.templates.usePreRender(pre) } @@ -1069,7 +1072,7 @@ func DecodeQuery(path string) string { func DecodeURL(uri string) string { u, err := url.Parse(uri) if err != nil { - return "" + return uri } return u.String() } @@ -1521,7 +1524,7 @@ func (api *muxAPI) API(path string, restAPI HandlerAPI, middleware ...HandlerFun // or no, I changed my mind, let all be named parameters and let users to decide what info they need, // using the Context to take more values (post form,url params and so on).- - paramPrefix := []byte("param") + paramPrefix := "param" for _, methodName := range AllMethods { methodWithBy := strings.Title(strings.ToLower(methodName)) + "By" if method, found := typ.MethodByName(methodWithBy); found { @@ -1552,8 +1555,8 @@ func (api *muxAPI) API(path string, restAPI HandlerAPI, middleware ...HandlerFun args[0] = newController j := 1 - ctx.VisitValues(func(k []byte, v interface{}) { - if bytes.HasPrefix(k, paramPrefix) { + ctx.VisitValues(func(k string, v interface{}) { + if strings.HasPrefix(k, paramPrefix) { args[j] = reflect.ValueOf(v.(string)) j++ // the first parameter is the context, other are the path parameters, j++ to be align with (API's registered)paramsLen diff --git a/template.go b/template.go index 278ead32..bcd719e7 100644 --- a/template.go +++ b/template.go @@ -27,6 +27,8 @@ type ( // so, you can change the filenameOrSource, the page binding, the options, and even add cookies, session value or a flash message through ctx // the return value of a PreRender is a boolean, if returns false then the next PreRender will not be executed, keep note // that the actual context's Render will be called at any case. + // + // Example: https://github.com/iris-contrib/examples/tree/master/template_engines/template_prerender PreRender func(ctx *Context, filenameOrSource string, binding interface{}, options ...map[string]interface{}) bool ) @@ -74,9 +76,12 @@ func (t *templateEngines) render(isFile bool, ctx *Context, filenameOrSource str } if len(t.prerenders) > 0 { + for i := range t.prerenders { + // I'm not making any checks here for performance reasons, means that // if binding is pointer it can be changed, otherwise not. + if shouldContinue := t.prerenders[i](ctx, filenameOrSource, binding, options...); !shouldContinue { break }