mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
Update to 6.0.7
This commit is contained in:
parent
c476fe8921
commit
893271bf02
21
HISTORY.md
21
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`.
|
**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
|
## 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)
|
- Add `iris.DestroySessionByID(string)` and `iris.DestroyAllSessions()` functions as requested by a community member in the [chat](https://kataras.rocket.chat/channel/iris)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
<a href="https://github.com/kataras/iris/blob/master/HISTORY.md"><img src="https://img.shields.io/badge/%20version%20-%206.0.6%20-blue.svg?style=flat-square" alt="CHANGELOG/HISTORY"></a>
|
<a href="https://github.com/kataras/iris/blob/master/HISTORY.md"><img src="https://img.shields.io/badge/%20version%20-%206.0.7%20-blue.svg?style=flat-square" alt="CHANGELOG/HISTORY"></a>
|
||||||
|
|
||||||
<a href="https://github.com/iris-contrib/examples"><img src="https://img.shields.io/badge/%20examples-repository-3362c2.svg?style=flat-square" alt="Examples"></a>
|
<a href="https://github.com/iris-contrib/examples"><img src="https://img.shields.io/badge/%20examples-repository-3362c2.svg?style=flat-square" alt="Examples"></a>
|
||||||
|
|
||||||
|
@ -938,14 +938,14 @@ You can read the full article [here](https://translate.google.com/translate?sl=a
|
||||||
Testing
|
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
|
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)!
|
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)!
|
||||||
|
|
|
@ -127,10 +127,10 @@ type Configuration struct {
|
||||||
// Default is false
|
// Default is false
|
||||||
DisablePathCorrection bool
|
DisablePathCorrection bool
|
||||||
|
|
||||||
// DisablePathEscape when is false then its escapes the path, the named parameters (if any).
|
// EnablePathEscape when is true 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
|
// 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 '/'
|
// accepts parameters with slash '/'
|
||||||
// Request: http://localhost:8080/details/Project%2FDelta
|
// Request: http://localhost:8080/details/Project%2FDelta
|
||||||
// ctx.Param("project") returns the raw named parameter: 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
|
// Look here: https://github.com/kataras/iris/issues/135 for more
|
||||||
//
|
//
|
||||||
// Default is false
|
// 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
|
// FireMethodNotAllowed if it's true router checks for StatusMethodNotAllowed(405) and fires the 405 error instead of 404
|
||||||
// Default is false
|
// Default is false
|
||||||
|
@ -325,10 +325,10 @@ var (
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OptionDisablePathEscape when is false then its escapes the path, the named parameters (if any).
|
// OptionEnablePathEscape when is true then its escapes the path, the named path parameters (if any).
|
||||||
OptionDisablePathEscape = func(val bool) OptionSet {
|
OptionEnablePathEscape = func(val bool) OptionSet {
|
||||||
return func(c *Configuration) {
|
return func(c *Configuration) {
|
||||||
c.DisablePathEscape = val
|
c.EnablePathEscape = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ var (
|
||||||
// Default values for base Iris conf
|
// Default values for base Iris conf
|
||||||
const (
|
const (
|
||||||
DefaultDisablePathCorrection = false
|
DefaultDisablePathCorrection = false
|
||||||
DefaultDisablePathEscape = false
|
DefaultEnablePathEscape = false
|
||||||
DefaultCharset = "UTF-8"
|
DefaultCharset = "UTF-8"
|
||||||
DefaultLoggerPreffix = "[IRIS] "
|
DefaultLoggerPreffix = "[IRIS] "
|
||||||
// Per-connection buffer size for requests' reading.
|
// Per-connection buffer size for requests' reading.
|
||||||
|
@ -469,7 +469,7 @@ func DefaultConfiguration() Configuration {
|
||||||
CheckForUpdates: false,
|
CheckForUpdates: false,
|
||||||
CheckForUpdatesSync: false,
|
CheckForUpdatesSync: false,
|
||||||
DisablePathCorrection: DefaultDisablePathCorrection,
|
DisablePathCorrection: DefaultDisablePathCorrection,
|
||||||
DisablePathEscape: DefaultDisablePathEscape,
|
EnablePathEscape: DefaultEnablePathEscape,
|
||||||
FireMethodNotAllowed: false,
|
FireMethodNotAllowed: false,
|
||||||
DisableBanner: false,
|
DisableBanner: false,
|
||||||
LoggerOut: DefaultLoggerOut,
|
LoggerOut: DefaultLoggerOut,
|
||||||
|
|
14
context.go
14
context.go
|
@ -242,15 +242,15 @@ func (ctx *Context) VirtualHostname() string {
|
||||||
// Path returns the full escaped path as string
|
// Path returns the full escaped path as string
|
||||||
// for unescaped use: ctx.RequestCtx.RequestURI() or RequestPath(escape bool)
|
// for unescaped use: ctx.RequestCtx.RequestURI() or RequestPath(escape bool)
|
||||||
func (ctx *Context) Path() string {
|
func (ctx *Context) Path() string {
|
||||||
return ctx.RequestPath(!ctx.framework.Config.DisablePathEscape)
|
return ctx.RequestPath(ctx.framework.Config.EnablePathEscape)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestPath returns the requested path
|
// RequestPath returns the requested path
|
||||||
func (ctx *Context) RequestPath(escape bool) string {
|
func (ctx *Context) RequestPath(escape bool) string {
|
||||||
if escape {
|
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
|
// 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.
|
// visitor must not retain references to key and value after returning.
|
||||||
// Make key and/or value copies if you need storing them 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++ {
|
for i, n := 0, len(ctx.values); i < n; i++ {
|
||||||
kv := &ctx.values[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
|
// 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) {
|
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 {
|
if _, ok := vg.(string); ok {
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +1001,7 @@ func (ctx *Context) ParamInt64(key string) (int64, error) {
|
||||||
// hasthe form of key1=value1,key2=value2...
|
// hasthe form of key1=value1,key2=value2...
|
||||||
func (ctx *Context) ParamsSentence() string {
|
func (ctx *Context) ParamsSentence() string {
|
||||||
var buff bytes.Buffer
|
var buff bytes.Buffer
|
||||||
ctx.VisitValues(func(kb []byte, vg interface{}) {
|
ctx.VisitValues(func(kb string, vg interface{}) {
|
||||||
v, ok := vg.(string)
|
v, ok := vg.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
|
|
|
@ -127,7 +127,7 @@ func TestContextURLParams(t *testing.T) {
|
||||||
params := ctx.URLParams()
|
params := ctx.URLParams()
|
||||||
ctx.JSON(iris.StatusOK, params)
|
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)
|
e.GET("/").WithQueryObject(passedParams).Expect().Status(iris.StatusOK).JSON().Equal(passedParams)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/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"}}},
|
{"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()
|
iris.ResetDefault()
|
||||||
|
|
||||||
for idx := range testRoutes {
|
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)
|
// run the tests (1)
|
||||||
for idx := range testRoutes {
|
for idx := range testRoutes {
|
||||||
|
@ -483,6 +483,7 @@ func TestRealSubdomainSimple(t *testing.T) {
|
||||||
|
|
||||||
func TestMuxPathEscape(t *testing.T) {
|
func TestMuxPathEscape(t *testing.T) {
|
||||||
iris.ResetDefault()
|
iris.ResetDefault()
|
||||||
|
iris.Config.EnablePathEscape = true
|
||||||
|
|
||||||
iris.Get("/details/:name", func(ctx *iris.Context) {
|
iris.Get("/details/:name", func(ctx *iris.Context) {
|
||||||
name := ctx.ParamDecoded("name")
|
name := ctx.ParamDecoded("name")
|
||||||
|
|
15
iris.go
15
iris.go
|
@ -54,7 +54,6 @@ visit https://docs.iris-go.com
|
||||||
package iris // import "github.com/kataras/iris"
|
package iris // import "github.com/kataras/iris"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
@ -81,7 +80,7 @@ const (
|
||||||
// IsLongTermSupport flag is true when the below version number is a long-term-support version
|
// IsLongTermSupport flag is true when the below version number is a long-term-support version
|
||||||
IsLongTermSupport = false
|
IsLongTermSupport = false
|
||||||
// Version is the current version number of the Iris web framework
|
// Version is the current version number of the Iris web framework
|
||||||
Version = "6.0.6"
|
Version = "6.0.7"
|
||||||
|
|
||||||
banner = ` _____ _
|
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
|
// 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
|
// 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.
|
// 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) {
|
func UsePreRender(pre PreRender) {
|
||||||
Default.UsePreRender(pre)
|
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
|
// 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
|
// 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.
|
// 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) {
|
func (s *Framework) UsePreRender(pre PreRender) {
|
||||||
s.templates.usePreRender(pre)
|
s.templates.usePreRender(pre)
|
||||||
}
|
}
|
||||||
|
@ -1069,7 +1072,7 @@ func DecodeQuery(path string) string {
|
||||||
func DecodeURL(uri string) string {
|
func DecodeURL(uri string) string {
|
||||||
u, err := url.Parse(uri)
|
u, err := url.Parse(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return uri
|
||||||
}
|
}
|
||||||
return u.String()
|
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,
|
// 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).-
|
// using the Context to take more values (post form,url params and so on).-
|
||||||
|
|
||||||
paramPrefix := []byte("param")
|
paramPrefix := "param"
|
||||||
for _, methodName := range AllMethods {
|
for _, methodName := range AllMethods {
|
||||||
methodWithBy := strings.Title(strings.ToLower(methodName)) + "By"
|
methodWithBy := strings.Title(strings.ToLower(methodName)) + "By"
|
||||||
if method, found := typ.MethodByName(methodWithBy); found {
|
if method, found := typ.MethodByName(methodWithBy); found {
|
||||||
|
@ -1552,8 +1555,8 @@ func (api *muxAPI) API(path string, restAPI HandlerAPI, middleware ...HandlerFun
|
||||||
args[0] = newController
|
args[0] = newController
|
||||||
j := 1
|
j := 1
|
||||||
|
|
||||||
ctx.VisitValues(func(k []byte, v interface{}) {
|
ctx.VisitValues(func(k string, v interface{}) {
|
||||||
if bytes.HasPrefix(k, paramPrefix) {
|
if strings.HasPrefix(k, paramPrefix) {
|
||||||
args[j] = reflect.ValueOf(v.(string))
|
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
|
j++ // the first parameter is the context, other are the path parameters, j++ to be align with (API's registered)paramsLen
|
||||||
|
|
|
@ -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
|
// 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
|
// 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.
|
// 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
|
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 {
|
if len(t.prerenders) > 0 {
|
||||||
|
|
||||||
for i := range t.prerenders {
|
for i := range t.prerenders {
|
||||||
|
|
||||||
// I'm not making any checks here for performance reasons, means that
|
// I'm not making any checks here for performance reasons, means that
|
||||||
// if binding is pointer it can be changed, otherwise not.
|
// if binding is pointer it can be changed, otherwise not.
|
||||||
|
|
||||||
if shouldContinue := t.prerenders[i](ctx, filenameOrSource, binding, options...); !shouldContinue {
|
if shouldContinue := t.prerenders[i](ctx, filenameOrSource, binding, options...); !shouldContinue {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user